Merge remote branch 'kc/new/enh/bug_5462' into kcmaster
[koha_fer] / cataloguing / addbiblio.pl
index a4f0cfa..da58166 100755 (executable)
@@ -1,8 +1,8 @@
 #!/usr/bin/perl 
 
 #!/usr/bin/perl 
 
-# $Id$
 
 # Copyright 2000-2002 Katipo Communications
 
 # Copyright 2000-2002 Katipo Communications
+# Copyright 2004-2010 BibLibre
 #
 # This file is part of Koha.
 #
 #
 # This file is part of Koha.
 #
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 #
 # 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., 59 Temple Place,
-# Suite 330, Boston, MA  02111-1307 USA
+# 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.
 
 use strict;
 
 use strict;
+#use warnings; FIXME - Bug 2505
 use CGI;
 use C4::Output;
 use C4::Auth;
 use CGI;
 use C4::Output;
 use C4::Auth;
@@ -30,6 +31,11 @@ use C4::Context;
 use MARC::Record;
 use C4::Log;
 use C4::Koha;    # XXX subfield_is_koha_internal_p
 use MARC::Record;
 use C4::Log;
 use C4::Koha;    # XXX subfield_is_koha_internal_p
+use C4::Branch;    # XXX subfield_is_koha_internal_p
+use C4::ClassSource;
+use C4::ImportBatch;
+use C4::Charset;
+
 use Date::Calc qw(Today);
 use MARC::File::USMARC;
 use MARC::File::XML;
 use Date::Calc qw(Today);
 use MARC::File::USMARC;
 use MARC::File::XML;
@@ -40,11 +46,13 @@ if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
 
 our($tagslib,$authorised_values_sth,$is_a_modif,$usedTagsLib,$mandatory_z3950);
 
 
 our($tagslib,$authorised_values_sth,$is_a_modif,$usedTagsLib,$mandatory_z3950);
 
-=item MARCfindbreeding
+=head1 FUNCTIONS
+
+=head2 MARCfindbreeding
 
 
-    $record = MARCfindbreeding($dbh, $breedingid);
+    $record = MARCfindbreeding($breedingid);
 
 
-Look up the breeding farm with database handle $dbh, for the
+Look up the import record repository for the record with
 record with id $breedingid.  If found, returns the decoded
 MARC::Record; otherwise, -1 is returned (FIXME).
 Returns as second parameter the character encoding.
 record with id $breedingid.  If found, returns the decoded
 MARC::Record; otherwise, -1 is returned (FIXME).
 Returns as second parameter the character encoding.
@@ -52,25 +60,23 @@ Returns as second parameter the character encoding.
 =cut
 
 sub MARCfindbreeding {
 =cut
 
 sub MARCfindbreeding {
-    my ( $dbh, $id ) = @_;
-    my $sth =
-      $dbh->prepare("select file,marc,encoding from marc_breeding where id=?");
-    $sth->execute($id);
-    my ( $file, $marc, $encoding ) = $sth->fetchrow;
+    my ( $id ) = @_;
+    my ($marc, $encoding) = GetImportRecordMarc($id);
+    # remove the - in isbn, koha store isbn without any -
     if ($marc) {
         my $record = MARC::Record->new_from_usmarc($marc);
     if ($marc) {
         my $record = MARC::Record->new_from_usmarc($marc);
-        if ( $record->field('010') ) {
-            foreach my $field ( $record->field('010') ) {
-                foreach my $subfield ( $field->subfield('a') ) {
-                    my $newisbn = $field->subfield('a');
+        my ($isbnfield,$isbnsubfield) = GetMarcFromKohaField('biblioitems.isbn','');
+        if ( $record->field($isbnfield) ) {
+            foreach my $field ( $record->field($isbnfield) ) {
+                foreach my $subfield ( $field->subfield($isbnsubfield) ) {
+                    my $newisbn = $field->subfield($isbnsubfield);
                     $newisbn =~ s/-//g;
                     $newisbn =~ s/-//g;
-                    $field->update( 'a' => $newisbn );
+                    $field->update( $isbnsubfield => $newisbn );
                 }
                 }
-                # record->insert_fields_ordered($record->field('010'));
             }
         }
             }
         }
-
-        if ($record->subfield(100,'a')) {
+        # fix the unimarc 100 coded field (with unicode information)
+        if (C4::Context->preference('marcflavour') eq 'UNIMARC' && $record->subfield(100,'a')) {
             my $f100a=$record->subfield(100,'a');
             my $f100 = $record->field(100);
             my $f100temp = $f100->as_string;
             my $f100a=$record->subfield(100,'a');
             my $f100 = $record->field(100);
             my $f100temp = $f100->as_string;
@@ -83,14 +89,15 @@ sub MARCfindbreeding {
             }
         }
                
             }
         }
                
-        if ( ref($record) eq undef ) {
+        if ( !defined(ref($record)) ) {
             return -1;
         }
         else {
             return -1;
         }
         else {
+            # normalize author : probably UNIMARC specific...
             if (    C4::Context->preference("z3950NormalizeAuthor")
                 and C4::Context->preference("z3950AuthorAuthFields") )
             {
             if (    C4::Context->preference("z3950NormalizeAuthor")
                 and C4::Context->preference("z3950AuthorAuthFields") )
             {
-                my ( $tag, $subfield ) = GetMarcFromKohaField("biblio.author");
+                my ( $tag, $subfield ) = GetMarcFromKohaField("biblio.author", '');
 
  #                 my $summary = C4::Context->preference("z3950authortemplate");
                 my $auth_fields =
 
  #                 my $summary = C4::Context->preference("z3950authortemplate");
                 my $auth_fields =
@@ -148,7 +155,7 @@ sub MARCfindbreeding {
     return -1;
 }
 
     return -1;
 }
 
-=item build_authorized_values_list
+=head2 build_authorized_values_list
 
 =cut
 
 
 =cut
 
@@ -162,16 +169,16 @@ sub build_authorized_values_list ($$$$$$$) {
 
     #---- branch
     if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
 
     #---- branch
     if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
-        my $sth =
-          $dbh->prepare(
-            "select branchcode,branchname from branches order by branchname");
-        $sth->execute;
-        push @authorised_values, ""
-          unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
-
-        while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) {
-            push @authorised_values, $branchcode;
-            $authorised_lib{$branchcode} = $branchname;
+        #Use GetBranches($onlymine)
+        my $onlymine=C4::Context->preference('IndependantBranches') && 
+                C4::Context->userenv && 
+                C4::Context->userenv->{flags} % 2 == 0 && 
+                C4::Context->userenv->{branch};
+        my $branches = GetBranches($onlymine);
+        my @branchloop;
+        foreach my $thisbranch ( sort keys %$branches ) {
+            push @authorised_values, $thisbranch;
+            $authorised_lib{$thisbranch} = $branches->{$thisbranch}->{'branchname'};
         }
 
         #----- itemtypes
         }
 
         #----- itemtypes
@@ -192,6 +199,25 @@ sub build_authorized_values_list ($$$$$$$) {
         }
         $value = $itemtype unless ($value);
 
         }
         $value = $itemtype unless ($value);
 
+          #---- class_sources
+    }
+    elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
+        push @authorised_values, ""
+          unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
+
+        my $class_sources = GetClassSources();
+
+        my $default_source = C4::Context->preference("DefaultClassificationSource");
+
+        foreach my $class_source (sort keys %$class_sources) {
+            next unless $class_sources->{$class_source}->{'used'} or
+                        ($value and $class_source eq $value) or
+                        ($class_source eq $default_source);
+            push @authorised_values, $class_source;
+            $authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'};
+            $value = $class_source unless ($value);
+            $value = $default_source unless ($value);
+        }
         #---- "true" authorised value
     }
     else {
         #---- "true" authorised value
     }
     else {
@@ -220,7 +246,7 @@ sub build_authorized_values_list ($$$$$$$) {
     );
 }
 
     );
 }
 
-=item CreateKey
+=head2 CreateKey
 
     Create a random value to set it into the input name
 
 
     Create a random value to set it into the input name
 
@@ -230,11 +256,11 @@ sub CreateKey(){
     return int(rand(1000000));
 }
 
     return int(rand(1000000));
 }
 
