From c27194a5b2e57924d697d39fe7afc46c96e93a34 Mon Sep 17 00:00:00 2001
From: Axel Amghar <axel.amghar@biblibre.com>
Date: Fri, 24 May 2019 17:13:50 +0200
Subject: [PATCH] Bug 22690: Merging records with many items (ElasticSearch)

This patch allow us to merged many items without timeout

Test plan :

Without the patch :

> - Create 2 records (one with 1000 items for example)
> - Add the records to one list and start the merging process of those records.
> - Choose the record with many items as the one to be eliminated.
> - Start the merging
> - After a while the web server should give you a timeout error (the merging process continues)

With the patch :
- make the same
- this time verify that all items have been merged without time out
---
 C4/Items.pm                                        | 61 ++++++++++++++++++++++
 cataloguing/merge.pl                               | 14 ++---
 .../prog/en/modules/cataloguing/merge.tt           |  2 +-
 3 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/C4/Items.pm b/C4/Items.pm
index 15b61f0..7df6267 100644
--- a/C4/Items.pm
+++ b/C4/Items.pm
@@ -1694,6 +1694,67 @@ sub MoveItemFromBiblio {
     return;
 }
 
+=head2 MoveItemsFromBiblio
+
+  MoveItemsFromBiblio($items_number, $frombiblio, $tobiblio);
+
+Moves all items from a biblio record to another
+
+return a table of items not moved
+
+=cut
+
+sub MoveItemsFromBiblio {
+    my ($items_number, $frombiblio, $tobiblio) = @_;
+    my $dbh = C4::Context->dbh;
+
+    my $nb_items = $dbh->selectrow_array(q|
+        SELECT COUNT(itemnumber)
+        FROM items
+        WHERE biblionumber = ?
+    |, undef, $frombiblio );
+
+    #if items are not already moved
+    if ($nb_items){
+        my $tobiblioitem = $dbh->selectrow_array(q|
+            SELECT biblioitemnumber
+            FROM biblioitems
+            WHERE biblionumber = ?
+        |, undef, $tobiblio );
+
+        $dbh->do(q|
+            UPDATE items
+            SET biblioitemnumber = ?,
+                biblionumber = ?
+            WHERE biblionumber = ?
+        |, undef, $tobiblioitem, $tobiblio, $frombiblio );
+
+        ModZebra( $tobiblio, "specialUpdate", "biblioserver" );
+        ModZebra( $frombiblio, "specialUpdate", "biblioserver" );
+
+        require C4::Acquisition;
+        my $where;
+        foreach my $item_number (@$items_number){
+            my $order = C4::Acquisition::GetOrderFromItemnumber($item_number);
+            if ($order) {
+                $order->{'biblionumber'} = $tobiblio;
+                C4::Acquisition::ModOrder($order);
+            }
+            $where .= " itemnumber = " . $item_number . " OR";
+        }
+        $where .= " itemnumber = " . @$items_number[0];
+
+        # Update reserves, hold_fill_targets, tmp_holdsqueue and linktracker tables
+        for my $table_name ( qw( reserves hold_fill_targets tmp_holdsqueue linktracker ) ) {
+            $dbh->do( qq|
+                UPDATE $table_name
+                SET biblionumber = $tobiblio
+                WHERE $where | );
+        }
+    }
+    return;
+}
+
 =head2 ItemSafeToDelete
 
    ItemSafeToDelete( $biblionumber, $itemnumber);
diff --git a/cataloguing/merge.pl b/cataloguing/merge.pl
index 146e88e..ff5304f 100755
--- a/cataloguing/merge.pl
+++ b/cataloguing/merge.pl
@@ -81,7 +81,6 @@ if ($merge) {
     $record->leader(GetMarcBiblio({ biblionumber => $ref_biblionumber })->leader());
 
     my $frameworkcode = $input->param('frameworkcode');
-    my @notmoveditems;
 
     # Modifying the reference record
     ModBiblio($record, $ref_biblionumber, $frameworkcode);
@@ -89,17 +88,12 @@ if ($merge) {
     # Moving items from the other record to the reference record
     foreach my $biblionumber (@biblionumbers) {
         my $items = Koha::Items->search({ biblionumber => $biblionumber });
+        my @items_number;
+
         while ( my $item = $items->next) {
-            my $res = MoveItemFromBiblio( $item->itemnumber, $biblionumber, $ref_biblionumber );
-            if ( not defined $res ) {
-                push @notmoveditems, $item->itemnumber;
-            }
+            push @items_number, $item->itemnumber;
         }
-    }
-    # If some items could not be moved :
-    if (scalar(@notmoveditems) > 0) {
-        my $itemlist = join(' ',@notmoveditems);
-        push @errors, { code => "CANNOT_MOVE", value => $itemlist };
+        C4::Items::MoveItemsFromBiblio(\@items_number, $biblionumber, $ref_biblionumber);
     }
 
     my $sth_subscription = $dbh->prepare("
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
index c21baca..f770cec 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
@@ -212,7 +212,7 @@ div#result { margin-top: 1em; }
                     'subfields': []
                 };
                 for (tag in tagslib) {
-                    if (tag == '000' || tag == '001')
+                    if (tag == '000' || tag == '001' || tag == '801')
                         continue;
                     if (tagslib[tag].mandatory == 1) {
                         if ($("#resultul span.field:contains("+ tag +")").length == 0) {
-- 
2.7.4