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
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
28 use C4::AuthoritiesMarc;
29 use C4::MarcModificationTemplates;
30 use Koha::Plugins::Handler;
32 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
35 # set the version for version checking
36 $VERSION = 3.07.00.049;
43 GetImportRecordMarcXML
48 AddItemsToImportBiblio
59 GetStagedWebserviceBatches
60 GetImportBatchRangeDesc
61 GetNumberOfNonZ3950ImportBatches
64 GetItemNumbersFromImportBatch
68 GetImportBatchOverlayAction
69 SetImportBatchOverlayAction
70 GetImportBatchNoMatchAction
71 SetImportBatchNoMatchAction
72 GetImportBatchItemAction
73 SetImportBatchItemAction
76 GetImportRecordOverlayStatus
77 SetImportRecordOverlayStatus
80 GetImportRecordMatches
81 SetImportRecordMatches
87 C4::ImportBatch - manage batches of imported MARC records
95 =head2 GetZ3950BatchId
97 my $batchid = GetZ3950BatchId($z3950server);
99 Retrieves the ID of the import batch for the Z39.50
100 reservoir for the given target. If necessary,
101 creates the import batch.
105 sub GetZ3950BatchId {
106 my ($z3950server) = @_;
108 my $dbh = C4::Context->dbh;
109 my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
110 WHERE batch_type = 'z3950'
112 $sth->execute($z3950server);
113 my $rowref = $sth->fetchrow_arrayref();
115 if (defined $rowref) {
118 my $batch_id = AddImportBatch( {
119 overlay_action => 'create_new',
120 import_status => 'staged',
121 batch_type => 'z3950',
122 file_name => $z3950server,
129 =head2 GetWebserviceBatchId
131 my $batchid = GetWebserviceBatchId();
133 Retrieves the ID of the import batch for webservice.
134 If necessary, creates the import batch.
138 my $WEBSERVICE_BASE_QRY = <<EOQ;
139 SELECT import_batch_id FROM import_batches
140 WHERE batch_type = 'webservice'
141 AND import_status = 'staged'
143 sub GetWebserviceBatchId {
146 my $dbh = C4::Context->dbh;
147 my $sql = $WEBSERVICE_BASE_QRY;
149 foreach my $field (qw(matcher_id overlay_action nomatch_action item_action)) {
150 if (my $val = $params->{$field}) {
151 $sql .= " AND $field = ?";
155 my $id = $dbh->selectrow_array($sql, undef, @args);
158 $params->{batch_type} = 'webservice';
159 $params->{import_status} = 'staged';
160 return AddImportBatch($params);
163 =head2 GetImportRecordMarc
165 my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);
169 sub GetImportRecordMarc {
170 my ($import_record_id) = @_;
172 my $dbh = C4::Context->dbh;
173 my ( $marc, $encoding ) = $dbh->selectrow_array(q|
174 SELECT marc, encoding
176 WHERE import_record_id = ?
177 |, undef, $import_record_id );
179 return $marc, $encoding;
182 sub GetRecordFromImportBiblio {
183 my ( $import_record_id, $embed_items ) = @_;
185 my ($marc) = GetImportRecordMarc($import_record_id);
186 my $record = MARC::Record->new_from_usmarc($marc);
188 EmbedItemsInImportBiblio( $record, $import_record_id ) if $embed_items;
193 sub EmbedItemsInImportBiblio {
194 my ( $record, $import_record_id ) = @_;
195 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber", '');
196 my $dbh = C4::Context->dbh;
197 my $import_items = $dbh->selectall_arrayref(q|
198 SELECT import_items.marcxml
200 WHERE import_record_id = ?
201 |, { Slice => {} }, $import_record_id );
203 for my $import_item ( @$import_items ) {
204 my $item_marc = MARC::Record::new_from_xml($import_item->{marcxml});
205 push @item_fields, $item_marc->field($itemtag);
207 $record->append_fields(@item_fields);
211 =head2 GetImportRecordMarcXML
213 my $marcxml = GetImportRecordMarcXML($import_record_id);
217 sub GetImportRecordMarcXML {
218 my ($import_record_id) = @_;
220 my $dbh = C4::Context->dbh;
221 my $sth = $dbh->prepare("SELECT marcxml FROM import_records WHERE import_record_id = ?");
222 $sth->execute($import_record_id);
223 my ($marcxml) = $sth->fetchrow();
229 =head2 AddImportBatch
231 my $batch_id = AddImportBatch($params_hash);
239 foreach (qw( matcher_id template_id branchcode
240 overlay_action nomatch_action item_action
241 import_status batch_type file_name comments record_type )) {
242 if (exists $params->{$_}) {
244 push @vals, $params->{$_};
247 my $dbh = C4::Context->dbh;
248 $dbh->do("INSERT INTO import_batches (".join( ',', @fields).")
249 VALUES (".join( ',', map '?', @fields).")",
252 return $dbh->{'mysql_insertid'};
255 =head2 GetImportBatch
257 my $row = GetImportBatch($batch_id);
259 Retrieve a hashref of an import_batches row.
266 my $dbh = C4::Context->dbh;
267 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
268 $sth->bind_param(1, $batch_id);
270 my $result = $sth->fetchrow_hashref;
276 =head2 AddBiblioToBatch
278 my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence,
279 $marc_record, $encoding, $z3950random, $update_counts);
283 sub AddBiblioToBatch {
284 my $batch_id = shift;
285 my $record_sequence = shift;
286 my $marc_record = shift;
287 my $encoding = shift;
288 my $z3950random = shift;
289 my $update_counts = @_ ? shift : 1;
291 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random, C4::Context->preference('marcflavour'));
292 _add_biblio_fields($import_record_id, $marc_record);
293 _update_batch_record_counts($batch_id) if $update_counts;
294 return $import_record_id;
297 =head2 ModBiblioInBatch
299 ModBiblioInBatch($import_record_id, $marc_record);
303 sub ModBiblioInBatch {
304 my ($import_record_id, $marc_record) = @_;
306 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
307 _update_biblio_fields($import_record_id, $marc_record);
311 =head2 AddAuthToBatch
313 my $import_record_id = AddAuthToBatch($batch_id, $record_sequence,
314 $marc_record, $encoding, $z3950random, $update_counts, [$marc_type]);
319 my $batch_id = shift;
320 my $record_sequence = shift;
321 my $marc_record = shift;
322 my $encoding = shift;
323 my $z3950random = shift;
324 my $update_counts = @_ ? shift : 1;
325 my $marc_type = shift || C4::Context->preference('marcflavour');
327 $marc_type = 'UNIMARCAUTH' if $marc_type eq 'UNIMARC';
329 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'auth', $encoding, $z3950random, $marc_type);
330 _add_auth_fields($import_record_id, $marc_record);
331 _update_batch_record_counts($batch_id) if $update_counts;
332 return $import_record_id;
335 =head2 ModAuthInBatch
337 ModAuthInBatch($import_record_id, $marc_record);
342 my ($import_record_id, $marc_record) = @_;
344 my $marcflavour = C4::Context->preference('marcflavour');
345 _update_import_record_marc($import_record_id, $marc_record, $marcflavour eq 'UNIMARC' ? 'UNIMARCAUTH' : 'USMARC');
349 =head2 BatchStageMarcRecords
351 ( $batch_id, $num_records, $num_items, @invalid_records ) =
352 BatchStageMarcRecords(
353 $encoding, $marc_records,
354 $file_name, $to_marc_plugin,
355 $marc_modification_template, $comments,
356 $branch_code, $parse_items,
357 $leave_as_staging, $progress_interval,
363 sub BatchStageMarcRecords {
364 my $record_type = shift;
365 my $encoding = shift;
366 my $marc_records = shift;
367 my $file_name = shift;
368 my $to_marc_plugin = shift;
369 my $marc_modification_template = shift;
370 my $comments = shift;
371 my $branch_code = shift;
372 my $parse_items = shift;
373 my $leave_as_staging = shift;
375 # optional callback to monitor status
377 my $progress_interval = 0;
378 my $progress_callback = undef;
380 $progress_interval = shift;
381 $progress_callback = shift;
382 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
383 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
386 my $batch_id = AddImportBatch( {
387 overlay_action => 'create_new',
388 import_status => 'staging',
389 batch_type => 'batch',
390 file_name => $file_name,
391 comments => $comments,
392 record_type => $record_type,
395 SetImportBatchItemAction($batch_id, 'always_add');
397 SetImportBatchItemAction($batch_id, 'ignore');
400 $marc_records = Koha::Plugins::Handler->run(
402 class => $to_marc_plugin,
404 params => { data => $marc_records }
406 ) if $to_marc_plugin;
408 my $marc_type = C4::Context->preference('marcflavour');
409 $marc_type .= 'AUTH' if ($marc_type eq 'UNIMARC' && $record_type eq 'auth');
410 my @invalid_records = ();
413 # FIXME - for now, we're dealing only with bibs
415 foreach my $marc_blob (split(/\x1D/, $marc_records)) {
416 $marc_blob =~ s/^\s+//g;
417 $marc_blob =~ s/\s+$//g;
418 next unless $marc_blob;
420 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
421 &$progress_callback($rec_num);
423 my ($marc_record, $charset_guessed, $char_errors) =
424 MarcToUTF8Record($marc_blob, $marc_type, $encoding);
426 $encoding = $charset_guessed unless $encoding;
428 ModifyRecordWithTemplate( $marc_modification_template, $marc_record ) if ( $marc_modification_template );
430 my $import_record_id;
431 if (scalar($marc_record->fields()) == 0) {
432 push @invalid_records, $marc_blob;
435 # Normalize the record so it doesn't have separated diacritics
436 SetUTF8Flag($marc_record);
439 if ($record_type eq 'biblio') {
440 $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
442 my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
443 $num_items += scalar(@import_items_ids);
445 } elsif ($record_type eq 'auth') {
446 $import_record_id = AddAuthToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0, $marc_type);
450 unless ($leave_as_staging) {
451 SetImportBatchStatus($batch_id, 'staged');
453 # FIXME branch_code, number of bibs, number of items
454 _update_batch_record_counts($batch_id);
455 return ($batch_id, $num_valid, $num_items, @invalid_records);
458 =head2 AddItemsToImportBiblio
460 my @import_items_ids = AddItemsToImportBiblio($batch_id,
461 $import_record_id, $marc_record, $update_counts);
465 sub AddItemsToImportBiblio {
466 my $batch_id = shift;
467 my $import_record_id = shift;
468 my $marc_record = shift;
469 my $update_counts = @_ ? shift : 0;
471 my @import_items_ids = ();
473 my $dbh = C4::Context->dbh;
474 my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
475 foreach my $item_field ($marc_record->field($item_tag)) {
476 my $item_marc = MARC::Record->new();
477 $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
478 $item_marc->append_fields($item_field);
479 $marc_record->delete_field($item_field);
480 my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
482 $sth->bind_param(1, $import_record_id);
483 $sth->bind_param(2, 'staged');
484 $sth->bind_param(3, $item_marc->as_xml());
486 push @import_items_ids, $dbh->{'mysql_insertid'};
490 if ($#import_items_ids > -1) {
491 _update_batch_record_counts($batch_id) if $update_counts;
492 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
494 return @import_items_ids;
497 =head2 BatchFindDuplicates
499 my $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
500 $max_matches, $progress_interval, $progress_callback);
502 Goes through the records loaded in the batch and attempts to
503 find duplicates for each one. Sets the matching status
504 of each record to "no_match" or "auto_match" as appropriate.
506 The $max_matches parameter is optional; if it is not supplied,
509 The $progress_interval and $progress_callback parameters are
510 optional; if both are supplied, the sub referred to by
511 $progress_callback will be invoked every $progress_interval
512 records using the number of records processed as the
517 sub BatchFindDuplicates {
518 my $batch_id = shift;
520 my $max_matches = @_ ? shift : 10;
522 # optional callback to monitor status
524 my $progress_interval = 0;
525 my $progress_callback = undef;
527 $progress_interval = shift;
528 $progress_callback = shift;
529 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
530 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
533 my $dbh = C4::Context->dbh;
535 my $sth = $dbh->prepare("SELECT import_record_id, record_type, marc
537 WHERE import_batch_id = ?");
538 $sth->execute($batch_id);
539 my $num_with_matches = 0;
541 while (my $rowref = $sth->fetchrow_hashref) {
543 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
544 &$progress_callback($rec_num);
546 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
548 if (defined $matcher) {
549 @matches = $matcher->get_matches($marc_record, $max_matches);
551 if (scalar(@matches) > 0) {
553 SetImportRecordMatches($rowref->{'import_record_id'}, @matches);
554 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'auto_match');
556 SetImportRecordMatches($rowref->{'import_record_id'}, ());
557 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'no_match');
561 return $num_with_matches;
564 =head2 BatchCommitRecords
566 my ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored) =
567 BatchCommitRecords($batch_id, $framework,
568 $progress_interval, $progress_callback);
572 sub BatchCommitRecords {
573 my $batch_id = shift;
574 my $framework = shift;
576 # optional callback to monitor status
578 my $progress_interval = 0;
579 my $progress_callback = undef;
581 $progress_interval = shift;
582 $progress_callback = shift;
583 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
584 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
590 my $num_items_added = 0;
591 my $num_items_replaced = 0;
592 my $num_items_errored = 0;
594 # commit (i.e., save, all records in the batch)
595 SetImportBatchStatus('importing');
596 my $overlay_action = GetImportBatchOverlayAction($batch_id);
597 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
598 my $item_action = GetImportBatchItemAction($batch_id);
601 my $dbh = C4::Context->dbh;
602 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marc, encoding
604 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
605 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
606 WHERE import_batch_id = ?");
607 $sth->execute($batch_id);
608 my $marcflavour = C4::Context->preference('marcflavour');
610 while (my $rowref = $sth->fetchrow_hashref) {
611 $record_type = $rowref->{'record_type'};
613 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
614 &$progress_callback($rec_num);
616 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
622 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
623 $marc_type = 'UNIMARCAUTH';
624 } elsif ($marcflavour eq 'UNIMARC') {
625 $marc_type = 'UNIMARC';
627 $marc_type = 'USMARC';
629 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
631 if ($record_type eq 'biblio') {
632 # remove any item tags - rely on BatchCommitItems
633 ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
634 foreach my $item_field ($marc_record->field($item_tag)) {
635 $marc_record->delete_field($item_field);
639 my ($record_result, $item_result, $record_match) =
640 _get_commit_action($overlay_action, $nomatch_action, $item_action,
641 $rowref->{'overlay_status'}, $rowref->{'import_record_id'}, $record_type);
645 if ($record_result eq 'create_new') {
647 if ($record_type eq 'biblio') {
648 my $biblioitemnumber;
649 ($recordid, $biblioitemnumber) = AddBiblio($marc_record, $framework);
650 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
651 if ($item_result eq 'create_new' || $item_result eq 'replace') {
652 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
653 $num_items_added += $bib_items_added;
654 $num_items_replaced += $bib_items_replaced;
655 $num_items_errored += $bib_items_errored;
658 $recordid = AddAuthority($marc_record, undef, GuessAuthTypeCode($marc_record));
659 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
661 my $sth = $dbh->prepare_cached($query);
662 $sth->execute($recordid, $rowref->{'import_record_id'});
664 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
665 } elsif ($record_result eq 'replace') {
667 $recordid = $record_match;
669 if ($record_type eq 'biblio') {
670 my $oldbiblio = GetBiblio($recordid);
671 $oldxml = GetXmlBiblio($recordid);
673 # remove item fields so that they don't get
674 # added again if record is reverted
675 # 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.
676 my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'}, $marc_type);
677 foreach my $item_field ($old_marc->field($item_tag)) {
678 $old_marc->delete_field($item_field);
680 $oldxml = $old_marc->as_xml($marc_type);
682 ModBiblio($marc_record, $recordid, $oldbiblio->{'frameworkcode'});
683 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
685 if ($item_result eq 'create_new' || $item_result eq 'replace') {
686 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
687 $num_items_added += $bib_items_added;
688 $num_items_replaced += $bib_items_replaced;
689 $num_items_errored += $bib_items_errored;
692 $oldxml = GetAuthorityXML($recordid);
694 ModAuthority($recordid, $marc_record, GuessAuthTypeCode($marc_record));
695 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
697 my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
698 $sth->execute($oldxml, $rowref->{'import_record_id'});
700 my $sth2 = $dbh->prepare_cached($query);
701 $sth2->execute($recordid, $rowref->{'import_record_id'});
703 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
704 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
705 } elsif ($record_result eq 'ignore') {
706 $recordid = $record_match;
708 $recordid = $record_match;
709 if ($record_type eq 'biblio' and defined $recordid and ( $item_result eq 'create_new' || $item_result eq 'replace' ) ) {
710 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
711 $num_items_added += $bib_items_added;
712 $num_items_replaced += $bib_items_replaced;
713 $num_items_errored += $bib_items_errored;
714 # still need to record the matched biblionumber so that the
715 # items can be reverted
716 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
717 $sth2->execute($recordid, $rowref->{'import_record_id'});
718 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
720 SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
724 SetImportBatchStatus($batch_id, 'imported');
725 return ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored);
728 =head2 BatchCommitItems
730 ($num_items_added, $num_items_errored) =
731 BatchCommitItems($import_record_id, $biblionumber);
735 sub BatchCommitItems {
736 my ( $import_record_id, $biblionumber, $action ) = @_;
738 my $dbh = C4::Context->dbh;
740 my $num_items_added = 0;
741 my $num_items_errored = 0;
742 my $num_items_replaced = 0;
744 my $sth = $dbh->prepare( "
745 SELECT import_items_id, import_items.marcxml, encoding
747 JOIN import_records USING (import_record_id)
748 WHERE import_record_id = ?
749 ORDER BY import_items_id
751 $sth->bind_param( 1, $import_record_id );
754 while ( my $row = $sth->fetchrow_hashref() ) {
755 my $item_marc = MARC::Record->new_from_xml( StripNonXmlChars( $row->{'marcxml'} ), 'UTF-8', $row->{'encoding'} );
757 # Delete date_due subfield as to not accidentally delete item checkout due dates
758 my ( $MARCfield, $MARCsubfield ) = GetMarcFromKohaField( 'items.onloan', GetFrameworkCode($biblionumber) );
759 $item_marc->field($MARCfield)->delete_subfield( code => $MARCsubfield );
761 my $item = TransformMarcToKoha( $dbh, $item_marc );
763 my $duplicate_barcode = exists( $item->{'barcode'} ) && GetItemnumberFromBarcode( $item->{'barcode'} );
764 my $duplicate_itemnumber = exists( $item->{'itemnumber'} );
766 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
767 if ( $action eq "replace" && $duplicate_itemnumber ) {
768 # Duplicate itemnumbers have precedence, that way we can update barcodes by overlaying
769 ModItemFromMarc( $item_marc, $biblionumber, $item->{itemnumber} );
770 $updsth->bind_param( 1, 'imported' );
771 $updsth->bind_param( 2, $item->{itemnumber} );
772 $updsth->bind_param( 3, $row->{'import_items_id'} );
775 $num_items_replaced++;
776 } elsif ( $action eq "replace" && $duplicate_barcode ) {
777 my $itemnumber = GetItemnumberFromBarcode( $item->{'barcode'} );
778 ModItemFromMarc( $item_marc, $biblionumber, $itemnumber );
779 $updsth->bind_param( 1, 'imported' );
780 $updsth->bind_param( 2, $item->{itemnumber} );
781 $updsth->bind_param( 3, $row->{'import_items_id'} );
784 $num_items_replaced++;
785 } elsif ($duplicate_barcode) {
786 $updsth->bind_param( 1, 'error' );
787 $updsth->bind_param( 2, 'duplicate item barcode' );
788 $updsth->bind_param( 3, $row->{'import_items_id'} );
790 $num_items_errored++;
792 my ( $item_biblionumber, $biblioitemnumber, $itemnumber ) = AddItemFromMarc( $item_marc, $biblionumber );
793 $updsth->bind_param( 1, 'imported' );
794 $updsth->bind_param( 2, $itemnumber );
795 $updsth->bind_param( 3, $row->{'import_items_id'} );
802 return ( $num_items_added, $num_items_replaced, $num_items_errored );
805 =head2 BatchRevertRecords
807 my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted,
808 $num_ignored) = BatchRevertRecords($batch_id);
812 sub BatchRevertRecords {
813 my $batch_id = shift;
818 my $num_reverted = 0;
820 my $num_items_deleted = 0;
821 # commit (i.e., save, all records in the batch)
822 SetImportBatchStatus('reverting');
823 my $overlay_action = GetImportBatchOverlayAction($batch_id);
824 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
825 my $dbh = C4::Context->dbh;
826 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marcxml_old, encoding, matched_biblionumber, matched_authid
828 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
829 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
830 WHERE import_batch_id = ?");
831 $sth->execute($batch_id);
833 my $marcflavour = C4::Context->preference('marcflavour');
834 while (my $rowref = $sth->fetchrow_hashref) {
835 $record_type = $rowref->{'record_type'};
836 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
840 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
841 $marc_type = 'UNIMARCAUTH';
842 } elsif ($marcflavour eq 'UNIMARC') {
843 $marc_type = 'UNIMARC';
845 $marc_type = 'USMARC';
848 my $record_result = _get_revert_action($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
850 if ($record_result eq 'delete') {
852 if ($record_type eq 'biblio') {
853 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
854 $error = DelBiblio($rowref->{'matched_biblionumber'});
856 my $deletedauthid = DelAuthority($rowref->{'matched_authid'});
858 if (defined $error) {
862 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
864 } elsif ($record_result eq 'restore') {
866 my $old_record = MARC::Record->new_from_xml(StripNonXmlChars($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'}, $marc_type);
867 if ($record_type eq 'biblio') {
868 my $biblionumber = $rowref->{'matched_biblionumber'};
869 my $oldbiblio = GetBiblio($biblionumber);
870 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
871 ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
873 my $authid = $rowref->{'matched_authid'};
874 ModAuthority($authid, $old_record, GuessAuthTypeCode($old_record));
876 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
877 } elsif ($record_result eq 'ignore') {
878 if ($record_type eq 'biblio') {
879 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
881 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
884 if ($record_type eq 'biblio') {
885 # remove matched_biblionumber only if there is no 'imported' item left
886 $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?";
887 $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')";
889 $query = "UPDATE import_auths SET matched_authid = NULL WHERE import_record_id = ?";
891 my $sth2 = $dbh->prepare_cached($query);
892 $sth2->execute($rowref->{'import_record_id'});
896 SetImportBatchStatus($batch_id, 'reverted');
897 return ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored);
900 =head2 BatchRevertItems
902 my $num_items_deleted = BatchRevertItems($import_record_id, $biblionumber);
906 sub BatchRevertItems {
907 my ($import_record_id, $biblionumber) = @_;
909 my $dbh = C4::Context->dbh;
910 my $num_items_deleted = 0;
912 my $sth = $dbh->prepare_cached("SELECT import_items_id, itemnumber
914 JOIN items USING (itemnumber)
915 WHERE import_record_id = ?");
916 $sth->bind_param(1, $import_record_id);
918 while (my $row = $sth->fetchrow_hashref()) {
919 my $error = DelItemCheck($dbh, $biblionumber, $row->{'itemnumber'});
921 my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
922 $updsth->bind_param(1, 'reverted');
923 $updsth->bind_param(2, $row->{'import_items_id'});
926 $num_items_deleted++;
933 return $num_items_deleted;
938 CleanBatch($batch_id)
940 Deletes all staged records from the import batch
941 and sets the status of the batch to 'cleaned'. Note
942 that deleting a stage record does *not* affect
943 any record that has been committed to the database.
948 my $batch_id = shift;
949 return unless defined $batch_id;
951 C4::Context->dbh->do('DELETE FROM import_records WHERE import_batch_id = ?', {}, $batch_id);
952 SetImportBatchStatus($batch_id, 'cleaned');
955 =head2 GetAllImportBatches
957 my $results = GetAllImportBatches();
959 Returns a references to an array of hash references corresponding
960 to all import_batches rows (of batch_type 'batch'), sorted in
961 ascending order by import_batch_id.
965 sub GetAllImportBatches {
966 my $dbh = C4::Context->dbh;
967 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
968 WHERE batch_type IN ('batch', 'webservice')
969 ORDER BY import_batch_id ASC");
973 while (my $row = $sth->fetchrow_hashref) {
974 push @$results, $row;
980 =head2 GetStagedWebserviceBatches
982 my $batch_ids = GetStagedWebserviceBatches();
984 Returns a references to an array of batch id's
985 of batch_type 'webservice' that are not imported
989 my $PENDING_WEBSERVICE_BATCHES_QRY = <<EOQ;
990 SELECT import_batch_id FROM import_batches
991 WHERE batch_type = 'webservice'
992 AND import_status = 'staged'
994 sub GetStagedWebserviceBatches {
995 my $dbh = C4::Context->dbh;
996 return $dbh->selectcol_arrayref($PENDING_WEBSERVICE_BATCHES_QRY);
999 =head2 GetImportBatchRangeDesc
1001 my $results = GetImportBatchRangeDesc($offset, $results_per_group);
1003 Returns a reference to an array of hash references corresponding to
1004 import_batches rows (sorted in descending order by import_batch_id)
1005 start at the given offset.
1009 sub GetImportBatchRangeDesc {
1010 my ($offset, $results_per_group) = @_;
1012 my $dbh = C4::Context->dbh;
1013 my $query = "SELECT * FROM import_batches
1014 WHERE batch_type IN ('batch', 'webservice')
1015 ORDER BY import_batch_id DESC";
1017 if ($results_per_group){
1018 $query .= " LIMIT ?";
1019 push(@params, $results_per_group);
1022 $query .= " OFFSET ?";
1023 push(@params, $offset);
1025 my $sth = $dbh->prepare_cached($query);
1026 $sth->execute(@params);
1027 my $results = $sth->fetchall_arrayref({});
1032 =head2 GetItemNumbersFromImportBatch
1034 my @itemsnos = GetItemNumbersFromImportBatch($batch_id);
1038 sub GetItemNumbersFromImportBatch {
1039 my ($batch_id) = @_;
1040 my $dbh = C4::Context->dbh;
1041 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=?");
1042 $sth->execute($batch_id);
1044 while ( my ($itm) = $sth->fetchrow_array ) {
1050 =head2 GetNumberOfImportBatches
1052 my $count = GetNumberOfImportBatches();
1056 sub GetNumberOfNonZ3950ImportBatches {
1057 my $dbh = C4::Context->dbh;
1058 my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type != 'z3950'");
1060 my ($count) = $sth->fetchrow_array();
1065 =head2 GetImportBiblios
1067 my $results = GetImportBiblios($importid);
1071 sub GetImportBiblios {
1072 my ($import_record_id) = @_;
1074 my $dbh = C4::Context->dbh;
1075 my $query = "SELECT * FROM import_biblios WHERE import_record_id = ?";
1076 return $dbh->selectall_arrayref(
1084 =head2 GetImportRecordsRange
1086 my $results = GetImportRecordsRange($batch_id, $offset, $results_per_group);
1088 Returns a reference to an array of hash references corresponding to
1089 import_biblios/import_auths/import_records rows for a given batch
1090 starting at the given offset.
1094 sub GetImportRecordsRange {
1095 my ( $batch_id, $offset, $results_per_group, $status, $parameters ) = @_;
1097 my $dbh = C4::Context->dbh;
1099 my $order_by = $parameters->{order_by} || 'import_record_id';
1100 ( $order_by ) = grep( /^$order_by$/, qw( import_record_id title status overlay_status ) ) ? $order_by : 'import_record_id';
1102 my $order_by_direction =
1103 uc( $parameters->{order_by_direction} ) eq 'DESC' ? 'DESC' : 'ASC';
1105 $order_by .= " $order_by_direction, authorized_heading" if $order_by eq 'title';
1107 my $query = "SELECT title, author, isbn, issn, authorized_heading, import_records.import_record_id,
1108 record_sequence, status, overlay_status,
1109 matched_biblionumber, matched_authid, record_type
1111 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
1112 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
1113 WHERE import_batch_id = ?";
1115 push(@params, $batch_id);
1117 $query .= " AND status=?";
1118 push(@params,$status);
1121 $query.=" ORDER BY $order_by $order_by_direction";
1123 if($results_per_group){
1124 $query .= " LIMIT ?";
1125 push(@params, $results_per_group);
1128 $query .= " OFFSET ?";
1129 push(@params, $offset);
1131 my $sth = $dbh->prepare_cached($query);
1132 $sth->execute(@params);
1133 my $results = $sth->fetchall_arrayref({});
1139 =head2 GetBestRecordMatch
1141 my $record_id = GetBestRecordMatch($import_record_id);
1145 sub GetBestRecordMatch {
1146 my ($import_record_id) = @_;
1148 my $dbh = C4::Context->dbh;
1149 my $sth = $dbh->prepare("SELECT candidate_match_id
1150 FROM import_record_matches
1151 JOIN import_records ON ( import_record_matches.import_record_id = import_records.import_record_id )
1152 LEFT JOIN biblio ON ( candidate_match_id = biblio.biblionumber )
1153 LEFT JOIN auth_header ON ( candidate_match_id = auth_header.authid )
1154 WHERE import_record_matches.import_record_id = ? AND
1155 ( (import_records.record_type = 'biblio' AND biblio.biblionumber IS NOT NULL) OR
1156 (import_records.record_type = 'auth' AND auth_header.authid IS NOT NULL) )
1157 ORDER BY score DESC, candidate_match_id DESC");
1158 $sth->execute($import_record_id);
1159 my ($record_id) = $sth->fetchrow_array();
1164 =head2 GetImportBatchStatus
1166 my $status = GetImportBatchStatus($batch_id);
1170 sub GetImportBatchStatus {
1171 my ($batch_id) = @_;
1173 my $dbh = C4::Context->dbh;
1174 my $sth = $dbh->prepare("SELECT import_status FROM import_batches WHERE import_batch_id = ?");
1175 $sth->execute($batch_id);
1176 my ($status) = $sth->fetchrow_array();
1182 =head2 SetImportBatchStatus
1184 SetImportBatchStatus($batch_id, $new_status);
1188 sub SetImportBatchStatus {
1189 my ($batch_id, $new_status) = @_;
1191 my $dbh = C4::Context->dbh;
1192 my $sth = $dbh->prepare("UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?");
1193 $sth->execute($new_status, $batch_id);
1198 =head2 GetImportBatchOverlayAction
1200 my $overlay_action = GetImportBatchOverlayAction($batch_id);
1204 sub GetImportBatchOverlayAction {
1205 my ($batch_id) = @_;
1207 my $dbh = C4::Context->dbh;
1208 my $sth = $dbh->prepare("SELECT overlay_action FROM import_batches WHERE import_batch_id = ?");
1209 $sth->execute($batch_id);
1210 my ($overlay_action) = $sth->fetchrow_array();
1212 return $overlay_action;
1217 =head2 SetImportBatchOverlayAction
1219 SetImportBatchOverlayAction($batch_id, $new_overlay_action);
1223 sub SetImportBatchOverlayAction {
1224 my ($batch_id, $new_overlay_action) = @_;
1226 my $dbh = C4::Context->dbh;
1227 my $sth = $dbh->prepare("UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?");
1228 $sth->execute($new_overlay_action, $batch_id);
1233 =head2 GetImportBatchNoMatchAction
1235 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
1239 sub GetImportBatchNoMatchAction {
1240 my ($batch_id) = @_;
1242 my $dbh = C4::Context->dbh;
1243 my $sth = $dbh->prepare("SELECT nomatch_action FROM import_batches WHERE import_batch_id = ?");
1244 $sth->execute($batch_id);
1245 my ($nomatch_action) = $sth->fetchrow_array();
1247 return $nomatch_action;
1252 =head2 SetImportBatchNoMatchAction
1254 SetImportBatchNoMatchAction($batch_id, $new_nomatch_action);
1258 sub SetImportBatchNoMatchAction {
1259 my ($batch_id, $new_nomatch_action) = @_;
1261 my $dbh = C4::Context->dbh;
1262 my $sth = $dbh->prepare("UPDATE import_batches SET nomatch_action = ? WHERE import_batch_id = ?");
1263 $sth->execute($new_nomatch_action, $batch_id);
1268 =head2 GetImportBatchItemAction
1270 my $item_action = GetImportBatchItemAction($batch_id);
1274 sub GetImportBatchItemAction {
1275 my ($batch_id) = @_;
1277 my $dbh = C4::Context->dbh;
1278 my $sth = $dbh->prepare("SELECT item_action FROM import_batches WHERE import_batch_id = ?");
1279 $sth->execute($batch_id);
1280 my ($item_action) = $sth->fetchrow_array();
1282 return $item_action;
1287 =head2 SetImportBatchItemAction
1289 SetImportBatchItemAction($batch_id, $new_item_action);
1293 sub SetImportBatchItemAction {
1294 my ($batch_id, $new_item_action) = @_;
1296 my $dbh = C4::Context->dbh;
1297 my $sth = $dbh->prepare("UPDATE import_batches SET item_action = ? WHERE import_batch_id = ?");
1298 $sth->execute($new_item_action, $batch_id);
1303 =head2 GetImportBatchMatcher
1305 my $matcher_id = GetImportBatchMatcher($batch_id);
1309 sub GetImportBatchMatcher {
1310 my ($batch_id) = @_;
1312 my $dbh = C4::Context->dbh;
1313 my $sth = $dbh->prepare("SELECT matcher_id FROM import_batches WHERE import_batch_id = ?");
1314 $sth->execute($batch_id);
1315 my ($matcher_id) = $sth->fetchrow_array();
1322 =head2 SetImportBatchMatcher
1324 SetImportBatchMatcher($batch_id, $new_matcher_id);
1328 sub SetImportBatchMatcher {
1329 my ($batch_id, $new_matcher_id) = @_;
1331 my $dbh = C4::Context->dbh;
1332 my $sth = $dbh->prepare("UPDATE import_batches SET matcher_id = ? WHERE import_batch_id = ?");
1333 $sth->execute($new_matcher_id, $batch_id);
1338 =head2 GetImportRecordOverlayStatus
1340 my $overlay_status = GetImportRecordOverlayStatus($import_record_id);
1344 sub GetImportRecordOverlayStatus {
1345 my ($import_record_id) = @_;
1347 my $dbh = C4::Context->dbh;
1348 my $sth = $dbh->prepare("SELECT overlay_status FROM import_records WHERE import_record_id = ?");
1349 $sth->execute($import_record_id);
1350 my ($overlay_status) = $sth->fetchrow_array();
1352 return $overlay_status;
1357 =head2 SetImportRecordOverlayStatus
1359 SetImportRecordOverlayStatus($import_record_id, $new_overlay_status);
1363 sub SetImportRecordOverlayStatus {
1364 my ($import_record_id, $new_overlay_status) = @_;
1366 my $dbh = C4::Context->dbh;
1367 my $sth = $dbh->prepare("UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?");
1368 $sth->execute($new_overlay_status, $import_record_id);
1373 =head2 GetImportRecordStatus
1375 my $status = GetImportRecordStatus($import_record_id);
1379 sub GetImportRecordStatus {
1380 my ($import_record_id) = @_;
1382 my $dbh = C4::Context->dbh;
1383 my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
1384 $sth->execute($import_record_id);
1385 my ($status) = $sth->fetchrow_array();
1392 =head2 SetImportRecordStatus
1394 SetImportRecordStatus($import_record_id, $new_status);
1398 sub SetImportRecordStatus {
1399 my ($import_record_id, $new_status) = @_;
1401 my $dbh = C4::Context->dbh;
1402 my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
1403 $sth->execute($new_status, $import_record_id);
1408 =head2 GetImportRecordMatches
1410 my $results = GetImportRecordMatches($import_record_id, $best_only);
1414 sub GetImportRecordMatches {
1415 my $import_record_id = shift;
1416 my $best_only = @_ ? shift : 0;
1418 my $dbh = C4::Context->dbh;
1419 # FIXME currently biblio only
1420 my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber,
1421 candidate_match_id, score, record_type
1423 JOIN import_record_matches USING (import_record_id)
1424 LEFT JOIN biblio ON (biblionumber = candidate_match_id)
1425 WHERE import_record_id = ?
1426 ORDER BY score DESC, biblionumber DESC");
1427 $sth->bind_param(1, $import_record_id);
1430 while (my $row = $sth->fetchrow_hashref) {
1431 if ($row->{'record_type'} eq 'auth') {
1432 $row->{'authorized_heading'} = C4::AuthoritiesMarc::GetAuthorizedHeading( { authid => $row->{'candidate_match_id'} } );
1434 next if ($row->{'record_type'} eq 'biblio' && not $row->{'biblionumber'});
1435 push @$results, $row;
1445 =head2 SetImportRecordMatches
1447 SetImportRecordMatches($import_record_id, @matches);
1451 sub SetImportRecordMatches {
1452 my $import_record_id = shift;
1455 my $dbh = C4::Context->dbh;
1456 my $delsth = $dbh->prepare("DELETE FROM import_record_matches WHERE import_record_id = ?");
1457 $delsth->execute($import_record_id);
1460 my $sth = $dbh->prepare("INSERT INTO import_record_matches (import_record_id, candidate_match_id, score)
1462 foreach my $match (@matches) {
1463 $sth->execute($import_record_id, $match->{'record_id'}, $match->{'score'});
1468 # internal functions
1470 sub _create_import_record {
1471 my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random, $marc_type) = @_;
1473 my $dbh = C4::Context->dbh;
1474 my $sth = $dbh->prepare("INSERT INTO import_records (import_batch_id, record_sequence, marc, marcxml,
1475 record_type, encoding, z3950random)
1476 VALUES (?, ?, ?, ?, ?, ?, ?)");
1477 $sth->execute($batch_id, $record_sequence, $marc_record->as_usmarc(), $marc_record->as_xml($marc_type),
1478 $record_type, $encoding, $z3950random);
1479 my $import_record_id = $dbh->{'mysql_insertid'};
1481 return $import_record_id;
1484 sub _update_import_record_marc {
1485 my ($import_record_id, $marc_record, $marc_type) = @_;
1487 my $dbh = C4::Context->dbh;
1488 my $sth = $dbh->prepare("UPDATE import_records SET marc = ?, marcxml = ?
1489 WHERE import_record_id = ?");
1490 $sth->execute($marc_record->as_usmarc(), $marc_record->as_xml($marc_type), $import_record_id);
1494 sub _add_auth_fields {
1495 my ($import_record_id, $marc_record) = @_;
1498 if ($marc_record->field('001')) {
1499 $controlnumber = $marc_record->field('001')->data();
1501 my $authorized_heading = C4::AuthoritiesMarc::GetAuthorizedHeading({ record => $marc_record });
1502 my $dbh = C4::Context->dbh;
1503 my $sth = $dbh->prepare("INSERT INTO import_auths (import_record_id, control_number, authorized_heading) VALUES (?, ?, ?)");
1504 $sth->execute($import_record_id, $controlnumber, $authorized_heading);
1508 sub _add_biblio_fields {
1509 my ($import_record_id, $marc_record) = @_;
1511 my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1512 my $dbh = C4::Context->dbh;
1513 # FIXME no controlnumber, originalsource
1514 $isbn = C4::Koha::GetNormalizedISBN($isbn);
1515 my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1516 $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1521 sub _update_biblio_fields {
1522 my ($import_record_id, $marc_record) = @_;
1524 my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1525 my $dbh = C4::Context->dbh;
1526 # FIXME no controlnumber, originalsource
1527 # FIXME 2 - should regularize normalization of ISBN wherever it is done
1531 my $sth = $dbh->prepare("UPDATE import_biblios SET title = ?, author = ?, isbn = ?, issn = ?
1532 WHERE import_record_id = ?");
1533 $sth->execute($title, $author, $isbn, $issn, $import_record_id);
1537 sub _parse_biblio_fields {
1538 my ($marc_record) = @_;
1540 my $dbh = C4::Context->dbh;
1541 my $bibliofields = TransformMarcToKoha($dbh, $marc_record, '');
1542 return ($bibliofields->{'title'}, $bibliofields->{'author'}, $bibliofields->{'isbn'}, $bibliofields->{'issn'});
1546 sub _update_batch_record_counts {
1547 my ($batch_id) = @_;
1549 my $dbh = C4::Context->dbh;
1550 my $sth = $dbh->prepare_cached("UPDATE import_batches SET
1554 WHERE import_batch_id = import_batches.import_batch_id),
1558 JOIN import_items USING (import_record_id)
1559 WHERE import_batch_id = import_batches.import_batch_id
1560 AND record_type = 'biblio')
1561 WHERE import_batch_id = ?");
1562 $sth->bind_param(1, $batch_id);
1567 sub _get_commit_action {
1568 my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id, $record_type) = @_;
1570 if ($record_type eq 'biblio') {
1571 my ($bib_result, $bib_match, $item_result);
1573 if ($overlay_status ne 'no_match') {
1574 $bib_match = GetBestRecordMatch($import_record_id);
1575 if ($overlay_action eq 'replace') {
1576 $bib_result = defined($bib_match) ? 'replace' : 'create_new';
1577 } elsif ($overlay_action eq 'create_new') {
1578 $bib_result = 'create_new';
1579 } elsif ($overlay_action eq 'ignore') {
1580 $bib_result = 'ignore';
1582 if($item_action eq 'always_add' or $item_action eq 'add_only_for_matches'){
1583 $item_result = 'create_new';
1585 elsif($item_action eq 'replace'){
1586 $item_result = 'replace';
1589 $item_result = 'ignore';
1592 $bib_result = $nomatch_action;
1593 $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ? 'create_new' : 'ignore';
1595 return ($bib_result, $item_result, $bib_match);
1596 } else { # must be auths
1597 my ($auth_result, $auth_match);
1599 if ($overlay_status ne 'no_match') {
1600 $auth_match = GetBestRecordMatch($import_record_id);
1601 if ($overlay_action eq 'replace') {
1602 $auth_result = defined($auth_match) ? 'replace' : 'create_new';
1603 } elsif ($overlay_action eq 'create_new') {
1604 $auth_result = 'create_new';
1605 } elsif ($overlay_action eq 'ignore') {
1606 $auth_result = 'ignore';
1609 $auth_result = $nomatch_action;
1612 return ($auth_result, undef, $auth_match);
1617 sub _get_revert_action {
1618 my ($overlay_action, $overlay_status, $status) = @_;
1622 if ($status eq 'ignored') {
1623 $bib_result = 'ignore';
1625 if ($overlay_action eq 'create_new') {
1626 $bib_result = 'delete';
1628 $bib_result = ($overlay_status eq 'match_applied') ? 'restore' : 'delete';
1639 Koha Development Team <http://koha-community.org/>
1641 Galen Charlton <galen.charlton@liblime.com>