|
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 |
- |
|
|