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;
33 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
36 # set the version for version checking
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
85 our $logger = Koha::Logger->get( { category => 'C4.ImportBatch' } );
89 C4::ImportBatch - manage batches of imported MARC records
97 =head2 GetZ3950BatchId
99 my $batchid = GetZ3950BatchId($z3950server);
101 Retrieves the ID of the import batch for the Z39.50
102 reservoir for the given target. If necessary,
103 creates the import batch.
107 sub GetZ3950BatchId {
108 my ($z3950server) = @_;
110 my $dbh = C4::Context->dbh;
111 my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
112 WHERE batch_type = 'z3950'
114 $sth->execute($z3950server);
115 my $rowref = $sth->fetchrow_arrayref();
117 if (defined $rowref) {
120 my $batch_id = AddImportBatch( {
121 overlay_action => 'create_new',
122 import_status => 'staged',
123 batch_type => 'z3950',
124 file_name => $z3950server,
131 =head2 GetWebserviceBatchId
133 my $batchid = GetWebserviceBatchId();
135 Retrieves the ID of the import batch for webservice.
136 If necessary, creates the import batch.
140 my $WEBSERVICE_BASE_QRY = <<EOQ;
141 SELECT import_batch_id FROM import_batches
142 WHERE batch_type = 'webservice'
143 AND import_status = 'staged'
145 sub GetWebserviceBatchId {
148 my $dbh = C4::Context->dbh;
149 my $sql = $WEBSERVICE_BASE_QRY;
151 foreach my $field (qw(matcher_id overlay_action nomatch_action item_action)) {
152 if (my $val = $params->{$field}) {
153 $sql .= " AND $field = ?";
157 my $id = $dbh->selectrow_array($sql, undef, @args);
160 $params->{batch_type} = 'webservice';
161 $params->{import_status} = 'staged';
162 return AddImportBatch($params);
165 =head2 GetImportRecordMarc
167 my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);
171 sub GetImportRecordMarc {
172 my ($import_record_id) = @_;
174 my $dbh = C4::Context->dbh;
175 my ( $marc, $encoding ) = $dbh->selectrow_array(q|
176 SELECT marc, encoding
178 WHERE import_record_id = ?
179 |, undef, $import_record_id );
181 return $marc, $encoding;
184 sub GetRecordFromImportBiblio {
185 my ( $import_record_id, $embed_items ) = @_;
187 my ($marc) = GetImportRecordMarc($import_record_id);
188 my $record = MARC::Record->new_from_usmarc($marc);
190 EmbedItemsInImportBiblio( $record, $import_record_id ) if $embed_items;
195 sub EmbedItemsInImportBiblio {
196 my ( $record, $import_record_id ) = @_;
197 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber", '');
198 my $dbh = C4::Context->dbh;
199 my $import_items = $dbh->selectall_arrayref(q|
200 SELECT import_items.marcxml
202 WHERE import_record_id = ?
203 |, { Slice => {} }, $import_record_id );
205 for my $import_item ( @$import_items ) {
206 my $item_marc = MARC::Record::new_from_xml($import_item->{marcxml});
207 push @item_fields, $item_marc->field($itemtag);
209 $record->append_fields(@item_fields);
213 =head2 GetImportRecordMarcXML
215 my $marcxml = GetImportRecordMarcXML($import_record_id);
219 sub GetImportRecordMarcXML {
220 my ($import_record_id) = @_;
222 my $dbh = C4::Context->dbh;
223 my $sth = $dbh->prepare("SELECT marcxml FROM import_records WHERE import_record_id = ?");
224 $sth->execute($import_record_id);
225 my ($marcxml) = $sth->fetchrow();
231 =head2 AddImportBatch
233 my $batch_id = AddImportBatch($params_hash);
241 foreach (qw( matcher_id template_id branchcode
242 overlay_action nomatch_action item_action
243 import_status batch_type file_name comments record_type )) {
244 if (exists $params->{$_}) {
246 push @vals, $params->{$_};
249 my $dbh = C4::Context->dbh;
250 $dbh->do("INSERT INTO import_batches (".join( ',', @fields).")
251 VALUES (".join( ',', map '?', @fields).")",
254 return $dbh->{'mysql_insertid'};
257 =head2 GetImportBatch
259 my $row = GetImportBatch($batch_id);
261 Retrieve a hashref of an import_batches row.
268 my $dbh = C4::Context->dbh;
269 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
270 $sth->bind_param(1, $batch_id);
272 my $result = $sth->fetchrow_hashref;
278 =head2 AddBiblioToBatch
280 my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence,
281 $marc_record, $encoding, $z3950random, $update_counts);
285 sub AddBiblioToBatch {
286 my $batch_id = shift;
287 my $record_sequence = shift;
288 my $marc_record = shift;
289 my $encoding = shift;
290 my $z3950random = shift;
291 my $update_counts = @_ ? shift : 1;
293 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random, C4::Context->preference('marcflavour'));
294 _add_biblio_fields($import_record_id, $marc_record);
295 _update_batch_record_counts($batch_id) if $update_counts;
296 return $import_record_id;
299 =head2 ModBiblioInBatch
301 ModBiblioInBatch($import_record_id, $marc_record);
305 sub ModBiblioInBatch {
306 my ($import_record_id, $marc_record) = @_;
308 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
309 _update_biblio_fields($import_record_id, $marc_record);
313 =head2 AddAuthToBatch
315 my $import_record_id = AddAuthToBatch($batch_id, $record_sequence,
316 $marc_record, $encoding, $z3950random, $update_counts, [$marc_type]);
321 my $batch_id = shift;
322 my $record_sequence = shift;
323 my $marc_record = shift;
324 my $encoding = shift;
325 my $z3950random = shift;
326 my $update_counts = @_ ? shift : 1;
327 my $marc_type = shift || C4::Context->preference('marcflavour');
329 $marc_type = 'UNIMARCAUTH' if $marc_type eq 'UNIMARC';
331 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'auth', $encoding, $z3950random, $marc_type);
332 _add_auth_fields($import_record_id, $marc_record);
333 _update_batch_record_counts($batch_id) if $update_counts;
334 return $import_record_id;
337 =head2 ModAuthInBatch
339 ModAuthInBatch($import_record_id, $marc_record);
344 my ($import_record_id, $marc_record) = @_;
346 my $marcflavour = C4::Context->preference('marcflavour');
347 _update_import_record_marc($import_record_id, $marc_record, $marcflavour eq 'UNIMARC' ? 'UNIMARCAUTH' : 'USMARC');
351 =head2 BatchStageMarcRecords
353 ( $batch_id, $num_records, $num_items, @invalid_records ) =
354 BatchStageMarcRecords(
355 $encoding, $marc_records,
356 $file_name, $to_marc_plugin,
357 $marc_modification_template, $comments,
358 $branch_code, $parse_items,
359 $leave_as_staging, $progress_interval,
365 sub BatchStageMarcRecords {
366 my $record_type = shift;
367 my $encoding = shift;
368 my $marc_records = shift;
369 my $file_name = shift;
370 my $to_marc_plugin = shift;
371 my $marc_modification_template = shift;
372 my $comments = shift;
373 my $branch_code = shift;
374 my $parse_items = shift;
375 my $leave_as_staging = shift;
377 # optional callback to monitor status
379 my $progress_interval = 0;
380 my $progress_callback = undef;
382 $progress_interval = shift;
383 $progress_callback = shift;
384 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
385 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
388 my $batch_id = AddImportBatch( {
389 overlay_action => 'create_new',
390 import_status => 'staging',
391 batch_type => 'batch',
392 file_name => $file_name,
393 comments => $comments,
394 record_type => $record_type,
397 SetImportBatchItemAction($batch_id, 'always_add');
399 SetImportBatchItemAction($batch_id, 'ignore');
402 $marc_records = Koha::Plugins::Handler->run(
404 class => $to_marc_plugin,
406 params => { data => $marc_records }
408 ) if $to_marc_plugin;
410 my $marc_type = C4::Context->preference('marcflavour');
411 $marc_type .= 'AUTH' if ($marc_type eq 'UNIMARC' && $record_type eq 'auth');
412 my @invalid_records = ();
415 # FIXME - for now, we're dealing only with bibs
417 foreach my $marc_blob (split(/\x1D/, $marc_records)) {
418 $marc_blob =~ s/^\s+//g;
419 $marc_blob =~ s/\s+$//g;
420 next unless $marc_blob;
422 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
423 &$progress_callback($rec_num);
425 my ($marc_record, $charset_guessed, $char_errors) =
426 MarcToUTF8Record($marc_blob, $marc_type, $encoding);
428 $encoding = $charset_guessed unless $encoding;
430 ModifyRecordWithTemplate( $marc_modification_template, $marc_record ) if ( $marc_modification_template );
432 my $import_record_id;
433 if (scalar($marc_record->fields()) == 0) {
434 push @invalid_records, $marc_blob;
437 # Normalize the record so it doesn't have separated diacritics
438 SetUTF8Flag($marc_record);
441 if ($record_type eq 'biblio') {
442 $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
444 my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
445 $num_items += scalar(@import_items_ids);
447 } elsif ($record_type eq 'auth') {
448 $import_record_id = AddAuthToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0, $marc_type);
452 unless ($leave_as_staging) {
453 SetImportBatchStatus($batch_id, 'staged');
455 # FIXME branch_code, number of bibs, number of items
456 _update_batch_record_counts($batch_id);
457 return ($batch_id, $num_valid, $num_items, @invalid_records);
460 =head2 AddItemsToImportBiblio
462 my @import_items_ids = AddItemsToImportBiblio($batch_id,
463 $import_record_id, $marc_record, $update_counts);
467 sub AddItemsToImportBiblio {
468 my $batch_id = shift;
469 my $import_record_id = shift;
470 my $marc_record = shift;
471 my $update_counts = @_ ? shift : 0;
473 my @import_items_ids = ();
475 my $dbh = C4::Context->dbh;
476 my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
477 foreach my $item_field ($marc_record->field($item_tag)) {
478 my $item_marc = MARC::Record->new();
479 $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
480 $item_marc->append_fields($item_field);
481 $marc_record->delete_field($item_field);
482 my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
484 $sth->bind_param(1, $import_record_id);
485 $sth->bind_param(2, 'staged');
486 $sth->bind_param(3, $item_marc->as_xml());
488 push @import_items_ids, $dbh->{'mysql_insertid'};
492 if ($#import_items_ids > -1) {
493 _update_batch_record_counts($batch_id) if $update_counts;
494 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
496 return @import_items_ids;
499 =head2 BatchFindDuplicates
501 my $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
502 $max_matches, $progress_interval, $progress_callback);
504 Goes through the records loaded in the batch and attempts to
505 find duplicates for each one. Sets the matching status
506 of each record to "no_match" or "auto_match" as appropriate.
508 The $max_matches parameter is optional; if it is not supplied,
511 The $progress_interval and $progress_callback parameters are
512 optional; if both are supplied, the sub referred to by
513 $progress_callback will be invoked every $progress_interval
514 records using the number of records processed as the
519 sub BatchFindDuplicates {
520 my $batch_id = shift;
522 my $max_matches = @_ ? shift : 10;
524 # optional callback to monitor status
526 my $progress_interval = 0;
527 my $progress_callback = undef;
529 $progress_interval = shift;
530 $progress_callback = shift;
531 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
532 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
535 my $dbh = C4::Context->dbh;
537 my $sth = $dbh->prepare("SELECT import_record_id, record_type, marc
539 WHERE import_batch_id = ?");
540 $sth->execute($batch_id);
541 my $num_with_matches = 0;
543 while (my $rowref = $sth->fetchrow_hashref) {
545 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
546 &$progress_callback($rec_num);
548 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
550 if (defined $matcher) {
551 @matches = $matcher->get_matches($marc_record, $max_matches);
553 if (scalar(@matches) > 0) {
555 SetImportRecordMatches($rowref->{'import_record_id'}, @matches);
556 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'auto_match');
558 SetImportRecordMatches($rowref->{'import_record_id'}, ());
559 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'no_match');
563 return $num_with_matches;
566 =head2 BatchCommitRecords
568 my ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored) =
569 BatchCommitRecords($batch_id, $framework,
570 $progress_interval, $progress_callback);
574 sub BatchCommitRecords {
575 my $batch_id = shift;
576 my $framework = shift;
578 # optional callback to monitor status
580 my $progress_interval = 0;
581 my $progress_callback = undef;
583 $progress_interval = shift;
584 $progress_callback = shift;
585 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
586 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
592 my $num_items_added = 0;
593 my $num_items_replaced = 0;
594 my $num_items_errored = 0;
596 # commit (i.e., save, all records in the batch)
597 SetImportBatchStatus('importing');
598 my $overlay_action = GetImportBatchOverlayAction($batch_id);
599 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
600 my $item_action = GetImportBatchItemAction($batch_id);
603 my $dbh = C4::Context->dbh;
604 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marc, encoding
606 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
607 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
608 WHERE import_batch_id = ?");
609 $sth->execute($batch_id);
610 my $marcflavour = C4::Context->preference('marcflavour');
612 while (my $rowref = $sth->fetchrow_hashref) {
613 $record_type = $rowref->{'record_type'};
615 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
616 &$progress_callback($rec_num);
618 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
624 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
625 $marc_type = 'UNIMARCAUTH';
626 } elsif ($marcflavour eq 'UNIMARC') {
627 $marc_type = 'UNIMARC';
629 $marc_type = 'USMARC';
631 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
633 if ($record_type eq 'biblio') {
634 # remove any item tags - rely on BatchCommitItems
635 ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
636 foreach my $item_field ($marc_record->field($item_tag)) {
637 $marc_record->delete_field($item_field);
641 my ($record_result, $item_result, $record_match) =
642 _get_commit_action($overlay_action, $nomatch_action, $item_action,
643 $rowref->{'overlay_status'}, $rowref->{'import_record_id'}, $record_type);
647 if ($record_result eq 'create_new') {
649 if ($record_type eq 'biblio') {
650 my $biblioitemnumber;
651 ($recordid, $biblioitemnumber) = AddBiblio($marc_record, $framework);
652 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
653 if ($item_result eq 'create_new' || $item_result eq 'replace') {
654 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
655 $num_items_added += $bib_items_added;
656 $num_items_replaced += $bib_items_replaced;
657 $num_items_errored += $bib_items_errored;
660 $recordid = AddAuthority($marc_record, undef, GuessAuthTypeCode($marc_record));
661 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
663 my $sth = $dbh->prepare_cached($query);
664 $sth->execute($recordid, $rowref->{'import_record_id'});
666 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
667 } elsif ($record_result eq 'replace') {
669 $recordid = $record_match;
671 if ($record_type eq 'biblio') {
672 my $oldbiblio = GetBiblio($recordid);
673 $oldxml = GetXmlBiblio($recordid);
675 # remove item fields so that they don't get
676 # added again if record is reverted
677 # 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.
678 my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'}, $marc_type);
679 foreach my $item_field ($old_marc->field($item_tag)) {
680 $old_marc->delete_field($item_field);
682 $oldxml = $old_marc->as_xml($marc_type);
684 ModBiblio($marc_record, $recordid, $oldbiblio->{'frameworkcode'});
685 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
687 if ($item_result eq 'create_new' || $item_result eq 'replace') {
688 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
689 $num_items_added += $bib_items_added;
690 $num_items_replaced += $bib_items_replaced;
691 $num_items_errored += $bib_items_errored;
694 $oldxml = GetAuthorityXML($recordid);
696 ModAuthority($recordid, $marc_record, GuessAuthTypeCode($marc_record));
697 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
699 my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
700 $sth->execute($oldxml, $rowref->{'import_record_id'});
702 my $sth2 = $dbh->prepare_cached($query);
703 $sth2->execute($recordid, $rowref->{'import_record_id'});
705 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
706 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
707 } elsif ($record_result eq 'ignore') {
708 $recordid = $record_match;
710 $recordid = $record_match;
711 if ($record_type eq 'biblio' and defined $recordid and ( $item_result eq 'create_new' || $item_result eq 'replace' ) ) {
712 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
713 $num_items_added += $bib_items_added;
714 $num_items_replaced += $bib_items_replaced;
715 $num_items_errored += $bib_items_errored;
716 # still need to record the matched biblionumber so that the
717 # items can be reverted
718 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
719 $sth2->execute($recordid, $rowref->{'import_record_id'});
720 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
722 SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
726 SetImportBatchStatus($batch_id, 'imported');
727 return ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored);
730 =head2 BatchCommitItems
732 ($num_items_added, $num_items_errored) =
733 BatchCommitItems($import_record_id, $biblionumber);
737 sub BatchCommitItems {
738 my ( $import_record_id, $biblionumber, $action ) = @_;
740 my $dbh = C4::Context->dbh;
742 my $num_items_added = 0;
743 my $num_items_errored = 0;
744 my $num_items_replaced = 0;
746 my $sth = $dbh->prepare( "
747 SELECT import_items_id, import_items.marcxml, encoding
749 JOIN import_records USING (import_record_id)
750 WHERE import_record_id = ?
751 ORDER BY import_items_id
753 $sth->bind_param( 1, $import_record_id );
756 while ( my $row = $sth->fetchrow_hashref() ) {
757 my $item_marc = MARC::Record->new_from_xml( StripNonXmlChars( $row->{'marcxml'} ), 'UTF-8', $row->{'encoding'} );
759 # Delete date_due subfield as to not accidentally delete item checkout due dates
760 my ( $MARCfield, $MARCsubfield ) = GetMarcFromKohaField( 'items.onloan', GetFrameworkCode($biblionumber) );
761 $item_marc->field($MARCfield)->delete_subfield( code => $MARCsubfield );
763 my $item = TransformMarcToKoha( $dbh, $item_marc );
765 my $duplicate_barcode = exists( $item->{'barcode'} ) && GetItemnumberFromBarcode( $item->{'barcode'} );
766 my $duplicate_itemnumber = exists( $item->{'itemnumber'} );
768 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
769 if ( $action eq "replace" && $duplicate_itemnumber ) {
770 # Duplicate itemnumbers have precedence, that way we can update barcodes by overlaying
771 ModItemFromMarc( $item_marc, $biblionumber, $item->{itemnumber} );
772 $updsth->bind_param( 1, 'imported' );
773 $updsth->bind_param( 2, $item->{itemnumber} );
774 $updsth->bind_param( 3, $row->{'import_items_id'} );
777 $num_items_replaced++;
778 } elsif ( $action eq "replace" && $duplicate_barcode ) {
779 my $itemnumber = GetItemnumberFromBarcode( $item->{'barcode'} );
780 ModItemFromMarc( $item_marc, $biblionumber, $itemnumber );
781 $updsth->bind_param( 1, 'imported' );
782 $updsth->bind_param( 2, $item->{itemnumber} );
783 $updsth->bind_param( 3, $row->{'import_items_id'} );
786 $num_items_replaced++;
787 } elsif ($duplicate_barcode) {
788 $updsth->bind_param( 1, 'error' );
789 $updsth->bind_param( 2, 'duplicate item barcode' );
790 $updsth->bind_param( 3, $row->{'import_items_id'} );
792 $num_items_errored++;
794 my ( $item_biblionumber, $biblioitemnumber, $itemnumber ) = AddItemFromMarc( $item_marc, $biblionumber );
795 $updsth->bind_param( 1, 'imported' );
796 $updsth->bind_param( 2, $itemnumber );
797 $updsth->bind_param( 3, $row->{'import_items_id'} );
804 return ( $num_items_added, $num_items_replaced, $num_items_errored );
807 =head2 BatchRevertRecords
809 my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted,
810 $num_ignored) = BatchRevertRecords($batch_id);
814 sub BatchRevertRecords {
815 my $batch_id = shift;
817 $logger->trace("C4::ImportBatch::BatchRevertRecords( $batch_id )");
822 my $num_reverted = 0;
824 my $num_items_deleted = 0;
825 # commit (i.e., save, all records in the batch)
826 SetImportBatchStatus('reverting');
827 my $overlay_action = GetImportBatchOverlayAction($batch_id);
828 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
829 my $dbh = C4::Context->dbh;
830 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marcxml_old, encoding, matched_biblionumber, matched_authid
832 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
833 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
834 WHERE import_batch_id = ?");
835 $sth->execute($batch_id);
837 my $marcflavour = C4::Context->preference('marcflavour');
838 while (my $rowref = $sth->fetchrow_hashref) {
839 $record_type = $rowref->{'record_type'};
840 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
844 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
845 $marc_type = 'UNIMARCAUTH';
846 } elsif ($marcflavour eq 'UNIMARC') {
847 $marc_type = 'UNIMARC';
849 $marc_type = 'USMARC';
852 my $record_result = _get_revert_action($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
854 if ($record_result eq 'delete') {
856 if ($record_type eq 'biblio') {
857 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
858 $error = DelBiblio($rowref->{'matched_biblionumber'});
860 my $deletedauthid = DelAuthority($rowref->{'matched_authid'});
862 if (defined $error) {
866 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
868 } elsif ($record_result eq 'restore') {
870 my $old_record = MARC::Record->new_from_xml(StripNonXmlChars($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'}, $marc_type);
871 if ($record_type eq 'biblio') {
872 my $biblionumber = $rowref->{'matched_biblionumber'};
873 my $oldbiblio = GetBiblio($biblionumber);
875 $logger->info("C4::ImportBatch::BatchRevertRecords: Biblio record $biblionumber does not exist, restoration of this record was skipped") unless $oldbiblio;
876 next unless $oldbiblio; # Record has since been deleted. Deleted records should stay deleted.
878 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
879 ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
881 my $authid = $rowref->{'matched_authid'};
882 ModAuthority($authid, $old_record, GuessAuthTypeCode($old_record));
884 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
885 } elsif ($record_result eq 'ignore') {
886 if ($record_type eq 'biblio') {
887 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
889 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
892 if ($record_type eq 'biblio') {
893 # remove matched_biblionumber only if there is no 'imported' item left
894 $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?";
895 $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')";
897 $query = "UPDATE import_auths SET matched_authid = NULL WHERE import_record_id = ?";
899 my $sth2 = $dbh->prepare_cached($query);
900 $sth2->execute($rowref->{'import_record_id'});
904 SetImportBatchStatus($batch_id, 'reverted');
905 return ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored);
908 =head2 BatchRevertItems
910 my $num_items_deleted = BatchRevertItems($import_record_id, $biblionumber);
914 sub BatchRevertItems {
915 my ($import_record_id, $biblionumber) = @_;
917 my $dbh = C4::Context->dbh;
918 my $num_items_deleted = 0;
920 my $sth = $dbh->prepare_cached("SELECT import_items_id, itemnumber
922 JOIN items USING (itemnumber)
923 WHERE import_record_id = ?");
924 $sth->bind_param(1, $import_record_id);
926 while (my $row = $sth->fetchrow_hashref()) {
927 my $error = DelItemCheck($dbh, $biblionumber, $row->{'itemnumber'});
929 my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
930 $updsth->bind_param(1, 'reverted');
931 $updsth->bind_param(2, $row->{'import_items_id'});
934 $num_items_deleted++;
941 return $num_items_deleted;
946 CleanBatch($batch_id)
948 Deletes all staged records from the import batch
949 and sets the status of the batch to 'cleaned'. Note
950 that deleting a stage record does *not* affect
951 any record that has been committed to the database.
956 my $batch_id = shift;
957 return unless defined $batch_id;
959 C4::Context->dbh->do('DELETE FROM import_records WHERE import_batch_id = ?', {}, $batch_id);
960 SetImportBatchStatus($batch_id, 'cleaned');
963 =head2 GetAllImportBatches
965 my $results = GetAllImportBatches();
967 Returns a references to an array of hash references corresponding
968 to all import_batches rows (of batch_type 'batch'), sorted in
969 ascending order by import_batch_id.
973 sub GetAllImportBatches {
974 my $dbh = C4::Context->dbh;
975 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
976 WHERE batch_type IN ('batch', 'webservice')
977 ORDER BY import_batch_id ASC");
981 while (my $row = $sth->fetchrow_hashref) {
982 push @$results, $row;
988 =head2 GetStagedWebserviceBatches
990 my $batch_ids = GetStagedWebserviceBatches();
992 Returns a references to an array of batch id's
993 of batch_type 'webservice' that are not imported
997 my $PENDING_WEBSERVICE_BATCHES_QRY = <<EOQ;
998 SELECT import_batch_id FROM import_batches
999 WHERE batch_type = 'webservice'
1000 AND import_status = 'staged'
1002 sub GetStagedWebserviceBatches {
1003 my $dbh = C4::Context->dbh;
1004 return $dbh->selectcol_arrayref($PENDING_WEBSERVICE_BATCHES_QRY);
1007 =head2 GetImportBatchRangeDesc
1009 my $results = GetImportBatchRangeDesc($offset, $results_per_group);
1011 Returns a reference to an array of hash references corresponding to
1012 import_batches rows (sorted in descending order by import_batch_id)
1013 start at the given offset.
1017 sub GetImportBatchRangeDesc {
1018 my ($offset, $results_per_group) = @_;
1020 my $dbh = C4::Context->dbh;
1021 my $query = "SELECT * FROM import_batches
1022 WHERE batch_type IN ('batch', 'webservice')
1023 ORDER BY import_batch_id DESC";
1025 if ($results_per_group){
1026 $query .= " LIMIT ?";
1027 push(@params, $results_per_group);
1030 $query .= " OFFSET ?";
1031 push(@params, $offset);
1033 my $sth = $dbh->prepare_cached($query);
1034 $sth->execute(@params);
1035 my $results = $sth->fetchall_arrayref({});
1040 =head2 GetItemNumbersFromImportBatch
1042 my @itemsnos = GetItemNumbersFromImportBatch($batch_id);
1046 sub GetItemNumbersFromImportBatch {
1047 my ($batch_id) = @_;
1048 my $dbh = C4::Context->dbh;
1049 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=?");
1050 $sth->execute($batch_id);
1052 while ( my ($itm) = $sth->fetchrow_array ) {
1058 =head2 GetNumberOfImportBatches
1060 my $count = GetNumberOfImportBatches();
1064 sub GetNumberOfNonZ3950ImportBatches {
1065 my $dbh = C4::Context->dbh;
1066 my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type != 'z3950'");
1068 my ($count) = $sth->fetchrow_array();
1073 =head2 GetImportBiblios
1075 my $results = GetImportBiblios($importid);
1079 sub GetImportBiblios {
1080 my ($import_record_id) = @_;
1082 my $dbh = C4::Context->dbh;
1083 my $query = "SELECT * FROM import_biblios WHERE import_record_id = ?";
1084 return $dbh->selectall_arrayref(
1092 =head2 GetImportRecordsRange
1094 my $results = GetImportRecordsRange($batch_id, $offset, $results_per_group);
1096 Returns a reference to an array of hash references corresponding to
1097 import_biblios/import_auths/import_records rows for a given batch
1098 starting at the given offset.
1102 sub GetImportRecordsRange {
1103 my ( $batch_id, $offset, $results_per_group, $status, $parameters ) = @_;
1105 my $dbh = C4::Context->dbh;
1107 my $order_by = $parameters->{order_by} || 'import_record_id';
1108 ( $order_by ) = grep( /^$order_by$/, qw( import_record_id title status overlay_status ) ) ? $order_by : 'import_record_id';
1110 my $order_by_direction =
1111 uc( $parameters->{order_by_direction} ) eq 'DESC' ? 'DESC' : 'ASC';
1113 $order_by .= " $order_by_direction, authorized_heading" if $order_by eq 'title';
1115 my $query = "SELECT title, author, isbn, issn, authorized_heading, import_records.import_record_id,
1116 record_sequence, status, overlay_status,
1117 matched_biblionumber, matched_authid, record_type
1119 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
1120 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
1121 WHERE import_batch_id = ?";
1123 push(@params, $batch_id);
1125 $query .= " AND status=?";
1126 push(@params,$status);
1129 $query.=" ORDER BY $order_by $order_by_direction";
1131 if($results_per_group){
1132 $query .= " LIMIT ?";
1133 push(@params, $results_per_group);
1136 $query .= " OFFSET ?";
1137 push(@params, $offset);
1139 my $sth = $dbh->prepare_cached($query);
1140 $sth->execute(@params);
1141 my $results = $sth->fetchall_arrayref({});
1147 =head2 GetBestRecordMatch
1149 my $record_id = GetBestRecordMatch($import_record_id);
1153 sub GetBestRecordMatch {
1154 my ($import_record_id) = @_;
1156 my $dbh = C4::Context->dbh;
1157 my $sth = $dbh->prepare("SELECT candidate_match_id
1158 FROM import_record_matches
1159 JOIN import_records ON ( import_record_matches.import_record_id = import_records.import_record_id )
1160 LEFT JOIN biblio ON ( candidate_match_id = biblio.biblionumber )
1161 LEFT JOIN auth_header ON ( candidate_match_id = auth_header.authid )
1162 WHERE import_record_matches.import_record_id = ? AND
1163 ( (import_records.record_type = 'biblio' AND biblio.biblionumber IS NOT NULL) OR
1164 (import_records.record_type = 'auth' AND auth_header.authid IS NOT NULL) )
1165 ORDER BY score DESC, candidate_match_id DESC");
1166 $sth->execute($import_record_id);
1167 my ($record_id) = $sth->fetchrow_array();
1172 =head2 GetImportBatchStatus
1174 my $status = GetImportBatchStatus($batch_id);
1178 sub GetImportBatchStatus {
1179 my ($batch_id) = @_;
1181 my $dbh = C4::Context->dbh;
1182 my $sth = $dbh->prepare("SELECT import_status FROM import_batches WHERE import_batch_id = ?");
1183 $sth->execute($batch_id);
1184 my ($status) = $sth->fetchrow_array();
1190 =head2 SetImportBatchStatus
1192 SetImportBatchStatus($batch_id, $new_status);
1196 sub SetImportBatchStatus {
1197 my ($batch_id, $new_status) = @_;
1199 my $dbh = C4::Context->dbh;
1200 my $sth = $dbh->prepare("UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?");
1201 $sth->execute($new_status, $batch_id);
1206 =head2 GetImportBatchOverlayAction
1208 my $overlay_action = GetImportBatchOverlayAction($batch_id);
1212 sub GetImportBatchOverlayAction {
1213 my ($batch_id) = @_;
1215 my $dbh = C4::Context->dbh;
1216 my $sth = $dbh->prepare("SELECT overlay_action FROM import_batches WHERE import_batch_id = ?");
1217 $sth->execute($batch_id);
1218 my ($overlay_action) = $sth->fetchrow_array();
1220 return $overlay_action;
1225 =head2 SetImportBatchOverlayAction
1227 SetImportBatchOverlayAction($batch_id, $new_overlay_action);
1231 sub SetImportBatchOverlayAction {
1232 my ($batch_id, $new_overlay_action) = @_;
1234 my $dbh = C4::Context->dbh;
1235 my $sth = $dbh->prepare("UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?");
1236 $sth->execute($new_overlay_action, $batch_id);
1241 =head2 GetImportBatchNoMatchAction
1243 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
1247 sub GetImportBatchNoMatchAction {
1248 my ($batch_id) = @_;
1250 my $dbh = C4::Context->dbh;
1251 my $sth = $dbh->prepare("SELECT nomatch_action FROM import_batches WHERE import_batch_id = ?");
1252 $sth->execute($batch_id);
1253 my ($nomatch_action) = $sth->fetchrow_array();
1255 return $nomatch_action;
1260 =head2 SetImportBatchNoMatchAction
1262 SetImportBatchNoMatchAction($batch_id, $new_nomatch_action);
1266 sub SetImportBatchNoMatchAction {
1267 my ($batch_id, $new_nomatch_action) = @_;
1269 my $dbh = C4::Context->dbh;
1270 my $sth = $dbh->prepare("UPDATE import_batches SET nomatch_action = ? WHERE import_batch_id = ?");
1271 $sth->execute($new_nomatch_action, $batch_id);
1276 =head2 GetImportBatchItemAction
1278 my $item_action = GetImportBatchItemAction($batch_id);
1282 sub GetImportBatchItemAction {
1283 my ($batch_id) = @_;
1285 my $dbh = C4::Context->dbh;
1286 my $sth = $dbh->prepare("SELECT item_action FROM import_batches WHERE import_batch_id = ?");
1287 $sth->execute($batch_id);
1288 my ($item_action) = $sth->fetchrow_array();
1290 return $item_action;
1295 =head2 SetImportBatchItemAction
1297 SetImportBatchItemAction($batch_id, $new_item_action);
1301 sub SetImportBatchItemAction {
1302 my ($batch_id, $new_item_action) = @_;
1304 my $dbh = C4::Context->dbh;
1305 my $sth = $dbh->prepare("UPDATE import_batches SET item_action = ? WHERE import_batch_id = ?");
1306 $sth->execute($new_item_action, $batch_id);
1311 =head2 GetImportBatchMatcher
1313 my $matcher_id = GetImportBatchMatcher($batch_id);
1317 sub GetImportBatchMatcher {
1318 my ($batch_id) = @_;
1320 my $dbh = C4::Context->dbh;
1321 my $sth = $dbh->prepare("SELECT matcher_id FROM import_batches WHERE import_batch_id = ?");
1322 $sth->execute($batch_id);
1323 my ($matcher_id) = $sth->fetchrow_array();
1330 =head2 SetImportBatchMatcher
1332 SetImportBatchMatcher($batch_id, $new_matcher_id);
1336 sub SetImportBatchMatcher {
1337 my ($batch_id, $new_matcher_id) = @_;
1339 my $dbh = C4::Context->dbh;
1340 my $sth = $dbh->prepare("UPDATE import_batches SET matcher_id = ? WHERE import_batch_id = ?");
1341 $sth->execute($new_matcher_id, $batch_id);
1346 =head2 GetImportRecordOverlayStatus
1348 my $overlay_status = GetImportRecordOverlayStatus($import_record_id);
1352 sub GetImportRecordOverlayStatus {
1353 my ($import_record_id) = @_;
1355 my $dbh = C4::Context->dbh;
1356 my $sth = $dbh->prepare("SELECT overlay_status FROM import_records WHERE import_record_id = ?");
1357 $sth->execute($import_record_id);
1358 my ($overlay_status) = $sth->fetchrow_array();
1360 return $overlay_status;
1365 =head2 SetImportRecordOverlayStatus
1367 SetImportRecordOverlayStatus($import_record_id, $new_overlay_status);
1371 sub SetImportRecordOverlayStatus {
1372 my ($import_record_id, $new_overlay_status) = @_;
1374 my $dbh = C4::Context->dbh;
1375 my $sth = $dbh->prepare("UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?");
1376 $sth->execute($new_overlay_status, $import_record_id);
1381 =head2 GetImportRecordStatus
1383 my $status = GetImportRecordStatus($import_record_id);
1387 sub GetImportRecordStatus {
1388 my ($import_record_id) = @_;
1390 my $dbh = C4::Context->dbh;
1391 my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
1392 $sth->execute($import_record_id);
1393 my ($status) = $sth->fetchrow_array();
1400 =head2 SetImportRecordStatus
1402 SetImportRecordStatus($import_record_id, $new_status);
1406 sub SetImportRecordStatus {
1407 my ($import_record_id, $new_status) = @_;
1409 my $dbh = C4::Context->dbh;
1410 my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
1411 $sth->execute($new_status, $import_record_id);
1416 =head2 GetImportRecordMatches
1418 my $results = GetImportRecordMatches($import_record_id, $best_only);
1422 sub GetImportRecordMatches {
1423 my $import_record_id = shift;
1424 my $best_only = @_ ? shift : 0;
1426 my $dbh = C4::Context->dbh;
1427 # FIXME currently biblio only
1428 my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber,
1429 candidate_match_id, score, record_type
1431 JOIN import_record_matches USING (import_record_id)
1432 LEFT JOIN biblio ON (biblionumber = candidate_match_id)
1433 WHERE import_record_id = ?
1434 ORDER BY score DESC, biblionumber DESC");
1435 $sth->bind_param(1, $import_record_id);
1438 while (my $row = $sth->fetchrow_hashref) {
1439 if ($row->{'record_type'} eq 'auth') {
1440 $row->{'authorized_heading'} = C4::AuthoritiesMarc::GetAuthorizedHeading( { authid => $row->{'candidate_match_id'} } );
1442 next if ($row->{'record_type'} eq 'biblio' && not $row->{'biblionumber'});
1443 push @$results, $row;
1453 =head2 SetImportRecordMatches
1455 SetImportRecordMatches($import_record_id, @matches);
1459 sub SetImportRecordMatches {
1460 my $import_record_id = shift;
1463 my $dbh = C4::Context->dbh;
1464 my $delsth = $dbh->prepare("DELETE FROM import_record_matches WHERE import_record_id = ?");
1465 $delsth->execute($import_record_id);
1468 my $sth = $dbh->prepare("INSERT INTO import_record_matches (import_record_id, candidate_match_id, score)
1470 foreach my $match (@matches) {
1471 $sth->execute($import_record_id, $match->{'record_id'}, $match->{'score'});
1476 # internal functions
1478 sub _create_import_record {
1479 my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random, $marc_type) = @_;
1481 my $dbh = C4::Context->dbh;
1482 my $sth = $dbh->prepare("INSERT INTO import_records (import_batch_id, record_sequence, marc, marcxml,
1483 record_type, encoding, z3950random)
1484 VALUES (?, ?, ?, ?, ?, ?, ?)");
1485 $sth->execute($batch_id, $record_sequence, $marc_record->as_usmarc(), $marc_record->as_xml($marc_type),
1486 $record_type, $encoding, $z3950random);
1487 my $import_record_id = $dbh->{'mysql_insertid'};
1489 return $import_record_id;
1492 sub _update_import_record_marc {
1493 my ($import_record_id, $marc_record, $marc_type) = @_;
1495 my $dbh = C4::Context->dbh;
1496 my $sth = $dbh->prepare("UPDATE import_records SET marc = ?, marcxml = ?
1497 WHERE import_record_id = ?");
1498 $sth->execute($marc_record->as_usmarc(), $marc_record->as_xml($marc_type), $import_record_id);
1502 sub _add_auth_fields {
1503 my ($import_record_id, $marc_record) = @_;
1506 if ($marc_record->field('001')) {
1507 $controlnumber = $marc_record->field('001')->data();
1509 my $authorized_heading = C4::AuthoritiesMarc::GetAuthorizedHeading({ record => $marc_record });
1510 my $dbh = C4::Context->dbh;
1511 my $sth = $dbh->prepare("INSERT INTO import_auths (import_record_id, control_number, authorized_heading) VALUES (?, ?, ?)");
1512 $sth->execute($import_record_id, $controlnumber, $authorized_heading);
1516 sub _add_biblio_fields {
1517 my ($import_record_id, $marc_record) = @_;
1519 my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1520 my $dbh = C4::Context->dbh;
1521 # FIXME no controlnumber, originalsource
1522 $isbn = C4::Koha::GetNormalizedISBN($isbn);
1523 my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1524 $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1529 sub _update_biblio_fields {
1530 my ($import_record_id, $marc_record) = @_;
1532 my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1533 my $dbh = C4::Context->dbh;
1534 # FIXME no controlnumber, originalsource
1535 # FIXME 2 - should regularize normalization of ISBN wherever it is done
1539 my $sth = $dbh->prepare("UPDATE import_biblios SET title = ?, author = ?, isbn = ?, issn = ?
1540 WHERE import_record_id = ?");
1541 $sth->execute($title, $author, $isbn, $issn, $import_record_id);
1545 sub _parse_biblio_fields {
1546 my ($marc_record) = @_;
1548 my $dbh = C4::Context->dbh;
1549 my $bibliofields = TransformMarcToKoha($dbh, $marc_record, '');
1550 return ($bibliofields->{'title'}, $bibliofields->{'author'}, $bibliofields->{'isbn'}, $bibliofields->{'issn'});
1554 sub _update_batch_record_counts {
1555 my ($batch_id) = @_;
1557 my $dbh = C4::Context->dbh;
1558 my $sth = $dbh->prepare_cached("UPDATE import_batches SET
1562 WHERE import_batch_id = import_batches.import_batch_id),
1566 JOIN import_items USING (import_record_id)
1567 WHERE import_batch_id = import_batches.import_batch_id
1568 AND record_type = 'biblio')
1569 WHERE import_batch_id = ?");
1570 $sth->bind_param(1, $batch_id);
1575 sub _get_commit_action {
1576 my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id, $record_type) = @_;
1578 if ($record_type eq 'biblio') {
1579 my ($bib_result, $bib_match, $item_result);
1581 if ($overlay_status ne 'no_match') {
1582 $bib_match = GetBestRecordMatch($import_record_id);
1583 if ($overlay_action eq 'replace') {
1584 $bib_result = defined($bib_match) ? 'replace' : 'create_new';
1585 } elsif ($overlay_action eq 'create_new') {
1586 $bib_result = 'create_new';
1587 } elsif ($overlay_action eq 'ignore') {
1588 $bib_result = 'ignore';
1590 if($item_action eq 'always_add' or $item_action eq 'add_only_for_matches'){
1591 $item_result = 'create_new';
1593 elsif($item_action eq 'replace'){
1594 $item_result = 'replace';
1597 $item_result = 'ignore';
1600 $bib_result = $nomatch_action;
1601 $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ? 'create_new' : 'ignore';
1603 return ($bib_result, $item_result, $bib_match);
1604 } else { # must be auths
1605 my ($auth_result, $auth_match);
1607 if ($overlay_status ne 'no_match') {
1608 $auth_match = GetBestRecordMatch($import_record_id);
1609 if ($overlay_action eq 'replace') {
1610 $auth_result = defined($auth_match) ? 'replace' : 'create_new';
1611 } elsif ($overlay_action eq 'create_new') {
1612 $auth_result = 'create_new';
1613 } elsif ($overlay_action eq 'ignore') {
1614 $auth_result = 'ignore';
1617 $auth_result = $nomatch_action;
1620 return ($auth_result, undef, $auth_match);
1625 sub _get_revert_action {
1626 my ($overlay_action, $overlay_status, $status) = @_;
1630 if ($status eq 'ignored') {
1631 $bib_result = 'ignore';
1633 if ($overlay_action eq 'create_new') {
1634 $bib_result = 'delete';
1636 $bib_result = ($overlay_status eq 'match_applied') ? 'restore' : 'delete';
1647 Koha Development Team <http://koha-community.org/>
1649 Galen Charlton <galen.charlton@liblime.com>