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