Lines 324-329
my $logger = Koha::Logger->get;
Link Here
|
324 |
my $schema = Koha::Database->schema; |
324 |
my $schema = Koha::Database->schema; |
325 |
my $marc_records = []; |
325 |
my $marc_records = []; |
326 |
my $lint = MARC::Lint->new; |
326 |
my $lint = MARC::Lint->new; |
|
|
327 |
$schema->txn_begin; |
328 |
$record_number = 0; |
327 |
RECORD: while () { |
329 |
RECORD: while () { |
328 |
my $record; |
330 |
my $record; |
329 |
$record_number++; |
331 |
$record_number++; |
Lines 356-361
RECORD: while () {
Link Here
|
356 |
next; |
358 |
next; |
357 |
} |
359 |
} |
358 |
} |
360 |
} |
|
|
361 |
|
359 |
# transcode the record to UTF8 if needed & applicable. |
362 |
# transcode the record to UTF8 if needed & applicable. |
360 |
if ( $record->encoding() eq 'MARC-8' and not $skip_marc8_conversion ) { |
363 |
if ( $record->encoding() eq 'MARC-8' and not $skip_marc8_conversion ) { |
361 |
my ( $guessed_charset, $charset_errors ); |
364 |
my ( $guessed_charset, $charset_errors ); |
Lines 370-733
RECORD: while () {
Link Here
|
370 |
} |
373 |
} |
371 |
SetUTF8Flag($record); |
374 |
SetUTF8Flag($record); |
372 |
&$localcust($record) if $localcust; |
375 |
&$localcust($record) if $localcust; |
373 |
push @{$marc_records}, $record; |
|
|
374 |
} else { |
375 |
last; |
376 |
} |
377 |
} |
378 |
|
376 |
|
379 |
$record_number = 0; |
377 |
$record_number++; |
380 |
my $records_total = @{$marc_records}; |
378 |
if ( ( $verbose // 1 ) == 1 ) { #no dot for verbose==2 |
381 |
$schema->txn_begin; |
379 |
print "." . ( $record_number % 100 == 0 ? "\n$record_number" : '' ); |
382 |
RECORD: foreach my $record ( @{$marc_records} ) { |
380 |
} |
383 |
$record_number++; |
|
|
384 |
if ( ( $verbose // 1 ) == 1 ) { #no dot for verbose==2 |
385 |
print "." . ( $record_number % 100 == 0 ? "\n$record_number" : '' ); |
386 |
} |
387 |
|
381 |
|
388 |
if ( $marc_mod_template_id > 0 ) { |
382 |
if ( $marc_mod_template_id > 0 ) { |
389 |
print "Modifying MARC\n" if $verbose; |
383 |
print "Modifying MARC\n" if $verbose; |
390 |
ModifyRecordWithTemplate( $marc_mod_template_id, $record ); |
384 |
ModifyRecordWithTemplate( $marc_mod_template_id, $record ); |
391 |
} |
385 |
} |
392 |
|
386 |
|
393 |
my $isbn; |
387 |
my $isbn; |
394 |
|
388 |
|
395 |
# remove trailing - in isbn (only for biblios, of course) |
389 |
# remove trailing - in isbn (only for biblios, of course) |
396 |
if ( $biblios && ( $cleanisbn || $isbn_check ) ) { |
390 |
if ( $biblios && ( $cleanisbn || $isbn_check ) ) { |
397 |
my $tag = $marc_flavour eq 'UNIMARC' ? '010' : '020'; |
391 |
my $tag = $marc_flavour eq 'UNIMARC' ? '010' : '020'; |
398 |
my $field = $record->field($tag); |
392 |
my $field = $record->field($tag); |
399 |
$isbn = $field && $field->subfield('a'); |
393 |
$isbn = $field && $field->subfield('a'); |
400 |
if ( $isbn && $cleanisbn ) { |
394 |
if ( $isbn && $cleanisbn ) { |
401 |
$isbn =~ s/-//g; |
395 |
$isbn =~ s/-//g; |
402 |
$field->update( 'a' => $isbn ); |
396 |
$field->update( 'a' => $isbn ); |
|
|
397 |
} |
403 |
} |
398 |
} |
404 |
} |
|
|
405 |
|
399 |
|
406 |
# search for duplicates (based on Local-number) |
400 |
# search for duplicates (based on Local-number) |
407 |
my $originalid = GetRecordId( $record, $tagid, $subfieldid ); |
401 |
my $originalid = GetRecordId( $record, $tagid, $subfieldid ); |
408 |
my $matched_record_id = undef; |
402 |
my $matched_record_id = undef; |
409 |
if ($match) { |
403 |
if ($match) { |
410 |
require C4::Search; |
404 |
require C4::Search; |
411 |
my $server = ( $authorities ? 'authorityserver' : 'biblioserver' ); |
405 |
my $server = ( $authorities ? 'authorityserver' : 'biblioserver' ); |
412 |
my $query = build_query( $match, $record ); |
406 |
my $query = build_query( $match, $record ); |
413 |
$logger->debug("Bulkmarcimport: $query"); |
407 |
$logger->debug("Bulkmarcimport: $query"); |
414 |
my ( $error, $results, $totalhits ) = $searcher->simple_search_compat( $query, 0, 3, [$server] ); |
408 |
my ( $error, $results, $totalhits ) = $searcher->simple_search_compat( $query, 0, 3, [$server] ); |
415 |
|
409 |
|
416 |
# changed to warn so able to continue with one broken record |
410 |
# changed to warn so able to continue with one broken record |
417 |
if ( defined $error ) { |
411 |
if ( defined $error ) { |
418 |
warn "unable to search the database for duplicates : $error"; |
412 |
warn "unable to search the database for duplicates : $error"; |
419 |
printlog( { id => $originalid, op => "match", status => "ERROR" } ) if ($logfile); |
413 |
printlog( { id => $originalid, op => "match", status => "ERROR" } ) if ($logfile); |
420 |
next RECORD; |
414 |
next RECORD; |
421 |
} |
415 |
} |
422 |
$logger->debug("Bulkmarcimport: $query $server : $totalhits"); |
416 |
$logger->debug("Bulkmarcimport: $query $server : $totalhits"); |
423 |
|
417 |
|
424 |
# sub SimpleSearch could return undefined, but only on error, so |
418 |
# sub SimpleSearch could return undefined, but only on error, so |
425 |
# should not really need to safeguard here, but do so anyway |
419 |
# should not really need to safeguard here, but do so anyway |
426 |
$results //= []; |
420 |
$results //= []; |
427 |
if ( @{$results} == 1 ) { |
421 |
if ( @{$results} == 1 ) { |
428 |
my $matched_record = C4::Search::new_record_from_zebra( $server, $results->[0] ); |
422 |
my $matched_record = C4::Search::new_record_from_zebra( $server, $results->[0] ); |
429 |
SetUTF8Flag($matched_record); |
423 |
SetUTF8Flag($matched_record); |
430 |
$matched_record_id = GetRecordId( $matched_record, $tagid, $subfieldid ); |
424 |
$matched_record_id = GetRecordId( $matched_record, $tagid, $subfieldid ); |
431 |
|
425 |
|
432 |
if ( $authorities && $marc_flavour ) { |
426 |
if ( $authorities && $marc_flavour ) { |
433 |
|
427 |
|
434 |
#Skip if authority in database is the same or newer than the incoming record |
428 |
#Skip if authority in database is the same or newer than the incoming record |
435 |
if ( RecordRevisionIsGtOrEq( $matched_record, $record ) ) { |
429 |
if ( RecordRevisionIsGtOrEq( $matched_record, $record ) ) { |
436 |
if ($yamlfile) { |
430 |
if ($yamlfile) { |
437 |
$yamlhash->{$originalid} = YAMLFileEntry( |
431 |
$yamlhash->{$originalid} = YAMLFileEntry( |
438 |
$matched_record, |
432 |
$matched_record, |
439 |
$matched_record_id, |
433 |
$matched_record_id, |
440 |
0 |
434 |
0 |
441 |
); |
435 |
); |
|
|
436 |
} |
437 |
next; |
442 |
} |
438 |
} |
443 |
next; |
|
|
444 |
} |
439 |
} |
|
|
440 |
} elsif ( @{$results} > 1 ) { |
441 |
$logger->debug("More than one match for: $query"); |
442 |
next; |
443 |
} else { |
444 |
$logger->debug("No match for: $query"); |
445 |
} |
445 |
} |
446 |
} elsif ( @{$results} > 1 ) { |
|
|
447 |
$logger->debug("More than one match for: $query"); |
448 |
next; |
449 |
} else { |
450 |
$logger->debug("No match for: $query"); |
451 |
} |
452 |
|
446 |
|
453 |
if ( $keepids && $originalid ) { |
447 |
if ( $keepids && $originalid ) { |
454 |
my $storeidfield; |
448 |
my $storeidfield; |
455 |
if ( length($keepids) == 3 ) { |
449 |
if ( length($keepids) == 3 ) { |
456 |
$storeidfield = MARC::Field->new( $keepids, $originalid ); |
450 |
$storeidfield = MARC::Field->new( $keepids, $originalid ); |
457 |
} else { |
451 |
} else { |
458 |
$storeidfield = |
452 |
$storeidfield = |
459 |
MARC::Field->new( substr( $keepids, 0, 3 ), "", "", substr( $keepids, 3, 1 ), $originalid ); |
453 |
MARC::Field->new( substr( $keepids, 0, 3 ), "", "", substr( $keepids, 3, 1 ), $originalid ); |
|
|
454 |
} |
455 |
$record->insert_fields_ordered($storeidfield); |
456 |
$record->delete_field( $record->field($tagid) ); |
460 |
} |
457 |
} |
461 |
$record->insert_fields_ordered($storeidfield); |
|
|
462 |
$record->delete_field( $record->field($tagid) ); |
463 |
} |
458 |
} |
464 |
} |
|
|
465 |
|
459 |
|
466 |
foreach my $stringfilter (@$filters) { |
460 |
foreach my $stringfilter (@$filters) { |
467 |
if ( length($stringfilter) == 3 ) { |
461 |
if ( length($stringfilter) == 3 ) { |
468 |
foreach my $field ( $record->field($stringfilter) ) { |
462 |
foreach my $field ( $record->field($stringfilter) ) { |
469 |
$record->delete_field($field); |
463 |
$record->delete_field($field); |
470 |
$logger->debug( "Removed: ", $field->as_string ); |
464 |
$logger->debug( "Removed: ", $field->as_string ); |
471 |
} |
465 |
} |
472 |
} elsif ( $stringfilter =~ /([0-9]{3})([a-z0-9])(.*)/ ) { |
466 |
} elsif ( $stringfilter =~ /([0-9]{3})([a-z0-9])(.*)/ ) { |
473 |
my $removetag = $1; |
467 |
my $removetag = $1; |
474 |
my $removesubfield = $2; |
468 |
my $removesubfield = $2; |
475 |
my $removematch = $3; |
469 |
my $removematch = $3; |
476 |
if ( ( $removetag > "010" ) && $removesubfield ) { |
470 |
if ( ( $removetag > "010" ) && $removesubfield ) { |
477 |
foreach my $field ( $record->field($removetag) ) { |
471 |
foreach my $field ( $record->field($removetag) ) { |
478 |
$field->delete_subfield( code => "$removesubfield", match => $removematch ); |
472 |
$field->delete_subfield( code => "$removesubfield", match => $removematch ); |
479 |
$logger->debug( "Potentially removed: ", $field->subfield($removesubfield) ); |
473 |
$logger->debug( "Potentially removed: ", $field->subfield($removesubfield) ); |
|
|
474 |
} |
480 |
} |
475 |
} |
481 |
} |
476 |
} |
482 |
} |
477 |
} |
483 |
} |
478 |
unless ($test_parameter) { |
484 |
unless ($test_parameter) { |
479 |
if ($authorities) { |
485 |
if ($authorities) { |
480 |
my $authtypecode = GuessAuthTypeCode( $record, $heading_fields ); |
486 |
my $authtypecode = GuessAuthTypeCode( $record, $heading_fields ); |
481 |
my $authid; |
487 |
my $authid; |
482 |
|
488 |
|
483 |
if ($matched_record_id) { |
489 |
if ($matched_record_id) { |
484 |
if ($update) { |
490 |
if ($update) { |
485 |
## Authority has an id and is in database: update |
491 |
## Authority has an id and is in database: update |
486 |
eval { |
492 |
eval { |
487 |
($authid) = ModAuthority( |
493 |
($authid) = ModAuthority( |
488 |
$matched_record_id, $record, $authtypecode, |
494 |
$matched_record_id, $record, $authtypecode, |
489 |
$mod_authority_options, |
495 |
$mod_authority_options, |
490 |
); |
|
|
491 |
}; |
492 |
if ($@) { |
493 |
warn "ERROR: Update authority $matched_record_id failed: $@\n"; |
494 |
printlog( { id => $matched_record_id, op => "update", status => "ERROR" } ) if ($logfile); |
495 |
next RECORD; |
496 |
} else { |
497 |
printlog( { id => $authid, op => "update", status => "ok" } ) if ($logfile); |
498 |
} |
499 |
} elsif ($logfile) { |
500 |
warn "WARNING: Update authority $originalid skipped"; |
501 |
printlog( |
502 |
{ |
503 |
id => $matched_record_id, |
504 |
op => "update", |
505 |
status => |
506 |
"warning: authority already in database and option -update not enabled, skipping..." |
507 |
} |
496 |
); |
508 |
); |
497 |
}; |
509 |
} |
|
|
510 |
} elsif ($insert) { |
511 |
## An authid is defined but no authority in database: insert |
512 |
eval { ($authid) = AddAuthority( $record, undef, $authtypecode, $add_authority_options ); }; |
498 |
if ($@) { |
513 |
if ($@) { |
499 |
warn "ERROR: Update authority $matched_record_id failed: $@\n"; |
514 |
warn "ERROR: Insert authority $originalid failed: $@\n"; |
500 |
printlog( { id => $matched_record_id, op => "update", status => "ERROR" } ) if ($logfile); |
515 |
printlog( { id => $originalid, op => "insert", status => "ERROR" } ) if ($logfile); |
501 |
next RECORD; |
516 |
next RECORD; |
502 |
} else { |
517 |
} else { |
503 |
printlog( { id => $authid, op => "update", status => "ok" } ) if ($logfile); |
518 |
printlog( { id => $authid, op => "insert", status => "ok" } ) if ($logfile); |
504 |
} |
519 |
} |
505 |
} elsif ($logfile) { |
520 |
} else { |
506 |
warn "WARNING: Update authority $originalid skipped"; |
521 |
warn "WARNING: Insert authority $originalid skipped"; |
507 |
printlog( |
522 |
printlog( |
508 |
{ |
523 |
{ |
509 |
id => $matched_record_id, |
524 |
id => $originalid, op => "insert", |
510 |
op => "update", |
525 |
status => "warning : authority not in database and option -insert not enabled, skipping..." |
511 |
status => |
|
|
512 |
"warning: authority already in database and option -update not enabled, skipping..." |
513 |
} |
526 |
} |
514 |
); |
527 |
) if ($logfile); |
515 |
} |
528 |
} |
516 |
} elsif ($insert) { |
529 |
|
517 |
## An authid is defined but no authority in database: insert |
530 |
if ($yamlfile) { |
518 |
eval { ($authid) = AddAuthority( $record, undef, $authtypecode, $add_authority_options ); }; |
531 |
$yamlhash->{$originalid} = YAMLFileEntry( |
519 |
if ($@) { |
532 |
$record, |
520 |
warn "ERROR: Insert authority $originalid failed: $@\n"; |
533 |
$authid, |
521 |
printlog( { id => $originalid, op => "insert", status => "ERROR" } ) if ($logfile); |
534 |
1 #@FIXME: Really always updated? |
522 |
next RECORD; |
535 |
); |
523 |
} else { |
|
|
524 |
printlog( { id => $authid, op => "insert", status => "ok" } ) if ($logfile); |
525 |
} |
536 |
} |
|
|
537 |
push @search_engine_record_ids, $authid; |
538 |
push @search_engine_records, $record; |
526 |
} else { |
539 |
} else { |
527 |
warn "WARNING: Insert authority $originalid skipped"; |
540 |
my ( $biblioitemnumber, $itemnumbers_ref, $errors_ref, $record_id ); |
528 |
printlog( |
|
|
529 |
{ |
530 |
id => $originalid, op => "insert", |
531 |
status => "warning : authority not in database and option -insert not enabled, skipping..." |
532 |
} |
533 |
) if ($logfile); |
534 |
} |
535 |
|
536 |
if ($yamlfile) { |
537 |
$yamlhash->{$originalid} = YAMLFileEntry( |
538 |
$record, |
539 |
$authid, |
540 |
1 #@FIXME: Really always updated? |
541 |
); |
542 |
} |
543 |
push @search_engine_record_ids, $authid; |
544 |
push @search_engine_records, $record; |
545 |
} else { |
546 |
my ( $biblioitemnumber, $itemnumbers_ref, $errors_ref, $record_id ); |
547 |
|
541 |
|
548 |
# check for duplicate, based on ISBN (skip it if we already have found a duplicate with match parameter |
542 |
# check for duplicate, based on ISBN (skip it if we already have found a duplicate with match parameter |
549 |
if ( !$matched_record_id && $isbn_check && $isbn ) { |
543 |
if ( !$matched_record_id && $isbn_check && $isbn ) { |
550 |
$sth_isbn->execute($isbn); |
544 |
$sth_isbn->execute($isbn); |
551 |
( $matched_record_id, $biblioitemnumber ) = $sth_isbn->fetchrow; |
545 |
( $matched_record_id, $biblioitemnumber ) = $sth_isbn->fetchrow; |
552 |
} |
546 |
} |
553 |
|
547 |
|
554 |
if ( defined $idmapfl && $matched_record_id ) { |
548 |
if ( defined $idmapfl && $matched_record_id ) { |
555 |
if ( $sourcetag < "010" ) { |
549 |
if ( $sourcetag < "010" ) { |
556 |
if ( $record->field($sourcetag) ) { |
550 |
if ( $record->field($sourcetag) ) { |
557 |
my $source = $record->field($sourcetag)->data(); |
551 |
my $source = $record->field($sourcetag)->data(); |
|
|
552 |
printf( $idmapfh "%s|%s\n", $source, $matched_record_id ); |
553 |
} |
554 |
} else { |
555 |
my $source = $record->subfield( $sourcetag, $sourcesubfield ); |
558 |
printf( $idmapfh "%s|%s\n", $source, $matched_record_id ); |
556 |
printf( $idmapfh "%s|%s\n", $source, $matched_record_id ); |
559 |
} |
557 |
} |
560 |
} else { |
|
|
561 |
my $source = $record->subfield( $sourcetag, $sourcesubfield ); |
562 |
printf( $idmapfh "%s|%s\n", $source, $matched_record_id ); |
563 |
} |
558 |
} |
564 |
} |
|
|
565 |
|
559 |
|
566 |
# Create biblio, unless we already have it (either match or ISBN) |
560 |
# Create biblio, unless we already have it (either match or ISBN) |
567 |
if ($matched_record_id) { |
561 |
if ($matched_record_id) { |
568 |
eval { $biblioitemnumber = Koha::Biblios->find($matched_record_id)->biblioitem->biblioitemnumber; }; |
562 |
eval { $biblioitemnumber = Koha::Biblios->find($matched_record_id)->biblioitem->biblioitemnumber; }; |
569 |
if ($update) { |
563 |
if ($update) { |
570 |
my $success; |
564 |
my $success; |
|
|
565 |
eval { |
566 |
$success = ModBiblio( |
567 |
$record, $matched_record_id, GetFrameworkCode($matched_record_id), |
568 |
$mod_biblio_options |
569 |
); |
570 |
}; |
571 |
if ($@) { |
572 |
warn "ERROR: Update biblio $matched_record_id failed: $@\n"; |
573 |
printlog( { id => $matched_record_id, op => "update", status => "ERROR" } ) if ($logfile); |
574 |
next RECORD; |
575 |
} elsif ( !$success ) { |
576 |
warn "ERROR: Update biblio $matched_record_id failed for unknown reason"; |
577 |
printlog( { id => $matched_record_id, op => "update", status => "ERROR" } ) if ($logfile); |
578 |
next RECORD; |
579 |
} else { |
580 |
$record_id = $matched_record_id; |
581 |
printlog( { id => $record_id, op => "update", status => "ok" } ) if ($logfile); |
582 |
} |
583 |
} else { |
584 |
warn "WARNING: Update biblio $originalid skipped"; |
585 |
printlog( |
586 |
{ |
587 |
id => $matched_record_id, op => "update", |
588 |
status => "warning : already in database and option -update not enabled, skipping..." |
589 |
} |
590 |
) if ($logfile); |
591 |
} |
592 |
} elsif ($insert) { |
593 |
my $record_clone = $record->clone(); |
594 |
C4::Biblio::_strip_item_fields($record_clone); |
571 |
eval { |
595 |
eval { |
572 |
$success = ModBiblio( |
596 |
( $record_id, $biblioitemnumber ) = AddBiblio( $record_clone, $framework, $add_biblio_options ); |
573 |
$record, $matched_record_id, GetFrameworkCode($matched_record_id), |
|
|
574 |
$mod_biblio_options |
575 |
); |
576 |
}; |
597 |
}; |
577 |
if ($@) { |
598 |
if ($@) { |
578 |
warn "ERROR: Update biblio $matched_record_id failed: $@\n"; |
599 |
warn "ERROR: Insert biblio $originalid failed: $@\n"; |
579 |
printlog( { id => $matched_record_id, op => "update", status => "ERROR" } ) if ($logfile); |
600 |
printlog( { id => $originalid, op => "insert", status => "ERROR" } ) if ($logfile); |
580 |
next RECORD; |
|
|
581 |
} elsif ( !$success ) { |
582 |
warn "ERROR: Update biblio $matched_record_id failed for unknown reason"; |
583 |
printlog( { id => $matched_record_id, op => "update", status => "ERROR" } ) if ($logfile); |
584 |
next RECORD; |
601 |
next RECORD; |
585 |
} else { |
602 |
} else { |
586 |
$record_id = $matched_record_id; |
603 |
printlog( { id => $originalid, op => "insert", status => "ok" } ) if ($logfile); |
587 |
printlog( { id => $record_id, op => "update", status => "ok" } ) if ($logfile); |
|
|
588 |
} |
604 |
} |
|
|
605 |
|
606 |
# If incoming record has bib ids set we need to transfer |
607 |
# new ids from record_clone to incoming record to avoid |
608 |
# working on wrong record (the original record) later on |
609 |
# when adding items for example |
610 |
C4::Biblio::_koha_marc_update_bib_ids( $record, $framework, $record_id, $biblioitemnumber ); |
589 |
} else { |
611 |
} else { |
590 |
warn "WARNING: Update biblio $originalid skipped"; |
612 |
warn "WARNING: Insert biblio $originalid skipped"; |
591 |
printlog( |
613 |
printlog( |
592 |
{ |
614 |
{ |
593 |
id => $matched_record_id, op => "update", |
615 |
id => $originalid, op => "insert", |
594 |
status => "warning : already in database and option -update not enabled, skipping..." |
616 |
status => "warning : biblio not in database and option -insert not enabled, skipping..." |
595 |
} |
617 |
} |
596 |
) if ($logfile); |
618 |
) if ($logfile); |
597 |
} |
|
|
598 |
} elsif ($insert) { |
599 |
my $record_clone = $record->clone(); |
600 |
C4::Biblio::_strip_item_fields($record_clone); |
601 |
eval { ( $record_id, $biblioitemnumber ) = AddBiblio( $record_clone, $framework, $add_biblio_options ) }; |
602 |
if ($@) { |
603 |
warn "ERROR: Insert biblio $originalid failed: $@\n"; |
604 |
printlog( { id => $originalid, op => "insert", status => "ERROR" } ) if ($logfile); |
605 |
next RECORD; |
619 |
next RECORD; |
606 |
} else { |
|
|
607 |
printlog( { id => $originalid, op => "insert", status => "ok" } ) if ($logfile); |
608 |
} |
620 |
} |
609 |
|
621 |
my $record_has_added_items = 0; |
610 |
# If incoming record has bib ids set we need to transfer |
622 |
if ($record_id) { |
611 |
# new ids from record_clone to incoming record to avoid |
623 |
$yamlhash->{$originalid} = $record_id if $yamlfile; |
612 |
# working on wrong record (the original record) later on |
|
|
613 |
# when adding items for example |
614 |
C4::Biblio::_koha_marc_update_bib_ids( $record, $framework, $record_id, $biblioitemnumber ); |
615 |
} else { |
616 |
warn "WARNING: Insert biblio $originalid skipped"; |
617 |
printlog( |
618 |
{ |
619 |
id => $originalid, op => "insert", |
620 |
status => "warning : biblio not in database and option -insert not enabled, skipping..." |
621 |
} |
622 |
) if ($logfile); |
623 |
next RECORD; |
624 |
} |
625 |
my $record_has_added_items = 0; |
626 |
if ($record_id) { |
627 |
$yamlhash->{$originalid} = $record_id if $yamlfile; |
628 |
eval { |
629 |
( $itemnumbers_ref, $errors_ref ) = |
630 |
AddItemBatchFromMarc( $record, $record_id, $biblioitemnumber, $framework ); |
631 |
}; |
632 |
my $error_adding = $@; |
633 |
|
634 |
if ($error_adding) { |
635 |
warn "ERROR: Adding items to bib $record_id failed: $error_adding"; |
636 |
printlog( { id => $record_id, op => "insert items", status => "ERROR" } ) if ($logfile); |
637 |
|
638 |
# if we failed because of an exception, assume that |
639 |
# the MARC columns in biblioitems were not set. |
640 |
next RECORD; |
641 |
} |
642 |
|
643 |
$record_has_added_items = @{$itemnumbers_ref}; |
644 |
|
645 |
if ( $dedup_barcode && grep { exists $_->{error_code} && $_->{error_code} eq 'duplicate_barcode' } |
646 |
@$errors_ref ) |
647 |
{ |
648 |
# Find the record called 'barcode' |
649 |
my ( $tag, $sub ) = C4::Biblio::GetMarcFromKohaField('items.barcode'); |
650 |
|
651 |
# Now remove any items that didn't have a duplicate_barcode error, |
652 |
# erase the barcodes on items that did, and re-add those items. |
653 |
my %dupes; |
654 |
foreach my $i ( 0 .. $#{$errors_ref} ) { |
655 |
my $ref = $errors_ref->[$i]; |
656 |
if ( $ref && ( $ref->{error_code} eq 'duplicate_barcode' ) ) { |
657 |
$dupes{ $ref->{item_sequence} } = 1; |
658 |
|
659 |
# Delete the error message because we're going to |
660 |
# retry this one. |
661 |
delete $errors_ref->[$i]; |
662 |
} |
663 |
} |
664 |
my $seq = 0; |
665 |
foreach my $field ( $record->field($tag) ) { |
666 |
$seq++; |
667 |
if ( $dupes{$seq} ) { |
668 |
|
669 |
# Here we remove the barcode |
670 |
$field->delete_subfield( code => $sub ); |
671 |
} else { |
672 |
|
673 |
# otherwise we delete the field because we don't want |
674 |
# two of them |
675 |
$record->delete_fields($field); |
676 |
} |
677 |
} |
678 |
|
679 |
# Now re-add the record as before, adding errors to the prev list |
680 |
my $more_errors; |
681 |
eval { |
624 |
eval { |
682 |
( $itemnumbers_ref, $more_errors ) = |
625 |
( $itemnumbers_ref, $errors_ref ) = |
683 |
AddItemBatchFromMarc( $record, $record_id, $biblioitemnumber, '' ); |
626 |
AddItemBatchFromMarc( $record, $record_id, $biblioitemnumber, $framework ); |
684 |
}; |
627 |
}; |
685 |
if ($@) { |
628 |
my $error_adding = $@; |
686 |
warn "ERROR: Adding items to bib $record_id failed: $@\n"; |
629 |
|
|
|
630 |
if ($error_adding) { |
631 |
warn "ERROR: Adding items to bib $record_id failed: $error_adding"; |
687 |
printlog( { id => $record_id, op => "insert items", status => "ERROR" } ) if ($logfile); |
632 |
printlog( { id => $record_id, op => "insert items", status => "ERROR" } ) if ($logfile); |
688 |
|
633 |
|
689 |
# if we failed because of an exception, assume that |
634 |
# if we failed because of an exception, assume that |
690 |
# the MARC columns in biblioitems were not set. |
635 |
# the MARC columns in biblioitems were not set. |
691 |
next RECORD; |
636 |
next RECORD; |
692 |
} |
637 |
} |
693 |
$record_has_added_items ||= @{$itemnumbers_ref}; |
638 |
|
694 |
if ( @{$more_errors} ) { |
639 |
$record_has_added_items = @{$itemnumbers_ref}; |
695 |
push @$errors_ref, @{$more_errors}; |
640 |
|
|
|
641 |
if ( $dedup_barcode && grep { exists $_->{error_code} && $_->{error_code} eq 'duplicate_barcode' } |
642 |
@$errors_ref ) |
643 |
{ |
644 |
# Find the record called 'barcode' |
645 |
my ( $tag, $sub ) = C4::Biblio::GetMarcFromKohaField('items.barcode'); |
646 |
|
647 |
# Now remove any items that didn't have a duplicate_barcode error, |
648 |
# erase the barcodes on items that did, and re-add those items. |
649 |
my %dupes; |
650 |
foreach my $i ( 0 .. $#{$errors_ref} ) { |
651 |
my $ref = $errors_ref->[$i]; |
652 |
if ( $ref && ( $ref->{error_code} eq 'duplicate_barcode' ) ) { |
653 |
$dupes{ $ref->{item_sequence} } = 1; |
654 |
|
655 |
# Delete the error message because we're going to |
656 |
# retry this one. |
657 |
delete $errors_ref->[$i]; |
658 |
} |
659 |
} |
660 |
my $seq = 0; |
661 |
foreach my $field ( $record->field($tag) ) { |
662 |
$seq++; |
663 |
if ( $dupes{$seq} ) { |
664 |
|
665 |
# Here we remove the barcode |
666 |
$field->delete_subfield( code => $sub ); |
667 |
} else { |
668 |
|
669 |
# otherwise we delete the field because we don't want |
670 |
# two of them |
671 |
$record->delete_fields($field); |
672 |
} |
673 |
} |
674 |
|
675 |
# Now re-add the record as before, adding errors to the prev list |
676 |
my $more_errors; |
677 |
eval { |
678 |
( $itemnumbers_ref, $more_errors ) = |
679 |
AddItemBatchFromMarc( $record, $record_id, $biblioitemnumber, '' ); |
680 |
}; |
681 |
if ($@) { |
682 |
warn "ERROR: Adding items to bib $record_id failed: $@\n"; |
683 |
printlog( { id => $record_id, op => "insert items", status => "ERROR" } ) if ($logfile); |
684 |
|
685 |
# if we failed because of an exception, assume that |
686 |
# the MARC columns in biblioitems were not set. |
687 |
next RECORD; |
688 |
} |
689 |
$record_has_added_items ||= @{$itemnumbers_ref}; |
690 |
if ( @{$more_errors} ) { |
691 |
push @$errors_ref, @{$more_errors}; |
692 |
} |
696 |
} |
693 |
} |
697 |
} |
|
|
698 |
|
694 |
|
699 |
if ($record_has_added_items) { |
695 |
if ($record_has_added_items) { |
700 |
printlog( { id => $record_id, op => "insert items", status => "ok" } ) if ($logfile); |
696 |
printlog( { id => $record_id, op => "insert items", status => "ok" } ) if ($logfile); |
701 |
} |
697 |
} |
702 |
|
698 |
|
703 |
if ( @{$errors_ref} ) { |
699 |
if ( @{$errors_ref} ) { |
704 |
report_item_errors( $record_id, $errors_ref ); |
700 |
report_item_errors( $record_id, $errors_ref ); |
705 |
} |
701 |
} |
706 |
|
702 |
|
707 |
my $biblio = Koha::Biblios->find($record_id); |
703 |
my $biblio = Koha::Biblios->find($record_id); |
708 |
$record = $biblio->metadata_record( { embed_items => 1 } ); |
704 |
$record = $biblio->metadata_record( { embed_items => 1 } ); |
709 |
|
705 |
|
710 |
push @search_engine_record_ids, $record_id; |
706 |
push @search_engine_record_ids, $record_id; |
711 |
push @search_engine_records, $record; |
707 |
push @search_engine_records, $record; |
|
|
708 |
} |
712 |
} |
709 |
} |
713 |
} |
710 |
if ( $record_number % $commitnum == 0 || $record_number == $number ) { |
714 |
if ( $record_number % $commitnum == 0 || $record_number == $number || $record_number == $records_total ) { |
711 |
$schema->txn_commit; |
715 |
$schema->txn_commit; |
712 |
$schema->txn_begin; |
716 |
$schema->txn_begin; |
713 |
if ($indexer) { |
717 |
if ($indexer) { |
714 |
$indexer->update_index( \@search_engine_record_ids, \@search_engine_records ) unless $skip_indexing; |
718 |
$indexer->update_index( \@search_engine_record_ids, \@search_engine_records ) unless $skip_indexing; |
715 |
if ( C4::Context->preference('AutoLinkBiblios') ) { |
719 |
if ( C4::Context->preference('AutoLinkBiblios') ) { |
716 |
foreach my $record (@search_engine_records) { |
720 |
foreach my $record (@search_engine_records) { |
717 |
BiblioAutoLink( $record, $framework ); |
721 |
BiblioAutoLink( $record, $framework ); |
718 |
} |
722 |
} |
719 |
} |
|
|
720 |
@search_engine_record_ids = (); |
721 |
@search_engine_records = (); |
723 |
} |
722 |
} |
724 |
@search_engine_record_ids = (); |
|
|
725 |
@search_engine_records = (); |
726 |
} |
723 |
} |
727 |
} |
724 |
} |
|
|
725 |
print $record->as_formatted() . "\n" if ( $verbose // 0 ) == 2; |
726 |
last if $record_number == $number; |
727 |
|
728 |
} else { |
729 |
last; |
728 |
} |
730 |
} |
729 |
print $record->as_formatted() . "\n" if ( $verbose // 0 ) == 2; |
|
|
730 |
last if $record_number == $number; |
731 |
} |
731 |
} |
732 |
$schema->txn_commit; |
732 |
$schema->txn_commit; |
733 |
|
733 |
|
734 |
- |
|
|