Bug 15381: Use Koha::Authority::Types in some other places
[koha.git] / C4 / AuthoritiesMarc.pm
index f316b17..c1e62aa 100644 (file)
@@ -3,18 +3,18 @@ package C4::AuthoritiesMarc;
 #
 # This file is part of Koha.
 #
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
 #
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use strict;
 use warnings;
@@ -26,7 +26,7 @@ use C4::AuthoritiesMarc::MARC21;
 use C4::AuthoritiesMarc::UNIMARC;
 use C4::Charset;
 use C4::Log;
-use Koha::Authority;
+use Koha::MetadataRecord::Authority;
 
 use vars qw($VERSION @ISA @EXPORT);
 
@@ -109,6 +109,7 @@ sub SearchAuthorities {
     my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby,$skipmetadata) = @_;
     # warn Dumper($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby);
     my $dbh=C4::Context->dbh;
+    $sortby="" unless $sortby;
     my $query;
     my $qpquery = '';
     my $QParser;
@@ -140,61 +141,68 @@ sub SearchAuthorities {
     my $and=" \@and " ;
     my $q2;
     my $attr_cnt = 0;
-    for(my $i = 0 ; $i <= $#{$value} ; $i++)
-    {
-        if (@$value[$i]){
-            if ( @$tags[$i] eq "mainmainentry" ) {
-                $attr = " \@attr 1=Heading-Main ";
-            }
-            elsif ( @$tags[$i] eq "mainentry" ) {
-                $attr = " \@attr 1=Heading ";
-            }
-            elsif ( @$tags[$i] eq "match" ) {
-                $attr = " \@attr 1=Match ";
-            }
-            elsif ( @$tags[$i] eq "match-heading" ) {
-                $attr = " \@attr 1=Match-heading ";
-            }
-            elsif ( @$tags[$i] eq "see-from" ) {
-                $attr = " \@attr 1=Match-heading-see-from ";
-            }
-            elsif ( @$tags[$i] eq "thesaurus" ) {
-                $attr = " \@attr 1=Subject-heading-thesaurus ";
-            }
-            else { # Assume any if no index was specified
+    for ( my $i = 0 ; $i <= $#{$value} ; $i++ ) {
+        if ( @$value[$i] ) {
+            if ( @$tags[$i] ) {
+                if ( @$tags[$i] eq "mainmainentry" ) {
+                    $attr = " \@attr 1=Heading-Main ";
+                }
+                elsif ( @$tags[$i] eq "mainentry" ) {
+                    $attr = " \@attr 1=Heading ";
+                }
+                elsif ( @$tags[$i] eq "match" ) {
+                    $attr = " \@attr 1=Match ";
+                }
+                elsif ( @$tags[$i] eq "match-heading" ) {
+                    $attr = " \@attr 1=Match-heading ";
+                }
+                elsif ( @$tags[$i] eq "see-from" ) {
+                    $attr = " \@attr 1=Match-heading-see-from ";
+                }
+                elsif ( @$tags[$i] eq "thesaurus" ) {
+                    $attr = " \@attr 1=Subject-heading-thesaurus ";
+                }
+                else {    # Assume any if no index was specified
+                    $attr = " \@attr 1=Any ";
+                }
+            }         #if @$tags[$i]
+            else {    # Assume any if no index was specified
                 $attr = " \@attr 1=Any ";
             }
-            if ( @$operator[$i] eq 'is' ) {
+
+            my $operator = @$operator[$i];
+            if ( $operator and $operator eq 'is' ) {
                 $attr .= " \@attr 4=1  \@attr 5=100 "
-                  ; ##Phrase, No truncation,all of subfield field must match
+                  ;    ##Phrase, No truncation,all of subfield field must match
             }
-            elsif ( @$operator[$i] eq "=" ) {
+            elsif ( $operator and $operator eq "=" ) {
                 $attr .= " \@attr 4=107 ";    #Number Exact match
             }
-            elsif ( @$operator[$i] eq "start" ) {
+            elsif ( $operator and $operator eq "start" ) {
                 $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
                   ;    #Firstinfield Phrase, Right truncated
             }
-            elsif ( @$operator[$i] eq "exact" ) {
+            elsif ( $operator and $operator eq "exact" ) {
                 $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
-                  ; ##Phrase, No truncation,all of subfield field must match
+                  ;    ##Phrase, No truncation,all of subfield field must match
             }
             else {
                 $attr .= " \@attr 5=1 \@attr 4=6 "
                   ;    ## Word list, right truncated, anywhere
-                  if ($sortby eq 'Relevance') {
-                      $attr .= "\@attr 2=102 ";
-                  }
+                if ( $sortby eq 'Relevance' ) {
+                    $attr .= "\@attr 2=102 ";
+                }
             }
-            @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
-            $attr =$attr."\"".@$value[$i]."\"";
-            $q2 .=$attr;
-            $dosearch=1;
+            @$value[$i] =~
+              s/"/\\"/g;    # Escape the double-quotes in the search value
+            $attr = $attr . "\"" . @$value[$i] . "\"";
+            $q2 .= $attr;
+            $dosearch = 1;
             ++$attr_cnt;
             if ($QParser) {
                 $qpquery .= " $tags->[$i]:\"$value->[$i]\"";
             }
-        }#if value
+        }    #if value
     }
     ##Add how many queries generated
     if (defined $query && $query=~/\S+/){
@@ -221,7 +229,7 @@ sub SearchAuthorities {
             $qpquery = $1;
         }
 
-        $qpquery .= " #$sortby";
+        $qpquery .= " #$sortby" unless $sortby eq '';
 
         $QParser->parse( $qpquery );
         $query = $QParser->target_syntax('authorityserver');
@@ -266,33 +274,39 @@ sub SearchAuthorities {
         
         ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
         my $rec=$oAResult->record($counter);
-        my $marcdata=$rec->raw();
-        my $authrecord;
-        my $separator=C4::Context->preference('authoritysep');
-        $authrecord = MARC::File::USMARC::decode($marcdata);
+        my $separator=C4::Context->preference('AuthoritySeparator');
+        my $authrecord = C4::Search::new_record_from_zebra(
+            'authorityserver',
+            $rec->raw()
+        );
+
+        if ( !defined $authrecord or !defined $authrecord->field('001') ) {
+            $counter++;
+            next;
+        }
+
+        SetUTF8Flag( $authrecord );
+
         my $authid=$authrecord->field('001')->data();
         my %newline;
         $newline{authid} = $authid;
         if ( !$skipmetadata ) {
-            my $summary =
-              BuildSummary( $authrecord, $authid, $authtypecode );
-            my $query_auth_tag =
-"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
-            my $sth = $dbh->prepare($query_auth_tag);
-            $sth->execute($authtypecode);
-            my $auth_tag_to_report = $sth->fetchrow;
+            my $auth_tag_to_report = Koha::Authority::Types->find($authtypecode)->auth_tag_to_report;
             my $reported_tag;
             my $mainentry = $authrecord->field($auth_tag_to_report);
             if ($mainentry) {
-
                 foreach ( $mainentry->subfields() ) {
                     $reported_tag .= '$' . $_->[0] . $_->[1];
                 }
             }
-            my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
+            my $thisauthtypecode = GetAuthTypeCode($authid);
+            my $thisauthtype = GetAuthType($thisauthtypecode);
             unless (defined $thisauthtype) {
-                $thisauthtype = GetAuthType($authtypecode) if $authtypecode;
+                $thisauthtypecode = $authtypecode;
+                $thisauthtype = GetAuthType($authtypecode);
             }
+            my $summary = BuildSummary( $authrecord, $authid, $thisauthtypecode );
+
             $newline{authtype}     = defined($thisauthtype) ?
                                         $thisauthtype->{'authtypetext'} : '';
             $newline{summary}      = $summary;
@@ -379,9 +393,9 @@ Get the record and tries to guess the adequate authtypecode from its content.
 =cut
 
 sub GuessAuthTypeCode {
-    my ($record) = @_;
+    my ($record, $heading_fields) = @_;
     return unless defined $record;
-my $heading_fields = {
+    $heading_fields //= {
     "MARC21"=>{
         '100'=>{authtypecode=>'PERSO_NAME'},
         '110'=>{authtypecode=>'CORPO_NAME'},
@@ -520,7 +534,7 @@ sub GetTagsLabels {
         $res->{$tag}->{repeatable} = $repeatable;
   }
   $sth=      $dbh->prepare(
-"SELECT tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,frameworkcode as authtypecode,value_builder,kohafield,seealso,hidden,isurl 
+"SELECT tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,frameworkcode as authtypecode,value_builder,kohafield,seealso,hidden,isurl,defaultvalue
 FROM auth_subfield_structure 
 WHERE authtypecode=? 
 ORDER BY tagfield,tagsubfield"
@@ -535,12 +549,13 @@ ORDER BY tagfield,tagsubfield"
     my $hidden;
     my $isurl;
     my $link;
+    my $defaultvalue;
 
     while (
         ( $tag,         $subfield,   $liblibrarian,   , $libopac,      $tab,
         $mandatory,     $repeatable, $authorised_value, $authtypecode,
         $value_builder, $kohafield,  $seealso,          $hidden,
-        $isurl,            $link )
+        $isurl,         $defaultvalue, $link )
         = $sth->fetchrow
       )
     {
@@ -556,6 +571,7 @@ ORDER BY tagfield,tagsubfield"
         $res->{$tag}->{$subfield}->{hidden}           = $hidden;
         $res->{$tag}->{$subfield}->{isurl}            = $isurl;
         $res->{$tag}->{$subfield}->{link}            = $link;
+        $res->{$tag}->{$subfield}->{defaultvalue}     = $defaultvalue;
     }
     return $res;
 }
@@ -737,7 +753,7 @@ sub ModAuthority {
        "VALUES (?,?)";
       $dbh->do($sqlinsert,undef,($authid,0));
   }
-  logaction( "AUTHORITIES", "MODIFY", $authid, "BEFORE=>" . $oldrecord->as_formatted ) if C4::Context->preference("AuthoritiesLog");
+  logaction( "AUTHORITIES", "MODIFY", $authid, "authority BEFORE=>" . $oldrecord->as_formatted ) if C4::Context->preference("AuthoritiesLog");
   return $authid;
 }
 
@@ -781,7 +797,7 @@ Returns MARC::Record of the authority passed in parameter.
 
 sub GetAuthority {
     my ($authid)=@_;
-    my $authority = Koha::Authority->get_from_authid($authid);
+    my $authority = Koha::MetadataRecord::Authority->get_from_authid($authid);
     return unless $authority;
     return ($authority->record);
 }
@@ -828,10 +844,7 @@ sub FindDuplicateAuthority {
 #    warn "IN for ".$record->as_formatted;
     my $dbh = C4::Context->dbh;
 #    warn "".$record->as_formatted;
-    my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?");
-    $sth->execute($authtypecode);
-    my ($auth_tag_to_report) = $sth->fetchrow;
-    $sth->finish;
+    my $auth_tag_to_report = Koha::Authority::Types->find($authtypecode)->auth_tag_to_report;
 #     warn "record :".$record->as_formatted."  auth_tag_to_report :$auth_tag_to_report";
     # build a request for SearchAuthorities
     my $QParser;
@@ -843,17 +856,20 @@ sub FindDuplicateAuthority {
         $op = 'and';
     }
     my $query='at:'.$authtypecode.' ';
-    my $filtervalues=qr([\001-\040\!\'\"\`\#\$\%\&\*\+,\-\./:;<=>\?\@\(\)\{\[\]\}_\|\~]);
+    my $filtervalues=qr([\001-\040\Q!'"`#$%&*+,-./:;<=>?@(){[}_|~\E\]]);
     if ($record->field($auth_tag_to_report)) {
-      foreach ($record->field($auth_tag_to_report)->subfields()) {
-        $_->[1]=~s/$filtervalues/ /g; $query.= " $op he:\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/);
-      }
+        foreach ($record->field($auth_tag_to_report)->subfields()) {
+            $_->[1]=~s/$filtervalues/ /g; $query.= " $op he:\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/);
+        }
     }
     my ($error, $results, $total_hits) = C4::Search::SimpleSearch( $query, 0, 1, [ "authorityserver" ] );
     # there is at least 1 result => return the 1st one
     if (!defined $error && @{$results} ) {
-      my $marcrecord = MARC::File::USMARC::decode($results->[0]);
-      return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode);
+        my $marcrecord = C4::Search::new_record_from_zebra(
+            'authorityserver',
+            $results->[0]
+        );
+        return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode);
     }
     # no result, returns nothing
     return;
@@ -865,7 +881,7 @@ sub FindDuplicateAuthority {
 
 Returns a hashref with a summary of the specified record.
 
-Comment : authtypecode can be infered from both record and authid.
+Comment : authtypecode can be inferred from both record and authid.
 Moreover, authid can also be inferred from $record.
 Would it be interesting to delete those things.
 
@@ -876,12 +892,20 @@ sub BuildSummary {
     my ($record,$authid,$authtypecode)=@_;
     my $dbh=C4::Context->dbh;
     my %summary;
+    my $summary_template;
     # handle $authtypecode is NULL or eq ""
     if ($authtypecode) {
         my $authref = GetAuthType($authtypecode);
         $summary{authtypecode} = $authref->{authtypecode};
         $summary{type} = $authref->{authtypetext};
-        $summary{summary} = $authref->{summary};
+        $summary_template = $authref->{summary};
+        # for MARC21, the authority type summary displays a label meant for
+        # display
+        if (C4::Context->preference('marcflavour') ne 'UNIMARC') {
+            $summary{label} = $authref->{summary};
+        } else {
+            $summary{summary} = $authref->{summary};
+        }
     }
     my $marc21subfields = 'abcdfghjklmnopqrstuvxyz68';
     my %marc21controlrefs = ( 'a' => 'earlier',
@@ -915,34 +939,36 @@ sub BuildSummary {
 #         feature will be enabled only for UNIMARC for backwards
 #         compatibility.
     if ($summary{summary} and C4::Context->preference('marcflavour') eq 'UNIMARC') {
-        my @fields = $record->fields();
-#             $reported_tag = '$9'.$result[$counter];
-        my @stringssummary;
-        foreach my $field (@fields) {
-            my $tag = $field->tag();
-            my $tagvalue = $field->as_string();
-            my $localsummary= $summary{summary};
-            $localsummary =~ s/\[(.?.?.?.?)$tag\*(.*?)\]/$1$tagvalue$2\[$1$tag$2\]/g;
-            if ($tag<10) {
-                if ($tag eq '001') {
-                    $reported_tag.='$3'.$field->data();
-                }
-            } else {
-                my @subf = $field->subfields;
-                for my $i (0..$#subf) {
-                    my $subfieldcode = $subf[$i][0];
-                    my $subfieldvalue = $subf[$i][1];
-                    my $tagsubf = $tag.$subfieldcode;
-                    $localsummary =~ s/\[(.?.?.?.?)$tagsubf(.*?)\]/$1$subfieldvalue$2\[$1$tagsubf$2\]/g;
+        my @matches = ($summary{summary} =~ m/\[(.*?)(\d{3})([\*a-z0-9])(.*?)\]/g);
+        my (@textbefore, @tag, @subtag, @textafter);
+        for(my $i = 0; $i < scalar @matches; $i++){
+            push @textbefore, $matches[$i] if($i%4 == 0);
+            push @tag,        $matches[$i] if($i%4 == 1);
+            push @subtag,     $matches[$i] if($i%4 == 2);
+            push @textafter,  $matches[$i] if($i%4 == 3);
+        }
+        for(my $i = scalar @tag; $i >= 0; $i--){
+            my $textbefore = $textbefore[$i] || '';
+            my $tag = $tag[$i] || '';
+            my $subtag = $subtag[$i] || '';
+            my $textafter = $textafter[$i] || '';
+            my $value = '';
+            my $field = $record->field($tag);
+            if ( $field ) {
+                if($subtag eq '*') {
+                    if($tag < 10) {
+                        $value = $textbefore . $field->data() . $textafter;
+                    }
+                } else {
+                    my @subfields = $field->subfield($subtag);
+                    if(@subfields > 0) {
+                        $value = $textbefore . join (" - ", @subfields) . $textafter;
+                    }
                 }
             }
-            push @stringssummary, $localsummary if ($localsummary ne $summary{summary});
+            $summary{summary} =~ s/\[\Q$textbefore$tag$subtag$textafter\E\]/$value/;
         }
-        my $resultstring;
-        $resultstring = join(" -- ",@stringssummary);
-        $resultstring =~ s/\[(.*?)\]//g;
-        $resultstring =~ s/\n/<br>/g;
-        $summary{summary}      =  $resultstring;
+        $summary{summary} =~ s/\\n/<br \/>/g;
     }
     my @authorized;
     my @notes;
@@ -953,7 +979,11 @@ sub BuildSummary {
 # construct UNIMARC summary, that is quite different from MARC21 one
 # accepted form
         foreach my $field ($record->field('2..')) {
-            push @authorized, { heading => $field->as_string('abcdefghijlmnopqrstuvwxyz'), field => $field->tag() };
+            push @authorized, {
+                heading => $field->as_string('abcdefghijlmnopqrstuvwxyz'),
+                hemain  => ( $field->subfield('a') // undef ),
+                field   => $field->tag(),
+            };
         }
 # rejected form(s)
         foreach my $field ($record->field('3..')) {
@@ -961,7 +991,12 @@ sub BuildSummary {
         }
         foreach my $field ($record->field('4..')) {
             my $thesaurus = $field->subfield('2') ? "thes. : ".$thesaurus{"$field->subfield('2')"}." : " : '';
-            push @seefrom, { heading => $thesaurus . $field->as_string('abcdefghijlmnopqrstuvwxyz'), type => 'seefrom', field => $field->tag() };
+            push @seefrom, {
+                heading => $thesaurus . $field->as_string('abcdefghijlmnopqrstuvwxyz'),
+                hemain  => ( $field->subfield('a') // undef ),
+                type    => 'seefrom',
+                field   => $field->tag(),
+            };
         }
 
         # see :
@@ -972,15 +1007,16 @@ sub BuildSummary {
                 field   => $_->tag,
                 type    => $type,
                 heading => $heading,
+                hemain  => ( $_->subfield('a') // undef ),
                 search  => $heading,
-                authid  => $_->subfield('9'),
+                authid  => ( $_->subfield('9') // undef ),
             }
         } $record->field('5..');
 
         # Other forms
         @otherscript = map { {
-            lang      => $_->subfield('8') || '',
-            term      => $_->subfield('a'),
+            lang      => length ($_->subfield('8')) == 6 ? substr ($_->subfield('8'), 3, 3) : $_->subfield('8') || '',
+            term      => $_->subfield('a') . ($_->subfield('b') ? ', ' . $_->subfield('b') : ''),
             direction => 'ltr',
             field     => $_->tag,
         } } $record->field('7..');
@@ -1022,9 +1058,17 @@ sub BuildSummary {
                 $subfields_to_report = 'vxyz';
             }
             if ($subfields_to_report) {
-                push @authorized, { heading => $field->as_string($subfields_to_report), field => $tag };
+                push @authorized, {
+                    heading => $field->as_string($subfields_to_report),
+                    hemain  => ( $field->subfield( substr($subfields_to_report, 0, 1) ) // undef ),
+                    field   => $tag,
+                };
             } else {
-                push @authorized, { heading => $field->as_string(), field => $tag };
+                push @authorized, {
+                    heading => $field->as_string(),
+                    hemain  => ( $field->subfield( 'a' ) // undef ),
+                    field   => $tag,
+                };
             }
         }
         foreach my $field ($record->field('4..')) { #See From
@@ -1035,9 +1079,19 @@ sub BuildSummary {
                 $type = 'earlier' if $type && $type ne 'n';
             }
             if ($type eq 'subfi') {
-                push @seefrom, { heading => $field->as_string($marc21subfields), type => ($field->subfield('i') || ''), field => $field->tag() };
+                push @seefrom, {
+                    heading => $field->as_string($marc21subfields),
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => ($field->subfield('i') || ''),
+                    field   => $field->tag(),
+                };
             } else {
-                push @seefrom, { heading => $field->as_string($marc21subfields), type => $type, field => $field->tag() };
+                push @seefrom, {
+                    heading => $field->as_string($marc21subfields),
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => $type,
+                    field   => $field->tag(),
+                };
             }
         }
         foreach my $field ($record->field('5..')) { #See Also
@@ -1050,18 +1104,20 @@ sub BuildSummary {
             if ($type eq 'subfi') {
                 push @seealso, {
                     heading => $field->as_string($marc21subfields),
-                    type => $field->subfield('i'),
-                    field => $field->tag(),
-                    search => $field->as_string($marc21subfields) || '',
-                    authid => $field->subfield('9') || ''
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => $field->subfield('i'),
+                    field   => $field->tag(),
+                    search  => $field->as_string($marc21subfields) || '',
+                    authid  => $field->subfield('9') || ''
                 };
             } else {
                 push @seealso, {
                     heading => $field->as_string($marc21subfields),
-                    type => $type,
-                    field => $field->tag(),
-                    search => $field->as_string($marc21subfields) || '',
-                    authid => $field->subfield('9') || ''
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => $type,
+                    field   => $field->tag(),
+                    search  => $field->as_string($marc21subfields) || '',
+                    authid  => $field->subfield('9') || ''
                 };
             }
         }
@@ -1089,6 +1145,7 @@ sub BuildSummary {
         }
     }
     $summary{mainentry} = $authorized[0]->{heading};
+    $summary{mainmainentry} = $authorized[0]->{hemain};
     $summary{authorized} = \@authorized;
     $summary{notes} = \@notes;
     $summary{seefrom} = \@seefrom;
@@ -1392,12 +1449,9 @@ sub merge {
     return "error MARCFROM not a marcrecord ".Data::Dumper::Dumper($MARCfrom) if scalar($MARCfrom->fields()) == 0;
     return "error MARCTO not a marcrecord".Data::Dumper::Dumper($MARCto) if scalar($MARCto->fields()) == 0;
     # search the tag to report
-    my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?");
-    $sth->execute($authtypecodefrom);
-    my ($auth_tag_to_report_from) = $sth->fetchrow;
-    $sth->execute($authtypecodeto);
-    my ($auth_tag_to_report_to) = $sth->fetchrow;
-    
+    my $auth_tag_to_report_from = Koha::Authority::Types->find($authtypecodefrom)->auth_tag_to_report;
+    my $auth_tag_to_report_to = Koha::Authority::Types->find($authtypecodeto)->auth_tag_to_report;
+
     my @record_to;
     @record_to = $MARCto->field($auth_tag_to_report_to)->subfields() if $MARCto->field($auth_tag_to_report_to);
     my @record_from;
@@ -1419,13 +1473,15 @@ sub merge {
     }
     my $z=0;
     while ( $z<$count ) {
-        my $rec;
-        $rec=$oResult->record($z);
-        my $marcdata = $rec->raw();
-        my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
+        my $marcrecordzebra = C4::Search::new_record_from_zebra(
+            'biblioserver',
+            $oResult->record($z)->raw()
+        );
         my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
-        my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
-        my $marcrecorddb=GetMarcBiblio($i);
+        my $i = ($biblionumbertagfield < 10)
+            ? $marcrecordzebra->field( $biblionumbertagfield )->data
+            : $marcrecordzebra->subfield( $biblionumbertagfield, $biblionumbertagsubfield );
+        my $marcrecorddb = GetMarcBiblio($i);
         push @reccache, $marcrecorddb;
         $z++;
     }
@@ -1433,7 +1489,7 @@ sub merge {
     #warn scalar(@reccache)." biblios to update";
     # Get All candidate Tags for the change 
     # (This will reduce the search scope in marc records).
-    $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?");
+    my $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?");
     $sth->execute($authtypecodefrom);
     my @tags_using_authtype;
     while (my ($tagfield) = $sth->fetchrow) {
@@ -1449,7 +1505,7 @@ sub merge {
     # BulkEdit marc records
     # May be used as a template for a bulkedit field  
     foreach my $marcrecord(@reccache){
-        my $update;           
+        my $update = 0;
         foreach my $tagfield (@tags_using_authtype){
 #             warn "tagfield : $tagfield ";
             foreach my $field ($marcrecord->field($tagfield)){