-=item GetMandatoryFieldZ3950
+=head2 GetMandatoryFieldZ3950
 
     This function return an hashref which containts all mandatory field
     to search with z3950 server.
 
     This function return an hashref which containts all mandatory field
     to search with z3950 server.
-    
+
 =cut
 
 sub GetMandatoryFieldZ3950($){
 =cut
 
 sub GetMandatoryFieldZ3950($){
@@ -243,16 +269,18 @@ sub GetMandatoryFieldZ3950($){
     my @title  = GetMarcFromKohaField('biblio.title',$frameworkcode);
     my @author = GetMarcFromKohaField('biblio.author',$frameworkcode);
     my @issn   = GetMarcFromKohaField('biblioitems.issn',$frameworkcode);
     my @title  = GetMarcFromKohaField('biblio.title',$frameworkcode);
     my @author = GetMarcFromKohaField('biblio.author',$frameworkcode);
     my @issn   = GetMarcFromKohaField('biblioitems.issn',$frameworkcode);
+    my @lccn   = GetMarcFromKohaField('biblioitems.lccn',$frameworkcode);
     
     return {
         $isbn[0].$isbn[1]     => 'isbn',
         $title[0].$title[1]   => 'title',
         $author[0].$author[1] => 'author',
         $issn[0].$issn[1]     => 'issn',
     
     return {
         $isbn[0].$isbn[1]     => 'isbn',
         $title[0].$title[1]   => 'title',
         $author[0].$author[1] => 'author',
         $issn[0].$issn[1]     => 'issn',
+        $lccn[0].$lccn[1]     => 'lccn',
     };
 }
 
     };
 }
 
-=item create_input
+=head2 create_input
 
  builds the <input ...> entry for a subfield.
 
 
  builds the <input ...> entry for a subfield.
 
@@ -265,8 +293,16 @@ sub create_input {
 
     $value =~ s/"/&quot;/g;
 
 
     $value =~ s/"/&quot;/g;
 
+    # determine maximum length; 9999 bytes per ISO 2709 except for leader and MARC21 008
+    my $max_length = 9999;
+    if ($tag eq '000') {
+        $max_length = 24;
+    } elsif ($tag eq '008' and C4::Context->preference('marcflavour') eq 'MARC21')  {
+        $max_length = 40;
+    }
+
     # if there is no value provided but a default value in parameters, get it
     # if there is no value provided but a default value in parameters, get it
-    unless ($value) {
+    if ( $value eq '' ) {
         $value = $tagslib->{$tag}->{$subfield}->{defaultvalue};
 
         # get today date & replace YYYY, MM, DD if provided in the default value
         $value = $tagslib->{$tag}->{$subfield}->{defaultvalue};
 
         # get today date & replace YYYY, MM, DD if provided in the default value
@@ -276,11 +312,20 @@ sub create_input {
         $value =~ s/YYYY/$year/g;
         $value =~ s/MM/$month/g;
         $value =~ s/DD/$day/g;
         $value =~ s/YYYY/$year/g;
         $value =~ s/MM/$month/g;
         $value =~ s/DD/$day/g;
+        my $username=(C4::Context->userenv?C4::Context->userenv->{'surname'}:"superlibrarian");    
+        $value=~s/user/$username/g;
+    
     }
     my $dbh = C4::Context->dbh;
     }
     my $dbh = C4::Context->dbh;
+
+    # map '@' as "subfield" label for fixed fields
+    # to something that's allowed in a div id.
+    my $id_subfield = $subfield;
+    $id_subfield = "00" if $id_subfield eq "@";
+
     my %subfield_data = (
         tag        => $tag,
     my %subfield_data = (
         tag        => $tag,
-        subfield   => $subfield,
+        subfield   => $id_subfield,
         marc_lib   => substr( $tagslib->{$tag}->{$subfield}->{lib}, 0, 22 ),
         marc_lib_plain => $tagslib->{$tag}->{$subfield}->{lib}, 
         tag_mandatory  => $tagslib->{$tag}->{mandatory},
         marc_lib   => substr( $tagslib->{$tag}->{$subfield}->{lib}, 0, 22 ),
         marc_lib_plain => $tagslib->{$tag}->{$subfield}->{lib}, 
         tag_mandatory  => $tagslib->{$tag}->{mandatory},
@@ -288,44 +333,79 @@ sub create_input {
         repeatable     => $tagslib->{$tag}->{$subfield}->{repeatable},
         kohafield      => $tagslib->{$tag}->{$subfield}->{kohafield},
         index          => $index_tag,
         repeatable     => $tagslib->{$tag}->{$subfield}->{repeatable},
         kohafield      => $tagslib->{$tag}->{$subfield}->{kohafield},
         index          => $index_tag,
-        id             => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
+        id             => "tag_".$tag."_subfield_".$id_subfield."_".$index_tag."_".$index_subfield,
         value          => $value,
         value          => $value,
+        random         => CreateKey(),
     );
     );
-    if($subfield eq '@'){
-        $subfield_data{id} = "tag_".$tag."_subfield_00_".$index_tag."_".$index_subfield;
-    } else {
-         $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield;
-    }
 
     if(exists $mandatory_z3950->{$tag.$subfield}){
         $subfield_data{z3950_mandatory} = $mandatory_z3950->{$tag.$subfield};
     }
 
     if(exists $mandatory_z3950->{$tag.$subfield}){
         $subfield_data{z3950_mandatory} = $mandatory_z3950->{$tag.$subfield};
     }
-    
+    # decide if the subfield must be expanded (visible) by default or not
+    # if it is mandatory, then expand. If it is hidden explicitly by the hidden flag, hidden anyway
     $subfield_data{visibility} = "display:none;"
         if (    ($tagslib->{$tag}->{$subfield}->{hidden} % 2 == 1) and $value ne ''
             or ($value eq '' and !$tagslib->{$tag}->{$subfield}->{mandatory})
         );
     $subfield_data{visibility} = "display:none;"
         if (    ($tagslib->{$tag}->{$subfield}->{hidden} % 2 == 1) and $value ne ''
             or ($value eq '' and !$tagslib->{$tag}->{$subfield}->{mandatory})
         );
-    
+    # always expand all subfields of a mandatory field
+    $subfield_data{visibility} = "" if $tagslib->{$tag}->{mandatory};
     # it's an authorised field
     if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
         $subfield_data{marc_value} =
           build_authorized_values_list( $tag, $subfield, $value, $dbh,
             $authorised_values_sth,$index_tag,$index_subfield );
 
     # it's an authorised field
     if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
         $subfield_data{marc_value} =
           build_authorized_values_list( $tag, $subfield, $value, $dbh,
             $authorised_values_sth,$index_tag,$index_subfield );
 
+    # it's a subfield $9 linking to an authority record - see bug 2206
+    }
+    elsif ($subfield eq "9" and
+           exists($tagslib->{$tag}->{'a'}->{authtypecode}) and
+           defined($tagslib->{$tag}->{'a'}->{authtypecode}) and
+           $tagslib->{$tag}->{'a'}->{authtypecode} ne '') {
+
+        $subfield_data{marc_value} =
+            "<input type=\"text\"
+                    id=\"".$subfield_data{id}."\"
+                    name=\"".$subfield_data{id}."\"
+                    value=\"$value\"
+                    class=\"input_marceditor readonly\"
+                    tabindex=\"1\"
+                    size=\"5\"
+                    maxlength=\"$max_length\"
+                    readonly=\"readonly\"
+                    \/>";
+
     # it's a thesaurus / authority field
     }
     elsif ( $tagslib->{$tag}->{$subfield}->{authtypecode} ) {
     # it's a thesaurus / authority field
     }
     elsif ( $tagslib->{$tag}->{$subfield}->{authtypecode} ) {
+     if (C4::Context->preference("BiblioAddsAuthorities")) {
+        $subfield_data{marc_value} =
+            "<input type=\"text\"
+                    id=\"".$subfield_data{id}."\"
+                    name=\"".$subfield_data{id}."\"
+                    value=\"$value\"
+                    class=\"input_marceditor readonly\"
+                    tabindex=\"1\"
+                    size=\"67\"
+                    maxlength=\"$max_length\"
+                    \/>
+                    <a href=\"#\" class=\"buttonDot\"
+                        onclick=\"openAuth(this.parentNode.getElementsByTagName('input')[1].id,'".$tagslib->{$tag}->{$subfield}->{authtypecode}."'); return false;\" tabindex=\"1\" title=\"Tag Editor\">...</a>
+            ";
+      } else {
         $subfield_data{marc_value} =
         $subfield_data{marc_value} =
-               "<input type=\"text\"
-                        id=".$subfield_data{id}."
-                        name=".$subfield_data{id}."
-                       value=\"$value\"
-                       class=\"input_marceditor\"
-                        tabindex=\"1\"                     
-                       DISABLE READONLY \/>
-                       <span class=\"buttonDot\"
-                               onclick=\"Dopop('/cgi-bin/koha/authorities/auth_finder.pl?authtypecode=".$tagslib->{$tag}->{$subfield}->{authtypecode}."&index=$subfield_data{id}','$subfield_data{id}')\">...</span>
-               ";
+            "<input type=\"text\"
+                    id=\"".$subfield_data{id}."\"
+                    name=\"".$subfield_data{id}."\"
+                    value=\"$value\"
+                    class=\"input_marceditor readonly\"
+                    tabindex=\"1\"
+                    size=\"67\"
+                    maxlength=\"$max_length\"
+                    readonly=\"readonly\"
+                    \/><a href=\"#\" class=\"buttonDot\"
+                        onclick=\"openAuth(this.parentNode.getElementsByTagName('input')[1].id,'".$tagslib->{$tag}->{$subfield}->{authtypecode}."'); return false;\" tabindex=\"1\" title=\"Tag Editor\">...</a>
+            ";
+      }
     # it's a plugin field
     }
     elsif ( $tagslib->{$tag}->{$subfield}->{'value_builder'} ) {
     # it's a plugin field
     }
     elsif ( $tagslib->{$tag}->{$subfield}->{'value_builder'} ) {
@@ -335,44 +415,63 @@ sub create_input {
         my $cgidir = C4::Context->intranetdir . "/cgi-bin/cataloguing/value_builder";
         unless ( opendir( DIR, "$cgidir" ) ) {
             $cgidir = C4::Context->intranetdir . "/cataloguing/value_builder";
         my $cgidir = C4::Context->intranetdir . "/cgi-bin/cataloguing/value_builder";
         unless ( opendir( DIR, "$cgidir" ) ) {
             $cgidir = C4::Context->intranetdir . "/cataloguing/value_builder";
+            closedir( DIR );
         }
         my $plugin = $cgidir . "/" . $tagslib->{$tag}->{$subfield}->{'value_builder'};
         }
         my $plugin = $cgidir . "/" . $tagslib->{$tag}->{$subfield}->{'value_builder'};
+        if (do $plugin) {
+            my $extended_param = plugin_parameters( $dbh, $rec, $tagslib, $subfield_data{id}, $tabloop );
+            my ( $function_name, $javascript ) = plugin_javascript( $dbh, $rec, $tagslib, $subfield_data{id}, $tabloop );
         
         
-        do $plugin;
-        my $extended_param = plugin_parameters( $dbh, $rec, $tagslib, $subfield_data{id}, $tabloop );
-        my ( $function_name, $javascript ) = plugin_javascript( $dbh, $rec, $tagslib, $subfield_data{id}, $tabloop );
-#         my ( $function_name, $javascript,$extended_param );
-        
-        $subfield_data{marc_value} =
-               "<input tabindex=\"1\"
-                        type=\"text\"
-                        id=".$subfield_data{id}."
-                       name=".$subfield_data{id}."
-                       value=\"$value\"
+            $subfield_data{marc_value} =
+                    "<input tabindex=\"1\"
+                            type=\"text\"
+                            id=\"".$subfield_data{id}."\"
+                            name=\"".$subfield_data{id}."\"
+                            value=\"$value\"
+                            class=\"input_marceditor\"
+                            onfocus=\"Focus$function_name($index_tag)\"
+                            size=\"67\"
+                            maxlength=\"$max_length\"
+                            onblur=\"Blur$function_name($index_tag); \" \/>
+                            <a href=\"#\" class=\"buttonDot\" onclick=\"Clic$function_name('$subfield_data{id}'); return false;\" tabindex=\"1\" title=\"Tag Editor\">...</a>
+                    $javascript";
+        } else {
+            warn "Plugin Failed: $plugin";
+            # supply default input form
+            $subfield_data{marc_value} =
+                "<input type=\"text\"
+                        id=\"".$subfield_data{id}."\"
+                        name=\"".$subfield_data{id}."\"
+                        value=\"$value\"
+                        tabindex=\"1\"
+                        size=\"67\"
+                        maxlength=\"$max_length\"
                         class=\"input_marceditor\"
                         class=\"input_marceditor\"
-                       onfocus=\"javascript:Focus$function_name($index_tag)\"
-                       onblur=\"javascript:Blur$function_name($index_tag); \" \/>
-               <span class=\"buttonDot\"
-                       onclick=\"Clic$function_name('$subfield_data{id}')\">...</a>
-               $javascript";
+                \/>
+                ";
+        }
         # it's an hidden field
     }
     elsif ( $tag eq '' ) {
         $subfield_data{marc_value} =
             "<input tabindex=\"1\"
                     type=\"hidden\"
         # it's an hidden field
     }
     elsif ( $tag eq '' ) {
         $subfield_data{marc_value} =
             "<input tabindex=\"1\"
                     type=\"hidden\"
-                    id=".$subfield_data{id}."
-                    name=".$subfield_data{id}."
+                    id=\"".$subfield_data{id}."\"
+                    name=\"".$subfield_data{id}."\"
+                    size=\"67\"
+                    maxlength=\"$max_length\"
                     value=\"$value\" \/>
             ";
     }
     elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) {
         $subfield_data{marc_value} =
             "<input type=\"text\"
                     value=\"$value\" \/>
             ";
     }
     elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) {
         $subfield_data{marc_value} =
             "<input type=\"text\"
-                    id=".$subfield_data{id}."
-                    name=".$subfield_data{id}."
+                    id=\"".$subfield_data{id}."\"
+                    name=\"".$subfield_data{id}."\"
                     class=\"input_marceditor\"
                     tabindex=\"1\"
                     class=\"input_marceditor\"
                     tabindex=\"1\"
+                    size=\"67\"
+                    maxlength=\"$max_length\"
                     value=\"$value\"
             \/>";
 
                     value=\"$value\"
             \/>";
 
@@ -392,8 +491,8 @@ sub create_input {
             $subfield_data{marc_value} =
                 "<textarea cols=\"70\"
                            rows=\"4\"
             $subfield_data{marc_value} =
                 "<textarea cols=\"70\"
                            rows=\"4\"
-                           id=".$subfield_data{id}."
-                           name=".$subfield_data{id}."
+                           id=\"".$subfield_data{id}."\"
+                           name=\"".$subfield_data{id}."\"
                            class=\"input_marceditor\"
                            tabindex=\"1\"
                            >$value</textarea>
                            class=\"input_marceditor\"
                            tabindex=\"1\"
                            >$value</textarea>
@@ -402,10 +501,12 @@ sub create_input {
         else {
             $subfield_data{marc_value} =
                 "<input type=\"text\"
         else {
             $subfield_data{marc_value} =
                 "<input type=\"text\"
-                        id=".$subfield_data{id}."
-                        name=".$subfield_data{id}."
+                        id=\"".$subfield_data{id}."\"
+                        name=\"".$subfield_data{id}."\"
                         value=\"$value\"
                         tabindex=\"1\"
                         value=\"$value\"
                         tabindex=\"1\"
+                        size=\"67\"
+                        maxlength=\"$max_length\"
                         class=\"input_marceditor\"
                 \/>
                 ";
                         class=\"input_marceditor\"
                 \/>
                 ";
@@ -415,6 +516,22 @@ sub create_input {
     return \%subfield_data;
 }
 
     return \%subfield_data;
 }
 
+
+=head2 format_indicator
+
+Translate indicator value for output form - specifically, map
+indicator = ' ' to ''.  This is for the convenience of a cataloger
+using a mouse to select an indicator input.
+
+=cut
+
+sub format_indicator {
+    my $ind_value = shift;
+    return '' if not defined $ind_value;
+    return '' if $ind_value eq ' ';
+    return $ind_value;
+}
+
 sub build_tabs ($$$$$) {
     my ( $template, $record, $dbh, $encoding,$input ) = @_;
 
 sub build_tabs ($$$$$) {
     my ( $template, $record, $dbh, $encoding,$input ) = @_;
 
@@ -455,7 +572,7 @@ sub build_tabs ($$$$$) {
         foreach my $tag (@tab_data) {
             $i++;
             next if ! $tag;
         foreach my $tag (@tab_data) {
             $i++;
             next if ! $tag;
-            my $indicator;
+            my ($indicator1, $indicator2);
             my $index_tag = CreateKey;
 
             # if MARC::Record is not empty =>use it as master loop, then add missing subfields that should be in the tab.
             my $index_tag = CreateKey;
 
             # if MARC::Record is not empty =>use it as master loop, then add missing subfields that should be in the tab.
@@ -468,6 +585,7 @@ sub build_tabs ($$$$$) {
                else {
                   push @fields, $record->leader(); # if tag == 000
                }
                else {
                   push @fields, $record->leader(); # if tag == 000
                }
+               # loop through each field
                 foreach my $field (@fields) {
                     
                     my @subfields_data;
                 foreach my $field (@fields) {
                     
                     my @subfields_data;
@@ -518,8 +636,15 @@ sub build_tabs ($$$$$) {
                         next if ( $tag < 10 );
                         next
                           if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -4 )
                         next if ( $tag < 10 );
                         next
                           if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -4 )
-                            or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 5 )
-                          );    #check for visibility flag
+                            or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 5 ) )
+                            and not ( $subfield eq "9" and
+                                      exists($tagslib->{$tag}->{'a'}->{authtypecode}) and
+                                      defined($tagslib->{$tag}->{'a'}->{authtypecode}) and
+                                      $tagslib->{$tag}->{'a'}->{authtypecode} ne ""
+                                    )
+                          ;    #check for visibility flag
+                               # if subfield is $9 in a field whose $a is authority-controlled,
+                               # always include in the form regardless of the hidden setting - bug 2206
                         next if ( defined( $field->subfield($subfield) ) );
                         push(
                             @subfields_data,
                         next if ( defined( $field->subfield($subfield) ) );
                         push(
                             @subfields_data,
@@ -530,15 +655,23 @@ sub build_tabs ($$$$$) {
                         );
                     }
                     if ( $#subfields_data >= 0 ) {
                         );
                     }
                     if ( $#subfields_data >= 0 ) {
+                        # build the tag entry.
+                        # note that the random() field is mandatory. Otherwise, on repeated fields, you'll 
+                        # have twice the same "name" value, and cgi->param() will return only one, making
+                        # all subfields to be merged in a single field.
                         my %tag_data = (
                             tag           => $tag,
                             index         => $index_tag,
                             tag_lib       => $tagslib->{$tag}->{lib},
                         my %tag_data = (
                             tag           => $tag,
                             index         => $index_tag,
                             tag_lib       => $tagslib->{$tag}->{lib},
+                            repeatable       => $tagslib->{$tag}->{repeatable},
+                            mandatory       => $tagslib->{$tag}->{mandatory},
                             subfield_loop => \@subfields_data,
                             subfield_loop => \@subfields_data,
-                            fixedfield    => ($tag < 10)?(1):(0),
+                            fixedfield    => $tag < 10?1:0,
+                            random        => CreateKey,
                         );
                         );
-                        if ($tag >= 010){ # no indicator for theses tag
-                           $tag_data{indicator} = $field->indicator(1).$field->indicator(2);
+                        if ($tag >= 10){ # no indicator for 00x tags
+                           $tag_data{indicator1} = format_indicator($field->indicator(1)),
+                           $tag_data{indicator2} = format_indicator($field->indicator(2)),
                         }
                         push( @loop_data, \%tag_data );
                     }
                         }
                         push( @loop_data, \%tag_data );
                     }
@@ -553,7 +686,14 @@ sub build_tabs ($$$$$) {
                     next
                       if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -5 )
                         or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 4 ) )
                     next
                       if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -5 )
                         or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 4 ) )
+                      and not ( $subfield eq "9" and
+                                exists($tagslib->{$tag}->{'a'}->{authtypecode}) and
+                                defined($tagslib->{$tag}->{'a'}->{authtypecode}) and
+                                $tagslib->{$tag}->{'a'}->{authtypecode} ne ""
+                              )
                       ;    #check for visibility flag
                       ;    #check for visibility flag
+                           # if subfield is $9 in a field whose $a is authority-controlled,
+                           # always include in the form regardless of the hidden setting - bug 2206
                     next
                       if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
                     push(
                     next
                       if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
                     push(
@@ -570,10 +710,12 @@ sub build_tabs ($$$$$) {
                         index            => $index_tag,
                         tag_lib          => $tagslib->{$tag}->{lib},
                         repeatable       => $tagslib->{$tag}->{repeatable},
                         index            => $index_tag,
                         tag_lib          => $tagslib->{$tag}->{lib},
                         repeatable       => $tagslib->{$tag}->{repeatable},
-                        indicator        => $indicator,
+                        mandatory       => $tagslib->{$tag}->{mandatory},
+                        indicator1       => $indicator1,
+                        indicator2       => $indicator2,
                         subfield_loop    => \@subfields_data,
                         tagfirstsubfield => $subfields_data[0],
                         subfield_loop    => \@subfields_data,
                         tagfirstsubfield => $subfields_data[0],
-                        fixedfield       => ($tag < 10)?(1):(0)
+                        fixedfield       => $tag < 10?1:0,
                     );
                     
                     push @loop_data, \%tag_data ;
                     );
                     
                     push @loop_data, \%tag_data ;
@@ -590,6 +732,95 @@ sub build_tabs ($$$$$) {
     $template->param( BIG_LOOP => \@BIG_LOOP );
 }
 
     $template->param( BIG_LOOP => \@BIG_LOOP );
 }
 
+#
+# sub that tries to find authorities linked to the biblio
+# the sub :
+#   - search in the authority DB for the same authid (in $9 of the biblio)
+#   - search in the authority DB for the same 001 (in $3 of the biblio in UNIMARC)
+#   - search in the authority DB for the same values (exactly) (in all subfields of the biblio)
+# if the authority is found, the biblio is modified accordingly to be connected to the authority.
+# if the authority is not found, it's added, and the biblio is then modified to be connected to the authority.
+#
+
+sub BiblioAddAuthorities{
+  my ( $record, $frameworkcode ) = @_;
+  my $dbh=C4::Context->dbh;
+  my $query=$dbh->prepare(qq|
+SELECT authtypecode,tagfield
+FROM marc_subfield_structure 
+WHERE frameworkcode=? 
+AND (authtypecode IS NOT NULL AND authtypecode<>\"\")|);
+# SELECT authtypecode,tagfield
+# FROM marc_subfield_structure 
+# WHERE frameworkcode=? 
+# AND (authtypecode IS NOT NULL OR authtypecode<>\"\")|);
+  $query->execute($frameworkcode);
+  my ($countcreated,$countlinked);
+  while (my $data=$query->fetchrow_hashref){
+    foreach my $field ($record->field($data->{tagfield})){
+      next if ($field->subfield('9'));
+      # No authorities id in the tag.
+      # Search if there is any authorities to link to.
+      my $query='at='.$data->{authtypecode}.' ';
+      map {$query.= ' and he,ext="'.$_->[1].'"' if ($_->[0]=~/[A-z]/)}  $field->subfields();
+      my ($error, $results, $total_hits)=SimpleSearch( $query, undef, undef, [ "authorityserver" ] );
+    # there is only 1 result 
+         if ( $error ) {
+        warn "BIBLIOADDSAUTHORITIES: $error";
+           return (0,0) ;
+         }
+      if ($results && scalar(@$results)==1) {
+        my $marcrecord = MARC::File::USMARC::decode($results->[0]);
+        $field->add_subfields('9'=>$marcrecord->field('001')->data);
+        $countlinked++;
+      } elsif (scalar(@$results)>1) {
+   #More than One result 
+   #This can comes out of a lack of a subfield.
+#         my $marcrecord = MARC::File::USMARC::decode($results->[0]);
+#         $record->field($data->{tagfield})->add_subfields('9'=>$marcrecord->field('001')->data);
+  $countlinked++;
+      } else {
+  #There are no results, build authority record, add it to Authorities, get authid and add it to 9
+  ###NOTICE : This is only valid if a subfield is linked to one and only one authtypecode     
+  ###NOTICE : This can be a problem. We should also look into other types and rejected forms.
+         my $authtypedata=GetAuthType($data->{authtypecode});
+         next unless $authtypedata;
+         my $marcrecordauth=MARC::Record->new();
+               if (C4::Context->preference('marcflavour') eq 'MARC21') {
+                       $marcrecordauth->leader('     nz  a22     o  4500');
+                       SetMarcUnicodeFlag($marcrecordauth, 'MARC21');
+                       }
+         my $authfield=MARC::Field->new($authtypedata->{auth_tag_to_report},'','',"a"=>"".$field->subfield('a'));
+         map { $authfield->add_subfields($_->[0]=>$_->[1]) if ($_->[0]=~/[A-z]/ && $_->[0] ne "a" )}  $field->subfields();
+         $marcrecordauth->insert_fields_ordered($authfield);
+
+         # bug 2317: ensure new authority knows it's using UTF-8; currently
+         # only need to do this for MARC21, as MARC::Record->as_xml_record() handles
+         # automatically for UNIMARC (by not transcoding)
+         # FIXME: AddAuthority() instead should simply explicitly require that the MARC::Record
+         # use UTF-8, but as of 2008-08-05, did not want to introduce that kind
+         # of change to a core API just before the 3.0 release.
+
+                               if (C4::Context->preference('marcflavour') eq 'MARC21') {
+                                       $marcrecordauth->insert_fields_ordered(MARC::Field->new('667','','','a'=>"Machine generated authority record."));
+                                       my $cite = $record->author() . ", " .  $record->title_proper() . ", " . $record->publication_date() . " "; 
+                                       $cite =~ s/^[\s\,]*//;
+                                       $cite =~ s/[\s\,]*$//;
+                                       $cite = "Work cat.: (" . C4::Context->preference('MARCOrgCode') . ")". $record->subfield('999','c') . ": " . $cite;
+                                       $marcrecordauth->insert_fields_ordered(MARC::Field->new('670','','','a'=>$cite));
+                               }
+
+#          warn "AUTH RECORD ADDED : ".$marcrecordauth->as_formatted;
+
+         my $authid=AddAuthority($marcrecordauth,'',$data->{authtypecode});
+         $countcreated++;
+         $field->add_subfields('9'=>$authid);
+      }
+    }  
+  }
+  return ($countlinked,$countcreated);
+}
+
 # ========================
 #          MAIN
 #=========================
 # ========================
 #          MAIN
 #=========================
@@ -601,8 +832,11 @@ my $z3950         = $input->param('z3950');
 my $op            = $input->param('op');
 my $mode          = $input->param('mode');
 my $frameworkcode = $input->param('frameworkcode');
 my $op            = $input->param('op');
 my $mode          = $input->param('mode');
 my $frameworkcode = $input->param('frameworkcode');
+my $redirect      = $input->param('redirect');
 my $dbh           = C4::Context->dbh;
 
 my $dbh           = C4::Context->dbh;
 
+my $userflags = ($frameworkcode eq 'FA') ? "fast_cataloging" : "edit_catalogue";
+
 $frameworkcode = &GetFrameworkCode($biblionumber)
   if ( $biblionumber and not($frameworkcode) );
 
 $frameworkcode = &GetFrameworkCode($biblionumber)
   if ( $biblionumber and not($frameworkcode) );
 
@@ -613,35 +847,26 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
         query           => $input,
         type            => "intranet",
         authnotrequired => 0,
         query           => $input,
         type            => "intranet",
         authnotrequired => 0,
-        flagsrequired   => { editcatalogue => 1 },
+        flagsrequired   => { editcatalogue => $userflags },
     }
 );
 
     }
 );
 
-#Getting the list of all frameworks
-my $queryfwk = $dbh->prepare("select frameworktext, frameworkcode from biblio_framework");
-$queryfwk->execute;
-my %select_fwk;
-my @select_fwk;
-my $curfwk;
-push @select_fwk, "Default";
-$select_fwk{"Default"} = "Default";
-
-while ( my ( $description, $fwk ) = $queryfwk->fetchrow ) {
-    push @select_fwk, $fwk;
-    $select_fwk{$fwk} = $description;
-}
-$curfwk = $frameworkcode;
-my $framework = CGI::scrolling_list(
-    -name     => 'Frameworks',
-    -id       => 'Frameworks',
-    -default  => $curfwk,
-    -OnChange => 'Changefwk(this);',
-    -values   => \@select_fwk,
-    -labels   => \%select_fwk,
-    -size     => 1,
-    -multiple => 0
-);
-$template->param( framework => $framework, breedingid => $breedingid );
+# Getting the list of all frameworks
+# get framework list
+my $frameworks = getframeworks;
+my @frameworkcodeloop;
+foreach my $thisframeworkcode ( keys %$frameworks ) {
+       my %row = (
+               value         => $thisframeworkcode,
+               frameworktext => $frameworks->{$thisframeworkcode}->{'frameworktext'},
+       );
+       if ($frameworkcode eq $thisframeworkcode){
+               $row{'selected'}="selected=\"selected\"";
+               }
+       push @frameworkcodeloop, \%row;
+} 
+$template->param( frameworkcodeloop => \@frameworkcodeloop,
+       breedingid => $breedingid );
 
 # ++ Global
 $tagslib         = &GetMarcStructure( 1, $frameworkcode );
 
 # ++ Global
 $tagslib         = &GetMarcStructure( 1, $frameworkcode );
@@ -652,8 +877,8 @@ $mandatory_z3950 = GetMandatoryFieldZ3950($frameworkcode);
 my $record   = -1;
 my $encoding = "";
 my (
 my $record   = -1;
 my $encoding = "";
 my (
-       $biblionumtagfield,
-       $biblionumtagsubfield,
+       $biblionumbertagfield,
+       $biblionumbertagsubfield,
        $biblioitemnumtagfield,
        $biblioitemnumtagsubfield,
        $bibitem,
        $biblioitemnumtagfield,
        $biblioitemnumtagsubfield,
        $bibitem,
@@ -664,16 +889,17 @@ if (($biblionumber) && !($breedingid)){
        $record = GetMarcBiblio($biblionumber);
 }
 if ($breedingid) {
        $record = GetMarcBiblio($biblionumber);
 }
 if ($breedingid) {
-    ( $record, $encoding ) = MARCfindbreeding( $dbh, $breedingid ) ;
+    ( $record, $encoding ) = MARCfindbreeding( $breedingid ) ;
 }
 
 $is_a_modif = 0;
     
 if ($biblionumber) {
     $is_a_modif = 1;
 }
 
 $is_a_modif = 0;
     
 if ($biblionumber) {
     $is_a_modif = 1;
+       $template->param( title => $record->title(), );
 
     # if it's a modif, retrieve bibli and biblioitem numbers for the future modification of old-DB.
 
     # if it's a modif, retrieve bibli and biblioitem numbers for the future modification of old-DB.
-    ( $biblionumtagfield, $biblionumtagsubfield ) =
+    ( $biblionumbertagfield, $biblionumbertagsubfield ) =
        &GetMarcFromKohaField( "biblio.biblionumber", $frameworkcode );
     ( $biblioitemnumtagfield, $biblioitemnumtagsubfield ) =
        &GetMarcFromKohaField( "biblioitems.biblioitemnumber", $frameworkcode );
        &GetMarcFromKohaField( "biblio.biblionumber", $frameworkcode );
     ( $biblioitemnumtagfield, $biblioitemnumtagsubfield ) =
        &GetMarcFromKohaField( "biblioitems.biblioitemnumber", $frameworkcode );
@@ -697,6 +923,9 @@ if ( $op eq "addbiblio" ) {
     if ( !$duplicatebiblionumber or $confirm_not_duplicate ) {
         my $oldbibnum;
         my $oldbibitemnum;
     if ( !$duplicatebiblionumber or $confirm_not_duplicate ) {
         my $oldbibnum;
         my $oldbibitemnum;
+        if (C4::Context->preference("BiblioAddsAuthorities")){
+          my ($countlinked,$countcreated)=BiblioAddAuthorities($record,$frameworkcode);
+        } 
         if ( $is_a_modif ) {
             ModBiblioframework( $biblionumber, $frameworkcode ); 
             ModBiblio( $record, $biblionumber, $frameworkcode );
         if ( $is_a_modif ) {
             ModBiblioframework( $biblionumber, $frameworkcode ); 
             ModBiblio( $record, $biblionumber, $frameworkcode );
@@ -704,17 +933,27 @@ if ( $op eq "addbiblio" ) {
         else {
             ( $biblionumber, $oldbibitemnum ) = AddBiblio( $record, $frameworkcode );
         }
         else {
             ( $biblionumber, $oldbibitemnum ) = AddBiblio( $record, $frameworkcode );
         }
-
-        if (C4::Context->preference("BiblioAddsAuthorities")){
-          my ($countlinked,$countcreated)=BiblioAddAuthorities($record,$frameworkcode);
-        }
-
-        if ($mode ne "popup"){
+        if ($mode ne "popup" && !$is_a_modif && $redirect eq "items"){
             print $input->redirect(
                 "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode"
             );
             exit;
             print $input->redirect(
                 "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode"
             );
             exit;
-        } else {
+        }
+               elsif($is_a_modif || $redirect eq "view"){
+            my $defaultview = C4::Context->preference('IntranetBiblioDefaultView');
+            my $views = { C4::Search::enabled_staff_search_views };
+            if ($defaultview eq 'isbd' && $views->{can_view_ISBD}) {
+                print $input->redirect("/cgi-bin/koha/catalogue/ISBDdetail.pl?biblionumber=$biblionumber");
+            } elsif  ($defaultview eq 'marc' && $views->{can_view_MARC}) {
+                print $input->redirect("/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode");
+            } elsif  ($defaultview eq 'labeled_marc' && $views->{can_view_labeledMARC}) {
+                print $input->redirect("/cgi-bin/koha/catalogue/labeledMARCdetail.pl?biblionumber=$biblionumber");
+            } else {
+                print $input->redirect("/cgi-bin/koha/catalogue/detail.pl?biblionumber=$biblionumber");
+            }
+            exit;
+
+               }else {
           $template->param(
             biblionumber => $biblionumber,
             done         =>1,
           $template->param(
             biblionumber => $biblionumber,
             done         =>1,
@@ -734,10 +973,6 @@ if ( $op eq "addbiblio" ) {
         build_tabs ($template, $record, $dbh,$encoding,$input);
         $template->param(
             biblionumber             => $biblionumber,
         build_tabs ($template, $record, $dbh,$encoding,$input);
         $template->param(
             biblionumber             => $biblionumber,
-            biblionumtagfield        => $biblionumtagfield,
-            biblionumtagsubfield     => $biblionumtagsubfield,
-            biblioitemnumtagfield    => $biblioitemnumtagfield,
-            biblioitemnumtagsubfield => $biblioitemnumtagsubfield,
             biblioitemnumber         => $biblioitemnumber,
             duplicatebiblionumber    => $duplicatebiblionumber,
             duplicatebibid           => $duplicatebiblionumber,
             biblioitemnumber         => $biblioitemnumber,
             duplicatebiblionumber    => $duplicatebiblionumber,
             duplicatebibid           => $duplicatebiblionumber,
@@ -776,8 +1011,8 @@ elsif ( $op eq "delete" ) {
     build_tabs( $template, $record, $dbh, $encoding,$input );
     $template->param(
         biblionumber             => $biblionumber,
     build_tabs( $template, $record, $dbh, $encoding,$input );
     $template->param(
         biblionumber             => $biblionumber,
-        biblionumtagfield        => $biblionumtagfield,
-        biblionumtagsubfield     => $biblionumtagsubfield,
+        biblionumbertagfield        => $biblionumbertagfield,
+        biblionumbertagsubfield     => $biblionumbertagsubfield,
         biblioitemnumtagfield    => $biblioitemnumtagfield,
         biblioitemnumtagsubfield => $biblioitemnumtagsubfield,
         biblioitemnumber         => $biblioitemnumber,
         biblioitemnumtagfield    => $biblioitemnumtagfield,
         biblioitemnumtagsubfield => $biblioitemnumtagsubfield,
         biblioitemnumber         => $biblioitemnumber,
@@ -785,6 +1020,9 @@ elsif ( $op eq "delete" ) {
 }
 
 $template->param( title => $record->title() ) if ( $record ne "-1" );
 }
 
 $template->param( title => $record->title() ) if ( $record ne "-1" );
+if (C4::Context->preference("marcflavour") eq "MARC21"){
+    $template->param(MARC21 => 1);
+}
 $template->param(
     popup => $mode,
     frameworkcode => $frameworkcode,
 $template->param(
     popup => $mode,
     frameworkcode => $frameworkcode,