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
;
31 use Koha
::Plugins
::Handler
;
34 use vars
qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
43 GetImportRecordMarcXML
48 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
86 our $logger = Koha
::Logger
->get( { category
=> 'C4.ImportBatch' } );
90 C4::ImportBatch - manage batches of imported MARC records
98 =head2 GetZ3950BatchId
100 my $batchid = GetZ3950BatchId($z3950server);
102 Retrieves the ID of the import batch for the Z39.50
103 reservoir for the given target. If necessary,
104 creates the import batch.
108 sub GetZ3950BatchId
{
109 my ($z3950server) = @_;
111 my $dbh = C4
::Context
->dbh;
112 my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
113 WHERE batch_type = 'z3950'
115 $sth->execute($z3950server);
116 my $rowref = $sth->fetchrow_arrayref();
118 if (defined $rowref) {
121 my $batch_id = AddImportBatch
( {
122 overlay_action
=> 'create_new',
123 import_status
=> 'staged',
124 batch_type
=> 'z3950',
125 file_name
=> $z3950server,
132 =head2 GetWebserviceBatchId
134 my $batchid = GetWebserviceBatchId();
136 Retrieves the ID of the import batch for webservice.
137 If necessary, creates the import batch.
141 my $WEBSERVICE_BASE_QRY = <<EOQ;
142 SELECT import_batch_id FROM import_batches
143 WHERE batch_type = 'webservice'
144 AND import_status = 'staged'
146 sub GetWebserviceBatchId
{
149 my $dbh = C4
::Context
->dbh;
150 my $sql = $WEBSERVICE_BASE_QRY;
152 foreach my $field (qw(matcher_id overlay_action nomatch_action item_action)) {
153 if (my $val = $params->{$field}) {
154 $sql .= " AND $field = ?";
158 my $id = $dbh->selectrow_array($sql, undef, @args);
161 $params->{batch_type
} = 'webservice';
162 $params->{import_status
} = 'staged';
163 return AddImportBatch
($params);
166 =head2 GetImportRecordMarc
168 my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);
172 sub GetImportRecordMarc
{
173 my ($import_record_id) = @_;
175 my $dbh = C4
::Context
->dbh;
176 my ( $marc, $encoding ) = $dbh->selectrow_array(q
|
177 SELECT marc
, encoding
179 WHERE import_record_id
= ?
180 |, undef, $import_record_id );
182 return $marc, $encoding;
185 sub GetRecordFromImportBiblio
{
186 my ( $import_record_id, $embed_items ) = @_;
188 my ($marc) = GetImportRecordMarc
($import_record_id);
189 my $record = MARC
::Record
->new_from_usmarc($marc);
191 EmbedItemsInImportBiblio
( $record, $import_record_id ) if $embed_items;
196 sub EmbedItemsInImportBiblio
{
197 my ( $record, $import_record_id ) = @_;
198 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField
("items.itemnumber", '');
199 my $dbh = C4
::Context
->dbh;
200 my $import_items = $dbh->selectall_arrayref(q
|
201 SELECT import_items
.marcxml
203 WHERE import_record_id
= ?
204 |, { Slice
=> {} }, $import_record_id );
206 for my $import_item ( @
$import_items ) {
207 my $item_marc = MARC
::Record
::new_from_xml
($import_item->{marcxml
});
208 push @item_fields, $item_marc->field($itemtag);
210 $record->append_fields(@item_fields);
214 =head2 GetImportRecordMarcXML
216 my $marcxml = GetImportRecordMarcXML($import_record_id);
220 sub GetImportRecordMarcXML
{
221 my ($import_record_id) = @_;
223 my $dbh = C4
::Context
->dbh;
224 my $sth = $dbh->prepare("SELECT marcxml FROM import_records WHERE import_record_id = ?");
225 $sth->execute($import_record_id);
226 my ($marcxml) = $sth->fetchrow();
232 =head2 AddImportBatch
234 my $batch_id = AddImportBatch($params_hash);
242 foreach (qw( matcher_id template_id branchcode
243 overlay_action nomatch_action item_action
244 import_status batch_type file_name comments record_type )) {
245 if (exists $params->{$_}) {
247 push @vals, $params->{$_};
250 my $dbh = C4
::Context
->dbh;
251 $dbh->do("INSERT INTO import_batches (".join( ',', @fields).")
252 VALUES (".join( ',', map '?', @fields).")",
255 return $dbh->{'mysql_insertid'};
258 =head2 GetImportBatch
260 my $row = GetImportBatch($batch_id);
262 Retrieve a hashref of an import_batches row.
269 my $dbh = C4
::Context
->dbh;
270 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
271 $sth->bind_param(1, $batch_id);
273 my $result = $sth->fetchrow_hashref;
279 =head2 AddBiblioToBatch
281 my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence,
282 $marc_record, $encoding, $z3950random, $update_counts);
286 sub AddBiblioToBatch
{
287 my $batch_id = shift;
288 my $record_sequence = shift;
289 my $marc_record = shift;
290 my $encoding = shift;
291 my $z3950random = shift;
292 my $update_counts = @_ ?
shift : 1;
294 my $import_record_id = _create_import_record
($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random, C4
::Context
->preference('marcflavour'));
295 _add_biblio_fields
($import_record_id, $marc_record);
296 _update_batch_record_counts
($batch_id) if $update_counts;
297 return $import_record_id;
300 =head2 ModBiblioInBatch
302 ModBiblioInBatch($import_record_id, $marc_record);
306 sub ModBiblioInBatch
{
307 my ($import_record_id, $marc_record) = @_;
309 _update_import_record_marc
($import_record_id, $marc_record, C4
::Context
->preference('marcflavour'));
310 _update_biblio_fields
($import_record_id, $marc_record);
314 =head2 AddAuthToBatch
316 my $import_record_id = AddAuthToBatch($batch_id, $record_sequence,
317 $marc_record, $encoding, $z3950random, $update_counts, [$marc_type]);
322 my $batch_id = shift;
323 my $record_sequence = shift;
324 my $marc_record = shift;
325 my $encoding = shift;
326 my $z3950random = shift;
327 my $update_counts = @_ ?
shift : 1;
328 my $marc_type = shift || C4
::Context
->preference('marcflavour');
330 $marc_type = 'UNIMARCAUTH' if $marc_type eq 'UNIMARC';
332 my $import_record_id = _create_import_record
($batch_id, $record_sequence, $marc_record, 'auth', $encoding, $z3950random, $marc_type);
333 _add_auth_fields
($import_record_id, $marc_record);
334 _update_batch_record_counts
($batch_id) if $update_counts;
335 return $import_record_id;
338 =head2 ModAuthInBatch
340 ModAuthInBatch($import_record_id, $marc_record);
345 my ($import_record_id, $marc_record) = @_;
347 my $marcflavour = C4
::Context
->preference('marcflavour');
348 _update_import_record_marc
($import_record_id, $marc_record, $marcflavour eq 'UNIMARC' ?
'UNIMARCAUTH' : 'USMARC');
352 =head2 BatchStageMarcRecords
354 ( $batch_id, $num_records, $num_items, @invalid_records ) =
355 BatchStageMarcRecords(
356 $record_type, $encoding,
357 $marc_records, $file_name,
358 $marc_modification_template, $comments,
359 $branch_code, $parse_items,
360 $leave_as_staging, $progress_interval,
366 sub BatchStageMarcRecords
{
367 my $record_type = shift;
368 my $encoding = shift;
369 my $marc_records = shift;
370 my $file_name = 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');
403 my $marc_type = C4
::Context
->preference('marcflavour');
404 $marc_type .= 'AUTH' if ($marc_type eq 'UNIMARC' && $record_type eq 'auth');
405 my @invalid_records = ();
408 # FIXME - for now, we're dealing only with bibs
410 foreach my $marc_record (@
$marc_records) {
412 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
413 &$progress_callback($rec_num);
416 ModifyRecordWithTemplate
( $marc_modification_template, $marc_record ) if ( $marc_modification_template );
418 my $import_record_id;
419 if (scalar($marc_record->fields()) == 0) {
420 push @invalid_records, $marc_record;
423 # Normalize the record so it doesn't have separated diacritics
424 SetUTF8Flag
($marc_record);
427 if ($record_type eq 'biblio') {
428 $import_record_id = AddBiblioToBatch
($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
430 my @import_items_ids = AddItemsToImportBiblio
($batch_id, $import_record_id, $marc_record, 0);
431 $num_items += scalar(@import_items_ids);
433 } elsif ($record_type eq 'auth') {
434 $import_record_id = AddAuthToBatch
($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0, $marc_type);
438 unless ($leave_as_staging) {
439 SetImportBatchStatus
($batch_id, 'staged');
441 # FIXME branch_code, number of bibs, number of items
442 _update_batch_record_counts
($batch_id);
443 return ($batch_id, $num_valid, $num_items, @invalid_records);
446 =head2 AddItemsToImportBiblio
448 my @import_items_ids = AddItemsToImportBiblio($batch_id,
449 $import_record_id, $marc_record, $update_counts);
453 sub AddItemsToImportBiblio
{
454 my $batch_id = shift;
455 my $import_record_id = shift;
456 my $marc_record = shift;
457 my $update_counts = @_ ?
shift : 0;
459 my @import_items_ids = ();
461 my $dbh = C4
::Context
->dbh;
462 my ($item_tag,$item_subfield) = &GetMarcFromKohaField
("items.itemnumber",'');
463 foreach my $item_field ($marc_record->field($item_tag)) {
464 my $item_marc = MARC
::Record
->new();
465 $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
466 $item_marc->append_fields($item_field);
467 $marc_record->delete_field($item_field);
468 my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
470 $sth->bind_param(1, $import_record_id);
471 $sth->bind_param(2, 'staged');
472 $sth->bind_param(3, $item_marc->as_xml());
474 push @import_items_ids, $dbh->{'mysql_insertid'};
478 if ($#import_items_ids > -1) {
479 _update_batch_record_counts
($batch_id) if $update_counts;
480 _update_import_record_marc
($import_record_id, $marc_record, C4
::Context
->preference('marcflavour'));
482 return @import_items_ids;
485 =head2 BatchFindDuplicates
487 my $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
488 $max_matches, $progress_interval, $progress_callback);
490 Goes through the records loaded in the batch and attempts to
491 find duplicates for each one. Sets the matching status
492 of each record to "no_match" or "auto_match" as appropriate.
494 The $max_matches parameter is optional; if it is not supplied,
497 The $progress_interval and $progress_callback parameters are
498 optional; if both are supplied, the sub referred to by
499 $progress_callback will be invoked every $progress_interval
500 records using the number of records processed as the
505 sub BatchFindDuplicates
{
506 my $batch_id = shift;
508 my $max_matches = @_ ?
shift : 10;
510 # optional callback to monitor status
512 my $progress_interval = 0;
513 my $progress_callback = undef;
515 $progress_interval = shift;
516 $progress_callback = shift;
517 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
518 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
521 my $dbh = C4
::Context
->dbh;
523 my $sth = $dbh->prepare("SELECT import_record_id, record_type, marc
525 WHERE import_batch_id = ?");
526 $sth->execute($batch_id);
527 my $num_with_matches = 0;
529 while (my $rowref = $sth->fetchrow_hashref) {
531 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
532 &$progress_callback($rec_num);
534 my $marc_record = MARC
::Record
->new_from_usmarc($rowref->{'marc'});
536 if (defined $matcher) {
537 @matches = $matcher->get_matches($marc_record, $max_matches);
539 if (scalar(@matches) > 0) {
541 SetImportRecordMatches
($rowref->{'import_record_id'}, @matches);
542 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'auto_match');
544 SetImportRecordMatches
($rowref->{'import_record_id'}, ());
545 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'no_match');
549 return $num_with_matches;
552 =head2 BatchCommitRecords
554 my ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored) =
555 BatchCommitRecords($batch_id, $framework,
556 $progress_interval, $progress_callback);
560 sub BatchCommitRecords
{
561 my $batch_id = shift;
562 my $framework = shift;
564 # optional callback to monitor status
566 my $progress_interval = 0;
567 my $progress_callback = undef;
569 $progress_interval = shift;
570 $progress_callback = shift;
571 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
572 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
578 my $num_items_added = 0;
579 my $num_items_replaced = 0;
580 my $num_items_errored = 0;
582 # commit (i.e., save, all records in the batch)
583 SetImportBatchStatus
('importing');
584 my $overlay_action = GetImportBatchOverlayAction
($batch_id);
585 my $nomatch_action = GetImportBatchNoMatchAction
($batch_id);
586 my $item_action = GetImportBatchItemAction
($batch_id);
589 my $dbh = C4
::Context
->dbh;
590 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marc, encoding
592 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
593 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
594 WHERE import_batch_id = ?");
595 $sth->execute($batch_id);
596 my $marcflavour = C4
::Context
->preference('marcflavour');
598 while (my $rowref = $sth->fetchrow_hashref) {
599 $record_type = $rowref->{'record_type'};
601 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
602 &$progress_callback($rec_num);
604 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
610 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
611 $marc_type = 'UNIMARCAUTH';
612 } elsif ($marcflavour eq 'UNIMARC') {
613 $marc_type = 'UNIMARC';
615 $marc_type = 'USMARC';
617 my $marc_record = MARC
::Record
->new_from_usmarc($rowref->{'marc'});
619 if ($record_type eq 'biblio') {
620 # remove any item tags - rely on BatchCommitItems
621 ($item_tag,$item_subfield) = &GetMarcFromKohaField
("items.itemnumber",'');
622 foreach my $item_field ($marc_record->field($item_tag)) {
623 $marc_record->delete_field($item_field);
627 my ($record_result, $item_result, $record_match) =
628 _get_commit_action
($overlay_action, $nomatch_action, $item_action,
629 $rowref->{'overlay_status'}, $rowref->{'import_record_id'}, $record_type);
633 if ($record_result eq 'create_new') {
635 if ($record_type eq 'biblio') {
636 my $biblioitemnumber;
637 ($recordid, $biblioitemnumber) = AddBiblio
($marc_record, $framework);
638 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
639 if ($item_result eq 'create_new' || $item_result eq 'replace') {
640 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems
($rowref->{'import_record_id'}, $recordid, $item_result);
641 $num_items_added += $bib_items_added;
642 $num_items_replaced += $bib_items_replaced;
643 $num_items_errored += $bib_items_errored;
646 $recordid = AddAuthority
($marc_record, undef, GuessAuthTypeCode
($marc_record));
647 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
649 my $sth = $dbh->prepare_cached($query);
650 $sth->execute($recordid, $rowref->{'import_record_id'});
652 SetImportRecordStatus
($rowref->{'import_record_id'}, 'imported');
653 } elsif ($record_result eq 'replace') {
655 $recordid = $record_match;
657 if ($record_type eq 'biblio') {
658 my $oldbiblio = Koha
::Biblios
->find( $recordid );
659 $oldxml = GetXmlBiblio
($recordid);
661 # remove item fields so that they don't get
662 # added again if record is reverted
663 # 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.
664 my $old_marc = MARC
::Record
->new_from_xml(StripNonXmlChars
($oldxml), 'UTF-8', $rowref->{'encoding'}, $marc_type);
665 foreach my $item_field ($old_marc->field($item_tag)) {
666 $old_marc->delete_field($item_field);
668 $oldxml = $old_marc->as_xml($marc_type);
670 ModBiblio
($marc_record, $recordid, $oldbiblio->frameworkcode);
671 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
673 if ($item_result eq 'create_new' || $item_result eq 'replace') {
674 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems
($rowref->{'import_record_id'}, $recordid, $item_result);
675 $num_items_added += $bib_items_added;
676 $num_items_replaced += $bib_items_replaced;
677 $num_items_errored += $bib_items_errored;
680 $oldxml = GetAuthorityXML
($recordid);
682 ModAuthority
($recordid, $marc_record, GuessAuthTypeCode
($marc_record));
683 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
685 my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
686 $sth->execute($oldxml, $rowref->{'import_record_id'});
688 my $sth2 = $dbh->prepare_cached($query);
689 $sth2->execute($recordid, $rowref->{'import_record_id'});
691 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'match_applied');
692 SetImportRecordStatus
($rowref->{'import_record_id'}, 'imported');
693 } elsif ($record_result eq 'ignore') {
694 $recordid = $record_match;
696 $recordid = $record_match;
697 if ($record_type eq 'biblio' and defined $recordid and ( $item_result eq 'create_new' || $item_result eq 'replace' ) ) {
698 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems
($rowref->{'import_record_id'}, $recordid, $item_result);
699 $num_items_added += $bib_items_added;
700 $num_items_replaced += $bib_items_replaced;
701 $num_items_errored += $bib_items_errored;
702 # still need to record the matched biblionumber so that the
703 # items can be reverted
704 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
705 $sth2->execute($recordid, $rowref->{'import_record_id'});
706 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'match_applied');
708 SetImportRecordStatus
($rowref->{'import_record_id'}, 'ignored');
712 SetImportBatchStatus
($batch_id, 'imported');
713 return ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored);
716 =head2 BatchCommitItems
718 ($num_items_added, $num_items_errored) =
719 BatchCommitItems($import_record_id, $biblionumber);
723 sub BatchCommitItems
{
724 my ( $import_record_id, $biblionumber, $action ) = @_;
726 my $dbh = C4
::Context
->dbh;
728 my $num_items_added = 0;
729 my $num_items_errored = 0;
730 my $num_items_replaced = 0;
732 my $sth = $dbh->prepare( "
733 SELECT import_items_id, import_items.marcxml, encoding
735 JOIN import_records USING (import_record_id)
736 WHERE import_record_id = ?
737 ORDER BY import_items_id
739 $sth->bind_param( 1, $import_record_id );
742 while ( my $row = $sth->fetchrow_hashref() ) {
743 my $item_marc = MARC
::Record
->new_from_xml( StripNonXmlChars
( $row->{'marcxml'} ), 'UTF-8', $row->{'encoding'} );
745 # Delete date_due subfield as to not accidentally delete item checkout due dates
746 my ( $MARCfield, $MARCsubfield ) = GetMarcFromKohaField
( 'items.onloan', GetFrameworkCode
($biblionumber) );
747 $item_marc->field($MARCfield)->delete_subfield( code
=> $MARCsubfield );
749 my $item = TransformMarcToKoha
( $item_marc );
751 my $duplicate_barcode = exists( $item->{'barcode'} ) && Koha
::Items
->find({ barcode
=> $item->{'barcode'} });
752 my $duplicate_itemnumber = exists( $item->{'itemnumber'} );
754 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
755 if ( $action eq "replace" && $duplicate_itemnumber ) {
756 # Duplicate itemnumbers have precedence, that way we can update barcodes by overlaying
757 ModItemFromMarc
( $item_marc, $biblionumber, $item->{itemnumber
} );
758 $updsth->bind_param( 1, 'imported' );
759 $updsth->bind_param( 2, $item->{itemnumber
} );
760 $updsth->bind_param( 3, $row->{'import_items_id'} );
763 $num_items_replaced++;
764 } elsif ( $action eq "replace" && $duplicate_barcode ) {
765 my $itemnumber = $duplicate_barcode->itemnumber;
766 ModItemFromMarc
( $item_marc, $biblionumber, $itemnumber );
767 $updsth->bind_param( 1, 'imported' );
768 $updsth->bind_param( 2, $item->{itemnumber
} );
769 $updsth->bind_param( 3, $row->{'import_items_id'} );
772 $num_items_replaced++;
773 } elsif ($duplicate_barcode) {
774 $updsth->bind_param( 1, 'error' );
775 $updsth->bind_param( 2, 'duplicate item barcode' );
776 $updsth->bind_param( 3, $row->{'import_items_id'} );
778 $num_items_errored++;
780 my ( $item_biblionumber, $biblioitemnumber, $itemnumber ) = AddItemFromMarc
( $item_marc, $biblionumber );
782 $updsth->bind_param( 1, 'imported' );
783 $updsth->bind_param( 2, $itemnumber );
784 $updsth->bind_param( 3, $row->{'import_items_id'} );
792 return ( $num_items_added, $num_items_replaced, $num_items_errored );
795 =head2 BatchRevertRecords
797 my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted,
798 $num_ignored) = BatchRevertRecords($batch_id);
802 sub BatchRevertRecords
{
803 my $batch_id = shift;
805 $logger->trace("C4::ImportBatch::BatchRevertRecords( $batch_id )");
810 my $num_reverted = 0;
812 my $num_items_deleted = 0;
813 # commit (i.e., save, all records in the batch)
814 SetImportBatchStatus
('reverting');
815 my $overlay_action = GetImportBatchOverlayAction
($batch_id);
816 my $nomatch_action = GetImportBatchNoMatchAction
($batch_id);
817 my $dbh = C4
::Context
->dbh;
818 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marcxml_old, encoding, matched_biblionumber, matched_authid
820 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
821 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
822 WHERE import_batch_id = ?");
823 $sth->execute($batch_id);
825 my $marcflavour = C4
::Context
->preference('marcflavour');
826 while (my $rowref = $sth->fetchrow_hashref) {
827 $record_type = $rowref->{'record_type'};
828 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
832 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
833 $marc_type = 'UNIMARCAUTH';
834 } elsif ($marcflavour eq 'UNIMARC') {
835 $marc_type = 'UNIMARC';
837 $marc_type = 'USMARC';
840 my $record_result = _get_revert_action
($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
842 if ($record_result eq 'delete') {
844 if ($record_type eq 'biblio') {
845 $num_items_deleted += BatchRevertItems
($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
846 $error = DelBiblio
($rowref->{'matched_biblionumber'});
848 DelAuthority
({ authid
=> $rowref->{'matched_authid'} });
850 if (defined $error) {
854 SetImportRecordStatus
($rowref->{'import_record_id'}, 'reverted');
856 } elsif ($record_result eq 'restore') {
858 my $old_record = MARC
::Record
->new_from_xml(StripNonXmlChars
($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'}, $marc_type);
859 if ($record_type eq 'biblio') {
860 my $biblionumber = $rowref->{'matched_biblionumber'};
861 my $oldbiblio = Koha
::Biblios
->find( $biblionumber );
863 $logger->info("C4::ImportBatch::BatchRevertRecords: Biblio record $biblionumber does not exist, restoration of this record was skipped") unless $oldbiblio;
864 next unless $oldbiblio; # Record has since been deleted. Deleted records should stay deleted.
866 $num_items_deleted += BatchRevertItems
($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
867 ModBiblio
($old_record, $biblionumber, $oldbiblio->frameworkcode);
869 my $authid = $rowref->{'matched_authid'};
870 ModAuthority
($authid, $old_record, GuessAuthTypeCode
($old_record));
872 SetImportRecordStatus
($rowref->{'import_record_id'}, 'reverted');
873 } elsif ($record_result eq 'ignore') {
874 if ($record_type eq 'biblio') {
875 $num_items_deleted += BatchRevertItems
($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
877 SetImportRecordStatus
($rowref->{'import_record_id'}, 'reverted');
880 if ($record_type eq 'biblio') {
881 # remove matched_biblionumber only if there is no 'imported' item left
882 $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?";
883 $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')";
885 $query = "UPDATE import_auths SET matched_authid = NULL WHERE import_record_id = ?";
887 my $sth2 = $dbh->prepare_cached($query);
888 $sth2->execute($rowref->{'import_record_id'});
892 SetImportBatchStatus
($batch_id, 'reverted');
893 return ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored);
896 =head2 BatchRevertItems
898 my $num_items_deleted = BatchRevertItems($import_record_id, $biblionumber);
902 sub BatchRevertItems
{
903 my ($import_record_id, $biblionumber) = @_;
905 my $dbh = C4
::Context
->dbh;
906 my $num_items_deleted = 0;
908 my $sth = $dbh->prepare_cached("SELECT import_items_id, itemnumber
910 JOIN items USING (itemnumber)
911 WHERE import_record_id = ?");
912 $sth->bind_param(1, $import_record_id);
914 while (my $row = $sth->fetchrow_hashref()) {
915 my $error = DelItemCheck
( $biblionumber, $row->{'itemnumber'});
917 my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
918 $updsth->bind_param(1, 'reverted');
919 $updsth->bind_param(2, $row->{'import_items_id'});
922 $num_items_deleted++;
929 return $num_items_deleted;
934 CleanBatch($batch_id)
936 Deletes all staged records from the import batch
937 and sets the status of the batch to 'cleaned'. Note
938 that deleting a stage record does *not* affect
939 any record that has been committed to the database.
944 my $batch_id = shift;
945 return unless defined $batch_id;
947 C4
::Context
->dbh->do('DELETE FROM import_records WHERE import_batch_id = ?', {}, $batch_id);
948 SetImportBatchStatus
($batch_id, 'cleaned');
953 DeleteBatch($batch_id)
955 Deletes the record from the database. This can only be done
956 once the batch has been cleaned.
961 my $batch_id = shift;
962 return unless defined $batch_id;
964 my $dbh = C4
::Context
->dbh;
965 my $sth = $dbh->prepare('DELETE FROM import_batches WHERE import_batch_id = ?');
966 $sth->execute( $batch_id );
969 =head2 GetAllImportBatches
971 my $results = GetAllImportBatches();
973 Returns a references to an array of hash references corresponding
974 to all import_batches rows (of batch_type 'batch'), sorted in
975 ascending order by import_batch_id.
979 sub GetAllImportBatches
{
980 my $dbh = C4
::Context
->dbh;
981 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
982 WHERE batch_type IN ('batch', 'webservice')
983 ORDER BY import_batch_id ASC");
987 while (my $row = $sth->fetchrow_hashref) {
988 push @
$results, $row;
994 =head2 GetStagedWebserviceBatches
996 my $batch_ids = GetStagedWebserviceBatches();
998 Returns a references to an array of batch id's
999 of batch_type 'webservice' that are not imported
1003 my $PENDING_WEBSERVICE_BATCHES_QRY = <<EOQ;
1004 SELECT import_batch_id FROM import_batches
1005 WHERE batch_type = 'webservice'
1006 AND import_status = 'staged'
1008 sub GetStagedWebserviceBatches
{
1009 my $dbh = C4
::Context
->dbh;
1010 return $dbh->selectcol_arrayref($PENDING_WEBSERVICE_BATCHES_QRY);
1013 =head2 GetImportBatchRangeDesc
1015 my $results = GetImportBatchRangeDesc($offset, $results_per_group);
1017 Returns a reference to an array of hash references corresponding to
1018 import_batches rows (sorted in descending order by import_batch_id)
1019 start at the given offset.
1023 sub GetImportBatchRangeDesc
{
1024 my ($offset, $results_per_group) = @_;
1026 my $dbh = C4
::Context
->dbh;
1027 my $query = "SELECT * FROM import_batches
1028 WHERE batch_type IN ('batch', 'webservice')
1029 ORDER BY import_batch_id DESC";
1031 if ($results_per_group){
1032 $query .= " LIMIT ?";
1033 push(@params, $results_per_group);
1036 $query .= " OFFSET ?";
1037 push(@params, $offset);
1039 my $sth = $dbh->prepare_cached($query);
1040 $sth->execute(@params);
1041 my $results = $sth->fetchall_arrayref({});
1046 =head2 GetItemNumbersFromImportBatch
1048 my @itemsnos = GetItemNumbersFromImportBatch($batch_id);
1052 sub GetItemNumbersFromImportBatch
{
1053 my ($batch_id) = @_;
1054 my $dbh = C4
::Context
->dbh;
1056 SELECT itemnumber FROM import_items
1057 INNER JOIN items USING
(itemnumber
)
1058 INNER JOIN import_records USING
(import_record_id
)
1059 WHERE import_batch_id
= ?
|;
1060 my $sth = $dbh->prepare( $sql );
1061 $sth->execute($batch_id);
1063 while ( my ($itm) = $sth->fetchrow_array ) {
1069 =head2 GetNumberOfImportBatches
1071 my $count = GetNumberOfImportBatches();
1075 sub GetNumberOfNonZ3950ImportBatches
{
1076 my $dbh = C4
::Context
->dbh;
1077 my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type != 'z3950'");
1079 my ($count) = $sth->fetchrow_array();
1084 =head2 GetImportBiblios
1086 my $results = GetImportBiblios($importid);
1090 sub GetImportBiblios
{
1091 my ($import_record_id) = @_;
1093 my $dbh = C4
::Context
->dbh;
1094 my $query = "SELECT * FROM import_biblios WHERE import_record_id = ?";
1095 return $dbh->selectall_arrayref(
1103 =head2 GetImportRecordsRange
1105 my $results = GetImportRecordsRange($batch_id, $offset, $results_per_group);
1107 Returns a reference to an array of hash references corresponding to
1108 import_biblios/import_auths/import_records rows for a given batch
1109 starting at the given offset.
1113 sub GetImportRecordsRange
{
1114 my ( $batch_id, $offset, $results_per_group, $status, $parameters ) = @_;
1116 my $dbh = C4
::Context
->dbh;
1118 my $order_by = $parameters->{order_by
} || 'import_record_id';
1119 ( $order_by ) = grep( /^$order_by$/, qw( import_record_id title status overlay_status ) ) ?
$order_by : 'import_record_id';
1121 my $order_by_direction =
1122 uc( $parameters->{order_by_direction
} // 'ASC' ) eq 'DESC' ?
'DESC' : 'ASC';
1124 $order_by .= " $order_by_direction, authorized_heading" if $order_by eq 'title';
1126 my $query = "SELECT title, author, isbn, issn, authorized_heading, import_records.import_record_id,
1127 record_sequence, status, overlay_status,
1128 matched_biblionumber, matched_authid, record_type
1130 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
1131 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
1132 WHERE import_batch_id = ?";
1134 push(@params, $batch_id);
1136 $query .= " AND status=?";
1137 push(@params,$status);
1140 $query.=" ORDER BY $order_by $order_by_direction";
1142 if($results_per_group){
1143 $query .= " LIMIT ?";
1144 push(@params, $results_per_group);
1147 $query .= " OFFSET ?";
1148 push(@params, $offset);
1150 my $sth = $dbh->prepare_cached($query);
1151 $sth->execute(@params);
1152 my $results = $sth->fetchall_arrayref({});
1158 =head2 GetBestRecordMatch
1160 my $record_id = GetBestRecordMatch($import_record_id);
1164 sub GetBestRecordMatch
{
1165 my ($import_record_id) = @_;
1167 my $dbh = C4
::Context
->dbh;
1168 my $sth = $dbh->prepare("SELECT candidate_match_id
1169 FROM import_record_matches
1170 JOIN import_records ON ( import_record_matches.import_record_id = import_records.import_record_id )
1171 LEFT JOIN biblio ON ( candidate_match_id = biblio.biblionumber )
1172 LEFT JOIN auth_header ON ( candidate_match_id = auth_header.authid )
1173 WHERE import_record_matches.import_record_id = ? AND
1174 ( (import_records.record_type = 'biblio' AND biblio.biblionumber IS NOT NULL) OR
1175 (import_records.record_type = 'auth' AND auth_header.authid IS NOT NULL) )
1176 ORDER BY score DESC, candidate_match_id DESC");
1177 $sth->execute($import_record_id);
1178 my ($record_id) = $sth->fetchrow_array();
1183 =head2 GetImportBatchStatus
1185 my $status = GetImportBatchStatus($batch_id);
1189 sub GetImportBatchStatus
{
1190 my ($batch_id) = @_;
1192 my $dbh = C4
::Context
->dbh;
1193 my $sth = $dbh->prepare("SELECT import_status FROM import_batches WHERE import_batch_id = ?");
1194 $sth->execute($batch_id);
1195 my ($status) = $sth->fetchrow_array();
1201 =head2 SetImportBatchStatus
1203 SetImportBatchStatus($batch_id, $new_status);
1207 sub SetImportBatchStatus
{
1208 my ($batch_id, $new_status) = @_;
1210 my $dbh = C4
::Context
->dbh;
1211 my $sth = $dbh->prepare("UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?");
1212 $sth->execute($new_status, $batch_id);
1217 =head2 GetImportBatchOverlayAction
1219 my $overlay_action = GetImportBatchOverlayAction($batch_id);
1223 sub GetImportBatchOverlayAction
{
1224 my ($batch_id) = @_;
1226 my $dbh = C4
::Context
->dbh;
1227 my $sth = $dbh->prepare("SELECT overlay_action FROM import_batches WHERE import_batch_id = ?");
1228 $sth->execute($batch_id);
1229 my ($overlay_action) = $sth->fetchrow_array();
1231 return $overlay_action;
1236 =head2 SetImportBatchOverlayAction
1238 SetImportBatchOverlayAction($batch_id, $new_overlay_action);
1242 sub SetImportBatchOverlayAction
{
1243 my ($batch_id, $new_overlay_action) = @_;
1245 my $dbh = C4
::Context
->dbh;
1246 my $sth = $dbh->prepare("UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?");
1247 $sth->execute($new_overlay_action, $batch_id);
1252 =head2 GetImportBatchNoMatchAction
1254 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
1258 sub GetImportBatchNoMatchAction
{
1259 my ($batch_id) = @_;
1261 my $dbh = C4
::Context
->dbh;
1262 my $sth = $dbh->prepare("SELECT nomatch_action FROM import_batches WHERE import_batch_id = ?");
1263 $sth->execute($batch_id);
1264 my ($nomatch_action) = $sth->fetchrow_array();
1266 return $nomatch_action;
1271 =head2 SetImportBatchNoMatchAction
1273 SetImportBatchNoMatchAction($batch_id, $new_nomatch_action);
1277 sub SetImportBatchNoMatchAction
{
1278 my ($batch_id, $new_nomatch_action) = @_;
1280 my $dbh = C4
::Context
->dbh;
1281 my $sth = $dbh->prepare("UPDATE import_batches SET nomatch_action = ? WHERE import_batch_id = ?");
1282 $sth->execute($new_nomatch_action, $batch_id);
1287 =head2 GetImportBatchItemAction
1289 my $item_action = GetImportBatchItemAction($batch_id);
1293 sub GetImportBatchItemAction
{
1294 my ($batch_id) = @_;
1296 my $dbh = C4
::Context
->dbh;
1297 my $sth = $dbh->prepare("SELECT item_action FROM import_batches WHERE import_batch_id = ?");
1298 $sth->execute($batch_id);
1299 my ($item_action) = $sth->fetchrow_array();
1301 return $item_action;
1306 =head2 SetImportBatchItemAction
1308 SetImportBatchItemAction($batch_id, $new_item_action);
1312 sub SetImportBatchItemAction
{
1313 my ($batch_id, $new_item_action) = @_;
1315 my $dbh = C4
::Context
->dbh;
1316 my $sth = $dbh->prepare("UPDATE import_batches SET item_action = ? WHERE import_batch_id = ?");
1317 $sth->execute($new_item_action, $batch_id);
1322 =head2 GetImportBatchMatcher
1324 my $matcher_id = GetImportBatchMatcher($batch_id);
1328 sub GetImportBatchMatcher
{
1329 my ($batch_id) = @_;
1331 my $dbh = C4
::Context
->dbh;
1332 my $sth = $dbh->prepare("SELECT matcher_id FROM import_batches WHERE import_batch_id = ?");
1333 $sth->execute($batch_id);
1334 my ($matcher_id) = $sth->fetchrow_array();
1341 =head2 SetImportBatchMatcher
1343 SetImportBatchMatcher($batch_id, $new_matcher_id);
1347 sub SetImportBatchMatcher
{
1348 my ($batch_id, $new_matcher_id) = @_;
1350 my $dbh = C4
::Context
->dbh;
1351 my $sth = $dbh->prepare("UPDATE import_batches SET matcher_id = ? WHERE import_batch_id = ?");
1352 $sth->execute($new_matcher_id, $batch_id);
1357 =head2 GetImportRecordOverlayStatus
1359 my $overlay_status = GetImportRecordOverlayStatus($import_record_id);
1363 sub GetImportRecordOverlayStatus
{
1364 my ($import_record_id) = @_;
1366 my $dbh = C4
::Context
->dbh;
1367 my $sth = $dbh->prepare("SELECT overlay_status FROM import_records WHERE import_record_id = ?");
1368 $sth->execute($import_record_id);
1369 my ($overlay_status) = $sth->fetchrow_array();
1371 return $overlay_status;
1376 =head2 SetImportRecordOverlayStatus
1378 SetImportRecordOverlayStatus($import_record_id, $new_overlay_status);
1382 sub SetImportRecordOverlayStatus
{
1383 my ($import_record_id, $new_overlay_status) = @_;
1385 my $dbh = C4
::Context
->dbh;
1386 my $sth = $dbh->prepare("UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?");
1387 $sth->execute($new_overlay_status, $import_record_id);
1392 =head2 GetImportRecordStatus
1394 my $status = GetImportRecordStatus($import_record_id);
1398 sub GetImportRecordStatus
{
1399 my ($import_record_id) = @_;
1401 my $dbh = C4
::Context
->dbh;
1402 my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
1403 $sth->execute($import_record_id);
1404 my ($status) = $sth->fetchrow_array();
1411 =head2 SetImportRecordStatus
1413 SetImportRecordStatus($import_record_id, $new_status);
1417 sub SetImportRecordStatus
{
1418 my ($import_record_id, $new_status) = @_;
1420 my $dbh = C4
::Context
->dbh;
1421 my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
1422 $sth->execute($new_status, $import_record_id);
1427 =head2 GetImportRecordMatches
1429 my $results = GetImportRecordMatches($import_record_id, $best_only);
1433 sub GetImportRecordMatches
{
1434 my $import_record_id = shift;
1435 my $best_only = @_ ?
shift : 0;
1437 my $dbh = C4
::Context
->dbh;
1438 # FIXME currently biblio only
1439 my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber,
1440 candidate_match_id, score, record_type
1442 JOIN import_record_matches USING (import_record_id)
1443 LEFT JOIN biblio ON (biblionumber = candidate_match_id)
1444 WHERE import_record_id = ?
1445 ORDER BY score DESC, biblionumber DESC");
1446 $sth->bind_param(1, $import_record_id);
1449 while (my $row = $sth->fetchrow_hashref) {
1450 if ($row->{'record_type'} eq 'auth') {
1451 $row->{'authorized_heading'} = C4
::AuthoritiesMarc
::GetAuthorizedHeading
( { authid
=> $row->{'candidate_match_id'} } );
1453 next if ($row->{'record_type'} eq 'biblio' && not $row->{'biblionumber'});
1454 push @
$results, $row;
1463 =head2 SetImportRecordMatches
1465 SetImportRecordMatches($import_record_id, @matches);
1469 sub SetImportRecordMatches
{
1470 my $import_record_id = shift;
1473 my $dbh = C4
::Context
->dbh;
1474 my $delsth = $dbh->prepare("DELETE FROM import_record_matches WHERE import_record_id = ?");
1475 $delsth->execute($import_record_id);
1478 my $sth = $dbh->prepare("INSERT INTO import_record_matches (import_record_id, candidate_match_id, score)
1480 foreach my $match (@matches) {
1481 $sth->execute($import_record_id, $match->{'record_id'}, $match->{'score'});
1485 =head2 RecordsFromISO2709File
1487 my ($errors, $records) = C4::ImportBatch::RecordsFromISO2709File($input_file, $record_type, $encoding);
1489 Reads ISO2709 binary porridge from the given file and creates MARC::Record-objects out of it.
1491 @PARAM1, String, absolute path to the ISO2709 file.
1492 @PARAM2, String, see stage_file.pl
1493 @PARAM3, String, should be utf8
1495 Returns two array refs.
1499 sub RecordsFromISO2709File
{
1500 my ($input_file, $record_type, $encoding) = @_;
1503 my $marc_type = C4
::Context
->preference('marcflavour');
1504 $marc_type .= 'AUTH' if ($marc_type eq 'UNIMARC' && $record_type eq 'auth');
1506 open IN
, "<$input_file" or die "$0: cannot open input file $input_file: $!\n";
1512 next unless $_; # skip if record has only whitespace, as might occur
1513 # if file includes newlines between each MARC record
1514 my ($marc_record, $charset_guessed, $char_errors) = MarcToUTF8Record
($_, $marc_type, $encoding);
1515 push @marc_records, $marc_record;
1516 if ($charset_guessed ne $encoding) {
1518 "Unexpected charset $charset_guessed, expecting $encoding";
1522 return ( \
@errors, \
@marc_records );
1525 =head2 RecordsFromMARCXMLFile
1527 my ($errors, $records) = C4::ImportBatch::RecordsFromMARCXMLFile($input_file, $encoding);
1529 Creates MARC::Record-objects out of the given MARCXML-file.
1531 @PARAM1, String, absolute path to the ISO2709 file.
1532 @PARAM2, String, should be utf8
1534 Returns two array refs.
1538 sub RecordsFromMARCXMLFile
{
1539 my ( $filename, $encoding ) = @_;
1540 my $batch = MARC
::File
::XML
->in( $filename );
1541 my ( @marcRecords, @errors, $record );
1543 eval { $record = $batch->next( $encoding ); };
1547 push @marcRecords, $record if $record;
1549 return (\
@errors, \
@marcRecords);
1552 =head2 RecordsFromMarcPlugin
1554 Converts text of input_file into array of MARC records with to_marc plugin
1558 sub RecordsFromMarcPlugin
{
1559 my ($input_file, $plugin_class, $encoding) = @_;
1560 my ( $text, @return );
1561 return \
@return if !$input_file || !$plugin_class;
1564 open IN
, "<$input_file" or die "$0: cannot open input file $input_file: $!\n";
1574 # Convert to large MARC blob with plugin
1575 $text = Koha
::Plugins
::Handler
->run({
1576 class => $plugin_class,
1577 method
=> 'to_marc',
1578 params
=> { data
=> $text },
1581 # Convert to array of MARC records
1583 my $marc_type = C4
::Context
->preference('marcflavour');
1584 foreach my $blob ( split(/\x1D/, $text) ) {
1585 next if $blob =~ /^\s*$/;
1586 my ($marcrecord) = MarcToUTF8Record
($blob, $marc_type, $encoding);
1587 push @return, $marcrecord;
1593 # internal functions
1595 sub _create_import_record
{
1596 my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random, $marc_type) = @_;
1598 my $dbh = C4
::Context
->dbh;
1599 my $sth = $dbh->prepare("INSERT INTO import_records (import_batch_id, record_sequence, marc, marcxml, marcxml_old,
1600 record_type, encoding, z3950random)
1601 VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
1602 $sth->execute($batch_id, $record_sequence, $marc_record->as_usmarc(), $marc_record->as_xml($marc_type), '',
1603 $record_type, $encoding, $z3950random);
1604 my $import_record_id = $dbh->{'mysql_insertid'};
1606 return $import_record_id;
1609 sub _update_import_record_marc
{
1610 my ($import_record_id, $marc_record, $marc_type) = @_;
1612 my $dbh = C4
::Context
->dbh;
1613 my $sth = $dbh->prepare("UPDATE import_records SET marc = ?, marcxml = ?
1614 WHERE import_record_id = ?");
1615 $sth->execute($marc_record->as_usmarc(), $marc_record->as_xml($marc_type), $import_record_id);
1619 sub _add_auth_fields
{
1620 my ($import_record_id, $marc_record) = @_;
1623 if ($marc_record->field('001')) {
1624 $controlnumber = $marc_record->field('001')->data();
1626 my $authorized_heading = C4
::AuthoritiesMarc
::GetAuthorizedHeading
({ record
=> $marc_record });
1627 my $dbh = C4
::Context
->dbh;
1628 my $sth = $dbh->prepare("INSERT INTO import_auths (import_record_id, control_number, authorized_heading) VALUES (?, ?, ?)");
1629 $sth->execute($import_record_id, $controlnumber, $authorized_heading);
1633 sub _add_biblio_fields
{
1634 my ($import_record_id, $marc_record) = @_;
1636 my ($title, $author, $isbn, $issn) = _parse_biblio_fields
($marc_record);
1637 my $dbh = C4
::Context
->dbh;
1638 # FIXME no controlnumber, originalsource
1639 $isbn = C4
::Koha
::GetNormalizedISBN
($isbn);
1640 my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1641 $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1646 sub _update_biblio_fields
{
1647 my ($import_record_id, $marc_record) = @_;
1649 my ($title, $author, $isbn, $issn) = _parse_biblio_fields
($marc_record);
1650 my $dbh = C4
::Context
->dbh;
1651 # FIXME no controlnumber, originalsource
1652 # FIXME 2 - should regularize normalization of ISBN wherever it is done
1656 my $sth = $dbh->prepare("UPDATE import_biblios SET title = ?, author = ?, isbn = ?, issn = ?
1657 WHERE import_record_id = ?");
1658 $sth->execute($title, $author, $isbn, $issn, $import_record_id);
1662 sub _parse_biblio_fields
{
1663 my ($marc_record) = @_;
1665 my $dbh = C4
::Context
->dbh;
1666 my $bibliofields = TransformMarcToKoha
($marc_record, '');
1667 return ($bibliofields->{'title'}, $bibliofields->{'author'}, $bibliofields->{'isbn'}, $bibliofields->{'issn'});
1671 sub _update_batch_record_counts
{
1672 my ($batch_id) = @_;
1674 my $dbh = C4
::Context
->dbh;
1675 my $sth = $dbh->prepare_cached("UPDATE import_batches SET
1679 WHERE import_batch_id = import_batches.import_batch_id),
1683 JOIN import_items USING (import_record_id)
1684 WHERE import_batch_id = import_batches.import_batch_id
1685 AND record_type = 'biblio')
1686 WHERE import_batch_id = ?");
1687 $sth->bind_param(1, $batch_id);
1692 sub _get_commit_action
{
1693 my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id, $record_type) = @_;
1695 if ($record_type eq 'biblio') {
1696 my ($bib_result, $bib_match, $item_result);
1698 if ($overlay_status ne 'no_match') {
1699 $bib_match = GetBestRecordMatch
($import_record_id);
1700 if ($overlay_action eq 'replace') {
1701 $bib_result = defined($bib_match) ?
'replace' : 'create_new';
1702 } elsif ($overlay_action eq 'create_new') {
1703 $bib_result = 'create_new';
1704 } elsif ($overlay_action eq 'ignore') {
1705 $bib_result = 'ignore';
1707 if($item_action eq 'always_add' or $item_action eq 'add_only_for_matches'){
1708 $item_result = 'create_new';
1710 elsif($item_action eq 'replace'){
1711 $item_result = 'replace';
1714 $item_result = 'ignore';
1717 $bib_result = $nomatch_action;
1718 $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ?
'create_new' : 'ignore';
1720 return ($bib_result, $item_result, $bib_match);
1721 } else { # must be auths
1722 my ($auth_result, $auth_match);
1724 if ($overlay_status ne 'no_match') {
1725 $auth_match = GetBestRecordMatch
($import_record_id);
1726 if ($overlay_action eq 'replace') {
1727 $auth_result = defined($auth_match) ?
'replace' : 'create_new';
1728 } elsif ($overlay_action eq 'create_new') {
1729 $auth_result = 'create_new';
1730 } elsif ($overlay_action eq 'ignore') {
1731 $auth_result = 'ignore';
1734 $auth_result = $nomatch_action;
1737 return ($auth_result, undef, $auth_match);
1742 sub _get_revert_action
{
1743 my ($overlay_action, $overlay_status, $status) = @_;
1747 if ($status eq 'ignored') {
1748 $bib_result = 'ignore';
1750 if ($overlay_action eq 'create_new') {
1751 $bib_result = 'delete';
1753 $bib_result = ($overlay_status eq 'match_applied') ?
'restore' : 'delete';
1764 Koha Development Team <http://koha-community.org/>
1766 Galen Charlton <galen.charlton@liblime.com>