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($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
36 # set the version for version checking
37 $VERSION = 3.07.00.049;
44 GetImportRecordMarcXML
49 AddItemsToImportBiblio
60 GetStagedWebserviceBatches
61 GetImportBatchRangeDesc
62 GetNumberOfNonZ3950ImportBatches
65 GetItemNumbersFromImportBatch
69 GetImportBatchOverlayAction
70 SetImportBatchOverlayAction
71 GetImportBatchNoMatchAction
72 SetImportBatchNoMatchAction
73 GetImportBatchItemAction
74 SetImportBatchItemAction
77 GetImportRecordOverlayStatus
78 SetImportRecordOverlayStatus
81 GetImportRecordMatches
82 SetImportRecordMatches
88 C4::ImportBatch - manage batches of imported MARC records
96 =head2 GetZ3950BatchId
98 my $batchid = GetZ3950BatchId($z3950server);
100 Retrieves the ID of the import batch for the Z39.50
101 reservoir for the given target. If necessary,
102 creates the import batch.
106 sub GetZ3950BatchId {
107 my ($z3950server) = @_;
109 my $dbh = C4::Context->dbh;
110 my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
111 WHERE batch_type = 'z3950'
113 $sth->execute($z3950server);
114 my $rowref = $sth->fetchrow_arrayref();
116 if (defined $rowref) {
119 my $batch_id = AddImportBatch( {
120 overlay_action => 'create_new',
121 import_status => 'staged',
122 batch_type => 'z3950',
123 file_name => $z3950server,
130 =head2 GetWebserviceBatchId
132 my $batchid = GetWebserviceBatchId();
134 Retrieves the ID of the import batch for webservice.
135 If necessary, creates the import batch.
139 my $WEBSERVICE_BASE_QRY = <<EOQ;
140 SELECT import_batch_id FROM import_batches
141 WHERE batch_type = 'webservice'
142 AND import_status = 'staged'
144 sub GetWebserviceBatchId {
147 my $dbh = C4::Context->dbh;
148 my $sql = $WEBSERVICE_BASE_QRY;
150 foreach my $field (qw(matcher_id overlay_action nomatch_action item_action)) {
151 if (my $val = $params->{$field}) {
152 $sql .= " AND $field = ?";
156 my $id = $dbh->selectrow_array($sql, undef, @args);
159 $params->{batch_type} = 'webservice';
160 $params->{import_status} = 'staged';
161 return AddImportBatch($params);
164 =head2 GetImportRecordMarc
166 my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);
170 sub GetImportRecordMarc {
171 my ($import_record_id) = @_;
173 my $dbh = C4::Context->dbh;
174 my ( $marc, $encoding ) = $dbh->selectrow_array(q|
175 SELECT marc, encoding
177 WHERE import_record_id = ?
178 |, undef, $import_record_id );
180 return $marc, $encoding;
183 sub GetRecordFromImportBiblio {
184 my ( $import_record_id, $embed_items ) = @_;
186 my ($marc) = GetImportRecordMarc($import_record_id);
187 my $record = MARC::Record->new_from_usmarc($marc);
189 EmbedItemsInImportBiblio( $record, $import_record_id ) if $embed_items;
194 sub EmbedItemsInImportBiblio {
195 my ( $record, $import_record_id ) = @_;
196 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber", '');
197 my $dbh = C4::Context->dbh;
198 my $import_items = $dbh->selectall_arrayref(q|
199 SELECT import_items.marcxml
201 WHERE import_record_id = ?
202 |, { Slice => {} }, $import_record_id );
204 for my $import_item ( @$import_items ) {
205 my $item_marc = MARC::Record::new_from_xml($import_item->{marcxml});
206 push @item_fields, $item_marc->field($itemtag);
208 $record->append_fields(@item_fields);
212 =head2 GetImportRecordMarcXML
214 my $marcxml = GetImportRecordMarcXML($import_record_id);
218 sub GetImportRecordMarcXML {
219 my ($import_record_id) = @_;
221 my $dbh = C4::Context->dbh;
222 my $sth = $dbh->prepare("SELECT marcxml FROM import_records WHERE import_record_id = ?");
223 $sth->execute($import_record_id);
224 my ($marcxml) = $sth->fetchrow();
230 =head2 AddImportBatch
232 my $batch_id = AddImportBatch($params_hash);
240 foreach (qw( matcher_id template_id branchcode
241 overlay_action nomatch_action item_action
242 import_status batch_type file_name comments record_type )) {
243 if (exists $params->{$_}) {
245 push @vals, $params->{$_};
248 my $dbh = C4::Context->dbh;
249 $dbh->do("INSERT INTO import_batches (".join( ',', @fields).")
250 VALUES (".join( ',', map '?', @fields).")",
253 return $dbh->{'mysql_insertid'};
256 =head2 GetImportBatch
258 my $row = GetImportBatch($batch_id);
260 Retrieve a hashref of an import_batches row.
267 my $dbh = C4::Context->dbh;
268 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
269 $sth->bind_param(1, $batch_id);
271 my $result = $sth->fetchrow_hashref;
277 =head2 AddBiblioToBatch
279 my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence,
280 $marc_record, $encoding, $z3950random, $update_counts);
284 sub AddBiblioToBatch {
285 my $batch_id = shift;
286 my $record_sequence = shift;
287 my $marc_record = shift;
288 my $encoding = shift;
289 my $z3950random = shift;
290 my $update_counts = @_ ? shift : 1;
292 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random, C4::Context->preference('marcflavour'));
293 _add_biblio_fields($import_record_id, $marc_record);
294 _update_batch_record_counts($batch_id) if $update_counts;
295 return $import_record_id;
298 =head2 ModBiblioInBatch
300 ModBiblioInBatch($import_record_id, $marc_record);
304 sub ModBiblioInBatch {
305 my ($import_record_id, $marc_record) = @_;
307 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
308 _update_biblio_fields($import_record_id, $marc_record);
312 =head2 AddAuthToBatch
314 my $import_record_id = AddAuthToBatch($batch_id, $record_sequence,
315 $marc_record, $encoding, $z3950random, $update_counts, [$marc_type]);
320 my $batch_id = shift;
321 my $record_sequence = shift;
322 my $marc_record = shift;
323 my $encoding = shift;
324 my $z3950random = shift;
325 my $update_counts = @_ ? shift : 1;
326 my $marc_type = shift || C4::Context->preference('marcflavour');
328 $marc_type = 'UNIMARCAUTH' if $marc_type eq 'UNIMARC';
330 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'auth', $encoding, $z3950random, $marc_type);
331 _add_auth_fields($import_record_id, $marc_record);
332 _update_batch_record_counts($batch_id) if $update_counts;
333 return $import_record_id;
336 =head2 ModAuthInBatch
338 ModAuthInBatch($import_record_id, $marc_record);
343 my ($import_record_id, $marc_record) = @_;
345 my $marcflavour = C4::Context->preference('marcflavour');
346 _update_import_record_marc($import_record_id, $marc_record, $marcflavour eq 'UNIMARC' ? 'UNIMARCAUTH' : 'USMARC');
350 =head2 BatchStageMarcRecords
352 ( $batch_id, $num_records, $num_items, @invalid_records ) =
353 BatchStageMarcRecords(
354 $encoding, $marc_records,
355 $file_name, $to_marc_plugin,
356 $marc_modification_template, $comments,
357 $branch_code, $parse_items,
358 $leave_as_staging, $progress_interval,
364 sub BatchStageMarcRecords {
365 my $record_type = shift;
366 my $encoding = shift;
367 my $marc_records = shift;
368 my $file_name = shift;
369 my $to_marc_plugin = shift;
370 my $marc_modification_template = shift;
371 my $comments = shift;
372 my $branch_code = shift;
373 my $parse_items = shift;
374 my $leave_as_staging = shift;
376 # optional callback to monitor status
378 my $progress_interval = 0;
379 my $progress_callback = undef;
381 $progress_interval = shift;
382 $progress_callback = shift;
383 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
384 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
387 my $batch_id = AddImportBatch( {
388 overlay_action => 'create_new',
389 import_status => 'staging',
390 batch_type => 'batch',
391 file_name => $file_name,
392 comments => $comments,
393 record_type => $record_type,
396 SetImportBatchItemAction($batch_id, 'always_add');
398 SetImportBatchItemAction($batch_id, 'ignore');
401 $marc_records = Koha::Plugins::Handler->run(
403 class => $to_marc_plugin,
405 params => { data => $marc_records }
407 ) if $to_marc_plugin;
409 my $marc_type = C4::Context->preference('marcflavour');
410 $marc_type .= 'AUTH' if ($marc_type eq 'UNIMARC' && $record_type eq 'auth');
411 my @invalid_records = ();
414 # FIXME - for now, we're dealing only with bibs
416 foreach my $marc_blob (split(/\x1D/, $marc_records)) {
417 $marc_blob =~ s/^\s+//g;
418 $marc_blob =~ s/\s+$//g;
419 next unless $marc_blob;
421 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
422 &$progress_callback($rec_num);
424 my ($marc_record, $charset_guessed, $char_errors) =
425 MarcToUTF8Record($marc_blob, $marc_type, $encoding);
427 $encoding = $charset_guessed unless $encoding;
429 ModifyRecordWithTemplate( $marc_modification_template, $marc_record ) if ( $marc_modification_template );
431 my $import_record_id;
432 if (scalar($marc_record->fields()) == 0) {
433 push @invalid_records, $marc_blob;
436 # Normalize the record so it doesn't have separated diacritics
437 SetUTF8Flag($marc_record);
440 if ($record_type eq 'biblio') {
441 $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
443 my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
444 $num_items += scalar(@import_items_ids);
446 } elsif ($record_type eq 'auth') {
447 $import_record_id = AddAuthToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0, $marc_type);
451 unless ($leave_as_staging) {
452 SetImportBatchStatus($batch_id, 'staged');
454 # FIXME branch_code, number of bibs, number of items
455 _update_batch_record_counts($batch_id);
456 return ($batch_id, $num_valid, $num_items, @invalid_records);
459 =head2 AddItemsToImportBiblio
461 my @import_items_ids = AddItemsToImportBiblio($batch_id,
462 $import_record_id, $marc_record, $update_counts);
466 sub AddItemsToImportBiblio {
467 my $batch_id = shift;
468 my $import_record_id = shift;
469 my $marc_record = shift;
470 my $update_counts = @_ ? shift : 0;
472 my @import_items_ids = ();
474 my $dbh = C4::Context->dbh;
475 my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
476 foreach my $item_field ($marc_record->field($item_tag)) {
477 my $item_marc = MARC::Record->new();
478 $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
479 $item_marc->append_fields($item_field);
480 $marc_record->delete_field($item_field);
481 my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
483 $sth->bind_param(1, $import_record_id);
484 $sth->bind_param(2, 'staged');
485 $sth->bind_param(3, $item_marc->as_xml());
487 push @import_items_ids, $dbh->{'mysql_insertid'};
491 if ($#import_items_ids > -1) {
492 _update_batch_record_counts($batch_id) if $update_counts;
493 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
495 return @import_items_ids;
498 =head2 BatchFindDuplicates
500 my $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
501 $max_matches, $progress_interval, $progress_callback);
503 Goes through the records loaded in the batch and attempts to
504 find duplicates for each one. Sets the matching status
505 of each record to "no_match" or "auto_match" as appropriate.
507 The $max_matches parameter is optional; if it is not supplied,
510 The $progress_interval and $progress_callback parameters are
511 optional; if both are supplied, the sub referred to by
512 $progress_callback will be invoked every $progress_interval
513 records using the number of records processed as the
518 sub BatchFindDuplicates {
519 my $batch_id = shift;
521 my $max_matches = @_ ? shift : 10;
523 # optional callback to monitor status
525 my $progress_interval = 0;
526 my $progress_callback = undef;
528 $progress_interval = shift;
529 $progress_callback = shift;
530 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
531 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
534 my $dbh = C4::Context->dbh;
536 my $sth = $dbh->prepare("SELECT import_record_id, record_type, marc
538 WHERE import_batch_id = ?");
539 $sth->execute($batch_id);
540 my $num_with_matches = 0;
542 while (my $rowref = $sth->fetchrow_hashref) {
544 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
545 &$progress_callback($rec_num);
547 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
549 if (defined $matcher) {
550 @matches = $matcher->get_matches($marc_record, $max_matches);
552 if (scalar(@matches) > 0) {
554 SetImportRecordMatches($rowref->{'import_record_id'}, @matches);
555 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'auto_match');
557 SetImportRecordMatches($rowref->{'import_record_id'}, ());
558 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'no_match');
562 return $num_with_matches;
565 =head2 BatchCommitRecords
567 my ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored) =
568 BatchCommitRecords($batch_id, $framework,
569 $progress_interval, $progress_callback);
573 sub BatchCommitRecords {
574 my $batch_id = shift;
575 my $framework = shift;
577 # optional callback to monitor status
579 my $progress_interval = 0;
580 my $progress_callback = undef;
582 $progress_interval = shift;
583 $progress_callback = shift;
584 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
585 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
591 my $num_items_added = 0;
592 my $num_items_replaced = 0;
593 my $num_items_errored = 0;
595 # commit (i.e., save, all records in the batch)
596 SetImportBatchStatus('importing');
597 my $overlay_action = GetImportBatchOverlayAction($batch_id);
598 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
599 my $item_action = GetImportBatchItemAction($batch_id);
602 my $dbh = C4::Context->dbh;
603 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marc, encoding
605 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
606 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
607 WHERE import_batch_id = ?");
608 $sth->execute($batch_id);
609 my $marcflavour = C4::Context->preference('marcflavour');
611 while (my $rowref = $sth->fetchrow_hashref) {
612 $record_type = $rowref->{'record_type'};
614 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
615 &$progress_callback($rec_num);
617 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
623 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
624 $marc_type = 'UNIMARCAUTH';
625 } elsif ($marcflavour eq 'UNIMARC') {
626 $marc_type = 'UNIMARC';
628 $marc_type = 'USMARC';
630 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
632 if ($record_type eq 'biblio') {
633 # remove any item tags - rely on BatchCommitItems
634 ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
635 foreach my $item_field ($marc_record->field($item_tag)) {
636 $marc_record->delete_field($item_field);
640 my ($record_result, $item_result, $record_match) =
641 _get_commit_action($overlay_action, $nomatch_action, $item_action,
642 $rowref->{'overlay_status'}, $rowref->{'import_record_id'}, $record_type);
646 if ($record_result eq 'create_new') {
648 if ($record_type eq 'biblio') {
649 my $biblioitemnumber;
650 ($recordid, $biblioitemnumber) = AddBiblio($marc_record, $framework);
651 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
652 if ($item_result eq 'create_new' || $item_result eq 'replace') {
653 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
654 $num_items_added += $bib_items_added;
655 $num_items_replaced += $bib_items_replaced;
656 $num_items_errored += $bib_items_errored;
659 $recordid = AddAuthority($marc_record, undef, GuessAuthTypeCode($marc_record));
660 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
662 my $sth = $dbh->prepare_cached($query);
663 $sth->execute($recordid, $rowref->{'import_record_id'});
665 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
666 } elsif ($record_result eq 'replace') {
668 $recordid = $record_match;
670 if ($record_type eq 'biblio') {
671 my $oldbiblio = GetBiblio($recordid);
672 $oldxml = GetXmlBiblio($recordid);
674 # remove item fields so that they don't get
675 # added again if record is reverted
676 # 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.
677 my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'}, $marc_type);
678 foreach my $item_field ($old_marc->field($item_tag)) {
679 $old_marc->delete_field($item_field);
681 $oldxml = $old_marc->as_xml($marc_type);
683 ModBiblio($marc_record, $recordid, $oldbiblio->{'frameworkcode'});
684 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
686 if ($item_result eq 'create_new' || $item_result eq 'replace') {
687 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
688 $num_items_added += $bib_items_added;
689 $num_items_replaced += $bib_items_replaced;
690 $num_items_errored += $bib_items_errored;
693 $oldxml = GetAuthorityXML($recordid);
695 ModAuthority($recordid, $marc_record, GuessAuthTypeCode($marc_record));
696 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
698 my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
699 $sth->execute($oldxml, $rowref->{'import_record_id'});
701 my $sth2 = $dbh->prepare_cached($query);
702 $sth2->execute($recordid, $rowref->{'import_record_id'});
704 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
705 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
706 } elsif ($record_result eq 'ignore') {
707 $recordid = $record_match;
709 $recordid = $record_match;
710 if ($record_type eq 'biblio' and defined $recordid and ( $item_result eq 'create_new' || $item_result eq 'replace' ) ) {
711 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
712 $num_items_added += $bib_items_added;
713 $num_items_replaced += $bib_items_replaced;
714 $num_items_errored += $bib_items_errored;
715 # still need to record the matched biblionumber so that the
716 # items can be reverted
717 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
718 $sth2->execute($recordid, $rowref->{'import_record_id'});
719 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
721 SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
725 SetImportBatchStatus($batch_id, 'imported');
726 return ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored);
729 =head2 BatchCommitItems
731 ($num_items_added, $num_items_errored) =
732 BatchCommitItems($import_record_id, $biblionumber);
736 sub BatchCommitItems {
737 my ( $import_record_id, $biblionumber, $action ) = @_;
739 my $dbh = C4::Context->dbh;
741 my $num_items_added = 0;
742 my $num_items_errored = 0;
743 my $num_items_replaced = 0;
745 my $sth = $dbh->prepare( "
746 SELECT import_items_id, import_items.marcxml, encoding
748 JOIN import_records USING (import_record_id)
749 WHERE import_record_id = ?
750 ORDER BY import_items_id
752 $sth->bind_param( 1, $import_record_id );
755 while ( my $row = $sth->fetchrow_hashref() ) {
756 my $item_marc = MARC::Record->new_from_xml( StripNonXmlChars( $row->{'marcxml'} ), 'UTF-8', $row->{'encoding'} );
758 # Delete date_due subfield as to not accidentally delete item checkout due dates
759 my ( $MARCfield, $MARCsubfield ) = GetMarcFromKohaField( 'items.onloan', GetFrameworkCode($biblionumber) );
760 $item_marc->field($MARCfield)->delete_subfield( code => $MARCsubfield );
762 my $item = TransformMarcToKoha( $dbh, $item_marc );
764 my $duplicate_barcode = exists( $item->{'barcode'} ) && GetItemnumberFromBarcode( $item->{'barcode'} );
765 my $duplicate_itemnumber = exists( $item->{'itemnumber'} );
767 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
768 if ( $action eq "replace" && $duplicate_itemnumber ) {
769 # Duplicate itemnumbers have precedence, that way we can update barcodes by overlaying
770 ModItemFromMarc( $item_marc, $biblionumber, $item->{itemnumber} );
771 $updsth->bind_param( 1, 'imported' );
772 $updsth->bind_param( 2, $item->{itemnumber} );
773 $updsth->bind_param( 3, $row->{'import_items_id'} );
776 $num_items_replaced++;
777 } elsif ( $action eq "replace" && $duplicate_barcode ) {
778 my $itemnumber = GetItemnumberFromBarcode( $item->{'barcode'} );
779 ModItemFromMarc( $item_marc, $biblionumber, $itemnumber );
780 $updsth->bind_param( 1, 'imported' );
781 $updsth->bind_param( 2, $item->{itemnumber} );
782 $updsth->bind_param( 3, $row->{'import_items_id'} );
785 $num_items_replaced++;
786 } elsif ($duplicate_barcode) {
787 $updsth->bind_param( 1, 'error' );
788 $updsth->bind_param( 2, 'duplicate item barcode' );
789 $updsth->bind_param( 3, $row->{'import_items_id'} );
791 $num_items_errored++;
793 my ( $item_biblionumber, $biblioitemnumber, $itemnumber ) = AddItemFromMarc( $item_marc, $biblionumber );
794 $updsth->bind_param( 1, 'imported' );
795 $updsth->bind_param( 2, $itemnumber );
796 $updsth->bind_param( 3, $row->{'import_items_id'} );
803 return ( $num_items_added, $num_items_replaced, $num_items_errored );
806 =head2 BatchRevertRecords
808 my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted,
809 $num_ignored) = BatchRevertRecords($batch_id);
813 sub BatchRevertRecords {
814 my $batch_id = shift;
816 my $logger = Koha::Logger->get( { category => 'C4.ImportBatch.BatchRevertRecords' } );
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("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>