From 0d151b25e2b62ae2e624cf449e305db57326b400 Mon Sep 17 00:00:00 2001
From: David Gustafsson <david.gustafsson@ub.gu.se>
Date: Wed, 21 Sep 2022 17:43:32 +0200
Subject: [PATCH] Bug 29440: defer biblio autolinking until records are indexed

---
 C4/Biblio.pm                           | 44 +++++++++++++++-----------
 misc/migration_tools/bulkmarcimport.pl |  9 +++++-
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/C4/Biblio.pm b/C4/Biblio.pm
index 9f9dd02726..c03d2393a0 100644
--- a/C4/Biblio.pm
+++ b/C4/Biblio.pm
@@ -186,31 +186,36 @@ The first argument is a C<MARC::Record> object containing the
 bib to add, while the second argument is the desired MARC
 framework code.
 
-This function also accepts a third, optional argument: a hashref
-to additional options.  The only defined option is C<defer_marc_save>,
-which if present and mapped to a true value, causes C<AddBiblio>
-to omit the call to save the MARC in C<biblio_metadata.metadata>
-This option is provided B<only>
-for the use of scripts such as C<bulkmarcimport.pl> that may need
-to do some manipulation of the MARC record for item parsing before
-saving it and which cannot afford the performance hit of saving
-the MARC record twice.  Consequently, do not use that option
-unless you can guarantee that C<ModBiblioMarc> will be called.
+The C<$options> argument is a hashref with additional parameters:
+
+=over 4
+
+=item C<defer_marc_save>
+
+Causes C<AddBiblio> to omit the call to save the MARC in C<biblio_metadata.metadata>
+This option is provided B<only> for the use of scripts such as C<bulkmarcimport.pl>
+that may need to do some manipulation of the MARC record for item parsing before
+saving it and which cannot afford the performance hit of saving the MARC record twice.
+Consequently, do not use that option unless you can guarantee that C<ModBiblioMarc>
+will be called.
+
+=item C<disable_autolink>
+
+Unless C<disable_autolink> is passed AddBiblio will link record headings
+to authorities based on settings in the system preferences. This flag allows
+us to not link records when the authority linker is saving modifications.
+
+=back
 
 =cut
 
 sub AddBiblio {
-    my $record          = shift;
-    my $frameworkcode   = shift;
-    my $options         = @_ ? shift : undef;
-    my $defer_marc_save = 0;
+    my ($record, $frameworkcode, $options) = @_;
+    $options //= {};
     if (!$record) {
         carp('AddBiblio called with undefined record');
         return;
     }
-    if ( defined $options and exists $options->{'defer_marc_save'} and $options->{'defer_marc_save'} ) {
-        $defer_marc_save = 1;
-    }
 
     my $schema = Koha::Database->schema;
     my ( $biblionumber, $biblioitemnumber );
@@ -286,12 +291,12 @@ sub AddBiblio {
             # update MARC subfield that stores biblioitems.cn_sort
             _koha_marc_update_biblioitem_cn_sort( $record, $olddata, $frameworkcode );
 
-            if (C4::Context->preference('BiblioAddsAuthorities')) {
+            if ($options->{'disable_autolink'} && C4::Context->preference('BiblioAddsAuthorities')) {
                 BiblioAutoLink( $record, $frameworkcode );
             }
 
             # now add the record
-            ModBiblioMarc( $record, $biblionumber ) unless $defer_marc_save;
+            ModBiblioMarc( $record, $biblionumber ) unless $options->{'defer_marc_save'};
 
             # update OAI-PMH sets
             if(C4::Context->preference("OAI-PMH:AutoUpdateSets")) {
@@ -545,6 +550,7 @@ sub BiblioAutoLink {
     my $record        = shift;
     my $frameworkcode = shift;
     my $verbose = shift;
+
     if (!$record) {
         carp('Undefined record passed to BiblioAutoLink');
         return 0;
diff --git a/misc/migration_tools/bulkmarcimport.pl b/misc/migration_tools/bulkmarcimport.pl
index b9e961c911..dc2374c6a7 100755
--- a/misc/migration_tools/bulkmarcimport.pl
+++ b/misc/migration_tools/bulkmarcimport.pl
@@ -19,6 +19,7 @@ use C4::Biblio qw(
     ModBiblioMarc
     GetFrameworkCode
     GetMarcBiblio
+    BiblioAutoLink
 );
 use C4::Koha;
 use C4::Charset qw( MarcToUTF8Record SetUTF8Flag );
@@ -125,6 +126,7 @@ if ($all) {
 
 my $using_elastic_search = (C4::Context->preference('SearchEngine') eq 'Elasticsearch');
 my $modify_biblio_marc_options = {
+    disable_autolink => $using_elastic_search,
     defer_search_engine_indexing => $using_elastic_search,
     overlay_context => { source => 'bulkmarcimport' }
 };
@@ -541,7 +543,7 @@ RECORD: foreach my $record (@{$marc_records}) {
                 }
             }
             elsif ($insert) {
-                eval { ($record_id, $biblioitemnumber) = AddBiblio($record, $framework, { defer_marc_save => 1 }) };
+                eval { ($record_id, $biblioitemnumber) = AddBiblio($record, $framework, { disable_autolink => 1, defer_marc_save => 1 }) };
                 if ($@) {
                     warn "ERROR: Insert biblio $originalid failed: $@\n";
                     printlog( { id => $originalid, op => "insert", status => "ERROR" } ) if ($logfile);
@@ -645,6 +647,11 @@ RECORD: foreach my $record (@{$marc_records}) {
             $schema->txn_begin;
             if ($indexer) {
                 $indexer->update_index(\@search_engine_record_ids, \@search_engine_records);
+                if (C4::Context->preference('BiblioAddsAuthorities')) {
+                    foreach my $record (@search_engine_records) {
+                        BiblioAutoLink($record, $framework);
+                    }
+                }
                 @search_engine_record_ids = ();
                 @search_engine_records = ();
             }
-- 
2.35.1