(Bug 4049) Searching itemtypes returning noise
[koha_fer] / C4 / Biblio.pm
old mode 100755 (executable)
new mode 100644 (file)
index 7b17981..a0e06f6
@@ -1,6 +1,7 @@
 package C4::Biblio;
 
 # Copyright 2000-2002 Katipo Communications
+# Copyright 2010 BibLibre
 #
 # This file is part of Koha.
 #
@@ -13,9 +14,9 @@ package C4::Biblio;
 # 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 warnings;
@@ -58,6 +59,7 @@ BEGIN {
       &GetBiblioItemInfosOf
       &GetBiblioItemByBiblioNumber
       &GetBiblioFromItemNumber
+      &GetBiblionumberFromItemnumber
 
       &GetRecordValue
       &GetFieldMapping
@@ -66,7 +68,9 @@ BEGIN {
 
       &GetISBDView
 
+      &GetMarcControlnumber
       &GetMarcNotes
+      &GetMarcISBN
       &GetMarcSubjects
       &GetMarcBiblio
       &GetMarcAuthors
@@ -80,7 +84,6 @@ BEGIN {
       &GetMarcStructure
       &GetMarcFromKohaField
       &GetFrameworkCode
-      &GetPublisherNameFromIsbn
       &TransformKohaToMarc
 
       &CountItemsIssued
@@ -213,11 +216,7 @@ When modifying a biblio or an item, the behaviour is quite similar.
 
 =head2 AddBiblio
 
-=over 4
-
-($biblionumber,$biblioitemnumber) = AddBiblio($record,$frameworkcode);
-
-=back
+  ($biblionumber,$biblioitemnumber) = AddBiblio($record,$frameworkcode);
 
 Exported function (core API) for adding a new biblio to koha.
 
@@ -251,6 +250,7 @@ sub AddBiblio {
     my $dbh = C4::Context->dbh;
 
     # transform the data into koha-table style data
+    SetUTF8Flag($record);
     my $olddata = TransformMarcToKoha( $dbh, $record, $frameworkcode );
     ( $biblionumber, $error ) = _koha_add_biblio( $dbh, $olddata, $frameworkcode );
     $olddata->{'biblionumber'} = $biblionumber;
@@ -270,11 +270,7 @@ sub AddBiblio {
 
 =head2 ModBiblio
 
-=over 4
-
-    ModBiblio( $record,$biblionumber,$frameworkcode);
-
-=back
+  ModBiblio( $record,$biblionumber,$frameworkcode);
 
 Replace an existing bib record identified by C<$biblionumber>
 with one supplied by the MARC::Record object C<$record>.  The embedded
@@ -299,6 +295,7 @@ sub ModBiblio {
         logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted );
     }
 
+    SetUTF8Flag($record);
     my $dbh = C4::Context->dbh;
 
     $frameworkcode = "" unless $frameworkcode;
@@ -323,15 +320,28 @@ sub ModBiblio {
     foreach my $fielditem (@fields) {
         my $field;
         foreach ( $fielditem->subfields() ) {
+            # re-encode the subfield only if it isn't already in utf-8.
+            my ($tag, $value) = @$_;
+            $tag = Encode::encode('utf-8', $tag) unless utf8::is_utf8($tag);
+            $value = Encode::encode('utf-8', $value) unless utf8::is_utf8($value);
+
             if ($field) {
-                $field->add_subfields( Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) );
+                $field->add_subfields( $tag => $value );
             } else {
-                $field = MARC::Field->new( "$itemtag", '', '', Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) );
+                $field = MARC::Field->new( "$itemtag", '', '', $tag => $value );
             }
         }
         $record->append_fields($field);
     }
 
+    foreach my $field ($record->fields()) {
+        if (! $field->is_control_field()) {
+            if (scalar($field->subfields()) == 0) {
+                $record->delete_fields($field);
+            }
+        }
+    }
+
     # update biblionumber and biblioitemnumber in MARC
     # FIXME - this is assuming a 1 to 1 relationship between
     # biblios and biblioitems
@@ -358,8 +368,9 @@ sub ModBiblio {
 
 =head2 ModBiblioframework
 
-    ModBiblioframework($biblionumber,$frameworkcode);
-    Exported function to modify a biblio framework
+   ModBiblioframework($biblionumber,$frameworkcode);
+
+Exported function to modify a biblio framework
 
 =cut
 
@@ -373,9 +384,8 @@ sub ModBiblioframework {
 
 =head2 DelBiblio
 
-=over
+  my $error = &DelBiblio($dbh,$biblionumber);
 
-my $error = &DelBiblio($dbh,$biblionumber);
 Exported function (core API) for deleting a biblio in koha.
 Deletes biblio record from Zebra and Koha tables (biblio,biblioitems,items)
 Also backs it up to deleted* tables
@@ -383,8 +393,6 @@ Checks to make sure there are not issues on any of the items
 return:
 C<$error> : undef unless an error occurs
 
-=back
-
 =cut
 
 sub DelBiblio {
@@ -446,11 +454,7 @@ sub DelBiblio {
 
 =head2 LinkBibHeadingsToAuthorities
 
-=over 4
-
-my $headings_linked = LinkBibHeadingsToAuthorities($marc);
-
-=back
+  my $headings_linked = LinkBibHeadingsToAuthorities($marc);
 
 Links bib headings to authority records by checking
 each authority-controlled field in the C<MARC::Record>
@@ -503,11 +507,7 @@ sub LinkBibHeadingsToAuthorities {
 
 =head2 GetRecordValue
 
-=over 4
-
-my $values = GetRecordValue($field, $record, $frameworkcode);
-
-=back
+  my $values = GetRecordValue($field, $record, $frameworkcode);
 
 Get MARC fields from a keyword defined in fieldmapping table.
 
@@ -540,11 +540,7 @@ sub GetRecordValue {
 
 =head2 SetFieldMapping
 
-=over 4
-
-SetFieldMapping($framework, $field, $fieldcode, $subfieldcode);
-
-=back
+  SetFieldMapping($framework, $field, $fieldcode, $subfieldcode);
 
 Set a Field to MARC mapping value, if it already exists we don't add a new one.
 
@@ -566,11 +562,7 @@ sub SetFieldMapping {
 
 =head2 DeleteFieldMapping
 
-=over 4
-
-DeleteFieldMapping($id);
-
-=back
+  DeleteFieldMapping($id);
 
 Delete a field mapping from an $id.
 
@@ -586,11 +578,7 @@ sub DeleteFieldMapping {
 
 =head2 GetFieldMapping
 
-=over 4
-
-GetFieldMapping($frameworkcode);
-
-=back
+  GetFieldMapping($frameworkcode);
 
 Get all field mappings for a specified frameworkcode
 
@@ -612,20 +600,18 @@ sub GetFieldMapping {
 
 =head2 GetBiblioData
 
-=over 4
+  $data = &GetBiblioData($biblionumber);
 
-$data = &GetBiblioData($biblionumber);
 Returns information about the book with the given biblionumber.
 C<&GetBiblioData> returns a reference-to-hash. The keys are the fields in
 the C<biblio> and C<biblioitems> tables in the
 Koha database.
+
 In addition, C<$data-E<gt>{subject}> is the list of the book's
 subjects, separated by C<" , "> (space, comma, space).
 If there are multiple biblioitems with the given biblionumber, only
 the first one is considered.
 
-=back
-
 =cut
 
 sub GetBiblioData {
@@ -658,17 +644,13 @@ sub GetBiblioData {
 
 =head2 &GetBiblioItemData
 
-=over 4
-
-$itemdata = &GetBiblioItemData($biblioitemnumber);
+  $itemdata = &GetBiblioItemData($biblioitemnumber);
 
 Looks up the biblioitem with the given biblioitemnumber. Returns a
 reference-to-hash. The keys are the fields from the C<biblio>,
 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
 
-=back
-
 =cut
 
 #'
@@ -691,12 +673,8 @@ sub GetBiblioItemData {
 
 =head2 GetBiblioItemByBiblioNumber
 
-=over 4
-
 NOTE : This function has been copy/paste from C4/Biblio.pm from head before zebra integration.
 
-=back
-
 =cut
 
 sub GetBiblioItemByBiblioNumber {
@@ -716,11 +694,24 @@ sub GetBiblioItemByBiblioNumber {
     return @results;
 }
 
-=head2 GetBiblioFromItemNumber
+=head2 GetBiblionumberFromItemnumber
 
-=over 4
 
-$item = &GetBiblioFromItemNumber($itemnumber,$barcode);
+=cut
+
+sub GetBiblionumberFromItemnumber {
+    my ($itemnumber) = @_;
+    my $dbh            = C4::Context->dbh;
+    my $sth            = $dbh->prepare("Select biblionumber FROM items WHERE itemnumber = ?");
+
+    $sth->execute($itemnumber);
+    my ($result) = $sth->fetchrow;
+    return ($result);
+}
+
+=head2 GetBiblioFromItemNumber
+
+  $item = &GetBiblioFromItemNumber($itemnumber,$barcode);
 
 Looks up the item with the given itemnumber. if undef, try the barcode.
 
@@ -728,8 +719,6 @@ C<&itemnodata> returns a reference-to-hash whose keys are the fields
 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
 database.
 
-=back
-
 =cut
 
 #'
@@ -761,14 +750,10 @@ sub GetBiblioFromItemNumber {
 
 =head2 GetISBDView 
 
-=over 4
-
-$isbd = &GetISBDView($biblionumber);
+  $isbd = &GetISBDView($biblionumber);
 
 Return the ISBD view which can be included in opac and intranet
 
-=back
-
 =cut
 
 sub GetISBDView {
@@ -778,7 +763,7 @@ sub GetISBDView {
     my ( $holdingbrtagf, $holdingbrtagsubf ) = &GetMarcFromKohaField( "items.holdingbranch", $itemtype );
     my $tagslib = &GetMarcStructure( 1, $itemtype );
 
-    my $ISBD = C4::Context->preference('ISBD');
+    my $ISBD = C4::Context->preference('isbd');
     my $bloc = $ISBD;
     my $res;
     my $blocres;
@@ -882,11 +867,7 @@ sub GetISBDView {
 
 =head2 GetBiblio
 
-=over 4
-
-( $count, @results ) = &GetBiblio($biblionumber);
-
-=back
+  ( $count, @results ) = &GetBiblio($biblionumber);
 
 =cut
 
@@ -907,11 +888,7 @@ sub GetBiblio {
 
 =head2 GetBiblioItemInfosOf
 
-=over 4
-
-GetBiblioItemInfosOf(@biblioitemnumbers);
-
-=back
+  GetBiblioItemInfosOf(@biblioitemnumbers);
 
 =cut
 
@@ -932,16 +909,12 @@ sub GetBiblioItemInfosOf {
 
 =head2 GetMarcStructure
 
-=over 4
-
-$res = GetMarcStructure($forlibrarian,$frameworkcode);
+  $res = GetMarcStructure($forlibrarian,$frameworkcode);
 
 Returns a reference to a big hash of hash, with the Marc structure for the given frameworkcode
 $forlibrarian  :if set to 1, the MARC descriptions are the librarians ones, otherwise it's the public (OPAC) ones
 $frameworkcode : the framework code to read
 
-=back
-
 =cut
 
 # cache for results of GetMarcStructure -- needed
@@ -1027,16 +1000,16 @@ sub GetMarcStructure {
 
 =head2 GetUsedMarcStructure
 
-    the same function as GetMarcStructure except it just takes field
-    in tab 0-9. (used field)
-    
-    my $results = GetUsedMarcStructure($frameworkcode);
-    
-    L<$results> is a ref to an array which each case containts a ref
-    to a hash which each keys is the columns from marc_subfield_structure
-    
-    L<$frameworkcode> is the framework code. 
-    
+The same function as GetMarcStructure except it just takes field
+in tab 0-9. (used field)
+
+  my $results = GetUsedMarcStructure($frameworkcode);
+
+C<$results> is a ref to an array which each case containts a ref
+to a hash which each keys is the columns from marc_subfield_structure
+
+C<$frameworkcode> is the framework code. 
+
 =cut
 
 sub GetUsedMarcStructure($) {
@@ -1055,14 +1028,11 @@ sub GetUsedMarcStructure($) {
 
 =head2 GetMarcFromKohaField
 
-=over 4
+  ($MARCfield,$MARCsubfield)=GetMarcFromKohaField($kohafield,$frameworkcode);
 
-($MARCfield,$MARCsubfield)=GetMarcFromKohaField($kohafield,$frameworkcode);
 Returns the MARC fields & subfields mapped to the koha field 
 for the given frameworkcode
 
-=back
-
 =cut
 
 sub GetMarcFromKohaField {
@@ -1074,11 +1044,7 @@ sub GetMarcFromKohaField {
 
 =head2 GetMarcBiblio
 
-=over 4
-
-my $record = GetMarcBiblio($biblionumber);
-
-=back
+  my $record = GetMarcBiblio($biblionumber);
 
 Returns MARC::Record representing bib identified by
 C<$biblionumber>.  If no bib exists, returns undef.
@@ -1109,15 +1075,11 @@ sub GetMarcBiblio {
 
 =head2 GetXmlBiblio
 
-=over 4
-
-my $marcxml = GetXmlBiblio($biblionumber);
+  my $marcxml = GetXmlBiblio($biblionumber);
 
 Returns biblioitems.marcxml of the biblionumber passed in parameter.
 The XML contains both biblio & item datas
 
-=back
-
 =cut
 
 sub GetXmlBiblio {
@@ -1131,14 +1093,10 @@ sub GetXmlBiblio {
 
 =head2 GetCOinSBiblio
 
-=over 4
-
-my $coins = GetCOinSBiblio($biblionumber);
+  my $coins = GetCOinSBiblio($biblionumber);
 
 Returns the COinS(a span) which can be included in a biblio record
 
-=back
-
 =cut
 
 sub GetCOinSBiblio {
@@ -1146,6 +1104,11 @@ sub GetCOinSBiblio {
     my $record = GetMarcBiblio($biblionumber);
 
     # get the coin format
+    if ( ! $record ) {
+       # can't get a valid MARC::Record object, bail out at this point
+       warn "We called GetMarcBiblio with a biblionumber that doesn't exist biblionumber=$biblionumber";
+       return;
+    }
     my $pos7 = substr $record->leader(), 7, 1;
     my $pos6 = substr $record->leader(), 6, 1;
     my $mtx;
@@ -1158,50 +1121,57 @@ sub GetCOinSBiblio {
     my $isbn      = '';
     my $issn      = '';
     my $publisher = '';
-
-    if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
-        my $fmts6;
-        my $fmts7;
-        %$fmts6 = (
-            'a' => 'book',
-            'b' => 'manuscript',
-            'c' => 'book',
-            'd' => 'manuscript',
-            'e' => 'map',
-            'f' => 'map',
-            'g' => 'film',
-            'i' => 'audioRecording',
-            'j' => 'audioRecording',
-            'k' => 'artwork',
-            'l' => 'document',
-            'm' => 'computerProgram',
-            'r' => 'document',
-
-        );
-        %$fmts7 = (
-            'a' => 'journalArticle',
-            's' => 'journal',
-        );
-
-        $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book';
-
-        if ( $genre eq 'book' ) {
+    my $pages     = '';
+    my $titletype = 'b';
+
+    # For the purposes of generating COinS metadata, LDR/06-07 can be
+    # considered the same for UNIMARC and MARC21
+    my $fmts6;
+    my $fmts7;
+    %$fmts6 = (
+                'a' => 'book',
+                'b' => 'manuscript',
+                'c' => 'book',
+                'd' => 'manuscript',
+                'e' => 'map',
+                'f' => 'map',
+                'g' => 'film',
+                'i' => 'audioRecording',
+                'j' => 'audioRecording',
+                'k' => 'artwork',
+                'l' => 'document',
+                'm' => 'computerProgram',
+                'o' => 'document',
+                'r' => 'document',
+            );
+    %$fmts7 = (
+                    'a' => 'journalArticle',
+                    's' => 'journal',
+              );
+
+    $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book';
+
+    if ( $genre eq 'book' ) {
             $genre = $fmts7->{$pos7} if $fmts7->{$pos7};
-        }
+    }
 
-        ##### We must transform mtx to a valable mtx and document type ####
-        if ( $genre eq 'book' ) {
+    ##### We must transform mtx to a valable mtx and document type ####
+    if ( $genre eq 'book' ) {
             $mtx = 'book';
-        } elsif ( $genre eq 'journal' ) {
+    } elsif ( $genre eq 'journal' ) {
             $mtx = 'journal';
-        } elsif ( $genre eq 'journalArticle' ) {
+            $titletype = 'j';
+    } elsif ( $genre eq 'journalArticle' ) {
             $mtx   = 'journal';
             $genre = 'article';
-        } else {
+            $titletype = 'a';
+    } else {
             $mtx = 'dc';
-        }
+    }
 
-        $genre = ( $mtx eq 'dc' ) ? "&amp;rft.type=$genre" : "&amp;rft.genre=$genre";
+    $genre = ( $mtx eq 'dc' ) ? "&amp;rft.type=$genre" : "&amp;rft.genre=$genre";
+
+    if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
 
         # Setting datas
         $aulast  = $record->subfield( '700', 'a' );
@@ -1225,9 +1195,6 @@ sub GetCOinSBiblio {
     } else {
 
         # MARC21 need some improve
-        my $fmts;
-        $mtx   = 'book';
-        $genre = "&amp;rft.genre=book";
 
         # Setting datas
         if ( $record->field('100') ) {
@@ -1240,18 +1207,36 @@ sub GetCOinSBiblio {
                 $oauthors .= "&amp;rft.au=$au";
             }
         }
-        $title = "&amp;rft.btitle=" . $record->subfield( '245', 'a' );
+        $title = "&amp;rft." . $titletype . "title=" . $record->subfield( '245', 'a' );
         $subtitle = $record->subfield( '245', 'b' ) || '';
         $title .= $subtitle;
-        $pubyear   = $record->subfield( '260', 'c' ) || '';
-        $publisher = $record->subfield( '260', 'b' ) || '';
-        $isbn      = $record->subfield( '020', 'a' ) || '';
-        $issn      = $record->subfield( '022', 'a' ) || '';
+        if ($titletype eq 'a') {
+            $pubyear   = substr $record->field('008')->data(), 7, 4;
+            $isbn      = $record->subfield( '773', 'z' ) || '';
+            $issn      = $record->subfield( '773', 'x' ) || '';
+            if ($mtx eq 'journal') {
+                $title    .= "&amp;rft.title=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a')));
+            } else {
+                $title    .= "&amp;rft.btitle=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a')) || '');
+            }
+            foreach my $rel ($record->subfield( '773', 'g' )) {
+                if ($pages) {
+                    $pages .= ', ';
+                }
+                $pages .= $rel;
+            }
+        } else {
+            $pubyear   = $record->subfield( '260', 'c' ) || '';
+            $publisher = $record->subfield( '260', 'b' ) || '';
+            $isbn      = $record->subfield( '020', 'a' ) || '';
+            $issn      = $record->subfield( '022', 'a' ) || '';
+        }
 
     }
     my $coins_value =
-"ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&amp;rft.isbn=$isbn&amp;rft.issn=$issn&amp;rft.aulast=$aulast&amp;rft.aufirst=$aufirst$oauthors&amp;rft.pub=$publisher&amp;rft.date=$pubyear";
+"ctx_ver=Z39.88-2004&amp;rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&amp;rft.isbn=$isbn&amp;rft.issn=$issn&amp;rft.aulast=$aulast&amp;rft.aufirst=$aufirst$oauthors&amp;rft.pub=$publisher&amp;rft.date=$pubyear&amp;rft.pages=$pages";
     $coins_value =~ s/(\ |&[^a])/\+/g;
+    $coins_value =~ s/\"/\&quot\;/g;
 
 #<!-- TMPL_VAR NAME="ocoins_format" -->&amp;rft.au=<!-- TMPL_VAR NAME="author" -->&amp;rft.btitle=<!-- TMPL_VAR NAME="title" -->&amp;rft.date=<!-- TMPL_VAR NAME="publicationyear" -->&amp;rft.pages=<!-- TMPL_VAR NAME="pages" -->&amp;rft.isbn=<!-- TMPL_VAR NAME=amazonisbn -->&amp;rft.aucorp=&amp;rft.place=<!-- TMPL_VAR NAME="place" -->&amp;rft.pub=<!-- TMPL_VAR NAME="publishercode" -->&amp;rft.edition=<!-- TMPL_VAR NAME="edition" -->&amp;rft.series=<!-- TMPL_VAR NAME="series" -->&amp;rft.genre="
 
@@ -1260,20 +1245,18 @@ sub GetCOinSBiblio {
 
 =head2 GetAuthorisedValueDesc
 
-=over 4
-
-my $subfieldvalue =get_authorised_value_desc(
+  my $subfieldvalue =get_authorised_value_desc(
     $tag, $subf[$i][0],$subf[$i][1], '', $taglib, $category, $opac);
+
 Retrieve the complete description for a given authorised value.
 
 Now takes $category and $value pair too.
-my $auth_value_desc =GetAuthorisedValueDesc(
-    '','', 'DVD' ,'','','CCODE');
 
-If the optional $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
+  my $auth_value_desc =GetAuthorisedValueDesc(
+    '','', 'DVD' ,'','','CCODE');
 
-
-=back
+If the optional $opac parameter is set to a true value, displays OPAC 
+descriptions rather than normal ones when they exist.
 
 =cut
 
@@ -1309,16 +1292,75 @@ sub GetAuthorisedValueDesc {
     }
 }
 
+=head2 GetMarcControlnumber
+
+  $marccontrolnumber = GetMarcControlnumber($record,$marcflavour);
+
+Get the control number / record Identifier from the MARC record and return it.
+
+=cut
+
+sub GetMarcControlnumber {
+    my ( $record, $marcflavour ) = @_;
+    my $controlnumber = "";
+    # Control number or Record identifier are the same field in MARC21 and UNIMARC
+    # Keep $marcflavour for possible later use
+    if ($marcflavour eq "MARC21" || $marcflavour eq "UNIMARC") {
+        my $controlnumberField = $record->field('001');
+        if ($controlnumberField) {
+            $controlnumber = $controlnumberField->data();
+        }
+    }
+    return $controlnumber;
+}
+
+=head2 GetMarcISBN
+
+  $marcisbnsarray = GetMarcISBN( $record, $marcflavour );
+
+Get all ISBNs from the MARC record and returns them in an array.
+ISBNs stored in differents places depending on MARC flavour
+
+=cut
+
+sub GetMarcISBN {
+    my ( $record, $marcflavour ) = @_;
+    my $scope;
+    if ( $marcflavour eq "MARC21" ) {
+        $scope = '020';
+    } else {    # assume unimarc if not marc21
+        $scope = '010';
+    }
+    my @marcisbns;
+    my $isbn = "";
+    my $tag  = "";
+    my $marcisbn;
+    foreach my $field ( $record->field($scope) ) {
+        my $value = $field->as_string();
+        if ( $isbn ne "" ) {
+            $marcisbn = { marcisbn => $isbn, };
+            push @marcisbns, $marcisbn;
+            $isbn = $value;
+        }
+        if ( $isbn ne $value ) {
+            $isbn = $isbn . " " . $value;
+        }
+    }
+
+    if ($isbn) {
+        $marcisbn = { marcisbn => $isbn };
+        push @marcisbns, $marcisbn;    #load last tag into array
+    }
+    return \@marcisbns;
+}    # end GetMarcISBN
+
 =head2 GetMarcNotes
 
-=over 4
+  $marcnotesarray = GetMarcNotes( $record, $marcflavour );
 
-$marcnotesarray = GetMarcNotes( $record, $marcflavour );
 Get all notes from the MARC record and returns them in an array.
 The note are stored in differents places depending on MARC flavour
 
-=back
-
 =cut
 
 sub GetMarcNotes {
@@ -1354,14 +1396,11 @@ sub GetMarcNotes {
 
 =head2 GetMarcSubjects
 
-=over 4
+  $marcsubjcts = GetMarcSubjects($record,$marcflavour);
 
-$marcsubjcts = GetMarcSubjects($record,$marcflavour);
 Get all subjects from the MARC record and returns them in an array.
 The subjects are stored in differents places depending on MARC flavour
 
-=back
-
 =cut
 
 sub GetMarcSubjects {
@@ -1380,6 +1419,8 @@ sub GetMarcSubjects {
     my $subfield = "";
     my $marcsubject;
 
+    my $subject_limit = C4::Context->preference("TraceCompleteSubfields") ? 'su,complete-subfield' : 'su';
+
     foreach my $field ( $record->field('6..') ) {
         next unless $field->tag() >= $mintag && $field->tag() <= $maxtag;
         my @subfields_loop;
@@ -1406,7 +1447,7 @@ sub GetMarcSubjects {
                 @link_loop = ( { 'limit' => 'an', link => "$linkvalue" } );
             }
             if ( not $found9 ) {
-                push @link_loop, { 'limit' => 'su', link => $linkvalue, operator => $operator };
+                push @link_loop, { 'limit' => $subject_limit, link => $linkvalue, operator => $operator };
             }
             my $separator = C4::Context->preference("authoritysep") unless $counter == 0;
 
@@ -1424,14 +1465,11 @@ sub GetMarcSubjects {
 
 =head2 GetMarcAuthors
 
-=over 4
+  authors = GetMarcAuthors($record,$marcflavour);
 
-authors = GetMarcAuthors($record,$marcflavour);
 Get all authors from the MARC record and returns them in an array.
 The authors are stored in differents places depending on MARC flavour
 
-=back
-
 =cut
 
 sub GetMarcAuthors {
@@ -1496,14 +1534,11 @@ sub GetMarcAuthors {
 
 =head2 GetMarcUrls
 
-=over 4
+  $marcurls = GetMarcUrls($record,$marcflavour);
 
-$marcurls = GetMarcUrls($record,$marcflavour);
 Returns arrayref of URLs from MARC data, suitable to pass to tmpl loop.
 Assumes web resources (not uncommon in MARC21 to omit resource type ind) 
 
-=back
-
 =cut
 
 sub GetMarcUrls {
@@ -1554,14 +1589,11 @@ sub GetMarcUrls {
 
 =head2 GetMarcSeries
 
-=over 4
+  $marcseriesarray = GetMarcSeries($record,$marcflavour);
 
-$marcseriesarray = GetMarcSeries($record,$marcflavour);
 Get all series from the MARC record and returns them in an array.
 The series are stored in differents places depending on MARC flavour
 
-=back
-
 =cut
 
 sub GetMarcSeries {
@@ -1609,7 +1641,7 @@ sub GetMarcSeries {
             if ($volume_number) {
                 push @subfields_loop, { volumenum => $value };
             } else {
-                push @subfields_loop, { code => $code, value => $value, link_loop => \@link_loop, separator => $separator, volumenum => $volume_number };
+                push @subfields_loop, { code => $code, value => $value, link_loop => \@link_loop, separator => $separator, volumenum => $volume_number } unless ( $series_subfield->[0] eq '9' );
             }
             $counter++;
         }
@@ -1626,11 +1658,7 @@ sub GetMarcSeries {
 
 =head2 GetFrameworkCode
 
-=over 4
-
-    $frameworkcode = GetFrameworkCode( $biblionumber )
-
-=back
+  $frameworkcode = GetFrameworkCode( $biblionumber )
 
 =cut
 
@@ -1643,46 +1671,14 @@ sub GetFrameworkCode {
     return $frameworkcode;
 }
 
-=head2 GetPublisherNameFromIsbn
-
-    $name = GetPublishercodeFromIsbn($isbn);
-    if(defined $name){
-        ...
-    }
-
-=cut
-
-sub GetPublisherNameFromIsbn($) {
-    my $isbn = shift;
-    $isbn =~ s/[- _]//g;
-    $isbn =~ s/^0*//;
-    my @codes = ( split '-', DisplayISBN($isbn) );
-    my $code  = $codes[0] . $codes[1] . $codes[2];
-    my $dbh   = C4::Context->dbh;
-    my $query = qq{
-        SELECT distinct publishercode
-        FROM   biblioitems
-        WHERE  isbn LIKE ?
-        AND    publishercode IS NOT NULL
-        LIMIT 1
-    };
-    my $sth = $dbh->prepare($query);
-    $sth->execute("$code%");
-    my $name = $sth->fetchrow;
-    return $name if length $name;
-    return undef;
-}
-
 =head2 TransformKohaToMarc
 
-=over 4
-
     $record = TransformKohaToMarc( $hash )
-    This function builds partial MARC::Record from a hash
-    Hash entries can be from biblio or biblioitems.
-    This function is called in acquisition module, to create a basic catalogue entry from user entry
 
-=back
+This function builds partial MARC::Record from a hash
+Hash entries can be from biblio or biblioitems.
+
+This function is called in acquisition module, to create a basic catalogue entry from user entry
 
 =cut
 
@@ -1699,12 +1695,8 @@ sub TransformKohaToMarc {
 
 =head2 TransformKohaToMarcOneField
 
-=over 4
-
     $record = TransformKohaToMarcOneField( $sth, $record, $kohafieldname, $value, $frameworkcode );
 
-=back
-
 =cut
 
 sub TransformKohaToMarcOneField {
@@ -1719,13 +1711,18 @@ sub TransformKohaToMarcOneField {
     }
     $sth->execute( $frameworkcode, $kohafieldname );
     if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
+        my @values = split(/\s?\|\s?/, $value, -1);
+        
+        foreach my $itemvalue (@values){
         my $tag = $record->field($tagfield);
         if ($tag) {
-            $tag->update( $tagsubfield => $value );
+                $tag->add_subfields( $tagsubfield => $itemvalue );
             $record->delete_field($tag);
             $record->insert_fields_ordered($tag);
-        } else {
-            $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
+            }
+            else {
+                $record->add_fields( $tagfield, " ", " ", $tagsubfield => $itemvalue );
+            }
         }
     }
     return $record;
@@ -1733,14 +1730,18 @@ sub TransformKohaToMarcOneField {
 
 =head2 TransformHtmlToXml
 
-=over 4
-
-$xml = TransformHtmlToXml( $tags, $subfields, $values, $indicator, $ind_tag, $auth_type )
+  $xml = TransformHtmlToXml( $tags, $subfields, $values, $indicator, 
+                             $ind_tag, $auth_type )
 
 $auth_type contains :
-- nothing : rebuild a biblio, un UNIMARC the encoding is in 100$a pos 26/27
-- UNIMARCAUTH : rebuild an authority. In UNIMARC, the encoding is in 100$a pos 13/14
-- ITEM : rebuild an item : in UNIMARC, 100$a, it's in the biblio ! (otherwise, we would get 2 100 fields !)
+
+=over
+
+=item - nothing : rebuild a biblio. In UNIMARC the encoding is in 100$a pos 26/27
+
+=item - UNIMARCAUTH : rebuild an authority. In UNIMARC, the encoding is in 100$a pos 13/14
+
+=item - ITEM : rebuild an item : in UNIMARC, 100$a, it's in the biblio ! (otherwise, we would get 2 100 fields !)
 
 =back
 
@@ -1954,8 +1955,14 @@ sub TransformHtmlToMarc {
             if ( $tag < 10 ) {                              # no code for theses fields
                                                             # in MARC editor, 000 contains the leader.
                 if ( $tag eq '000' ) {
-                    $record->leader( $cgi->param( $params->[ $j + 1 ] ) ) if length( $cgi->param( $params->[ $j + 1 ] ) ) == 24;
-
+                    # Force a fake leader even if not provided to avoid crashing
+                    # during decoding MARC record containing UTF-8 characters
+                    $record->leader(
+                        length( $cgi->param($params->[$j+1]) ) == 24
+                        ? $cgi->param( $params->[ $j + 1 ] )
+                        : '     nam a22        4500'
+                       )
+                    ;
                     # between 001 and 009 (included)
                 } elsif ( $cgi->param( $params->[ $j + 1 ] ) ne '' ) {
                     $newfield = MARC::Field->new( $tag, $cgi->param( $params->[ $j + 1 ] ), );
@@ -1991,11 +1998,7 @@ our $inverted_field_map;
 
 =head2 TransformMarcToKoha
 
-=over 4
-
-    $result = TransformMarcToKoha( $dbh, $record, $frameworkcode )
-
-=back
+  $result = TransformMarcToKoha( $dbh, $record, $frameworkcode )
 
 Extract data from a MARC bib record into a hashref representing
 Koha biblio, biblioitems, and items fields. 
@@ -2108,23 +2111,21 @@ sub _get_inverted_marc_field_map {
 
 =head2 _disambiguate
 
-=over 4
-
-$newkey = _disambiguate($table, $field);
+  $newkey = _disambiguate($table, $field);
 
 This is a temporary hack to distinguish between the
 following sets of columns when using TransformMarcToKoha.
 
-items.cn_source & biblioitems.cn_source
-items.cn_sort & biblioitems.cn_sort
+  items.cn_source & biblioitems.cn_source
+  items.cn_sort & biblioitems.cn_sort
 
 Columns that are currently NOT distinguished (FIXME
 due to lack of time to fully test) are:
 
-biblio.notes and biblioitems.notes
-biblionumber
-timestamp
-biblioitemnumber
+  biblio.notes and biblioitems.notes
+  biblionumber
+  timestamp
+  biblioitemnumber
 
 FIXME - this is necessary because prefixing each column
 name with the table name would require changing lots
@@ -2135,8 +2136,6 @@ version.  In the future, it would also be good to
 separate DB access and UI presentation field names
 more.
 
-=back
-
 =cut
 
 sub CountItemsIssued {
@@ -2160,15 +2159,12 @@ sub _disambiguate {
 
 =head2 get_koha_field_from_marc
 
-=over 4
-
-$result->{_disambiguate($table, $field)} = get_koha_field_from_marc($table,$field,$record,$frameworkcode);
+  $result->{_disambiguate($table, $field)} = 
+     get_koha_field_from_marc($table,$field,$record,$frameworkcode);
 
 Internal function to map data from the MARC record to a specific non-MARC field.
 FIXME: this is meant to replace TransformMarcToKohaOneField after more testing.
 
-=back
-
 =cut
 
 sub get_koha_field_from_marc {
@@ -2202,11 +2198,7 @@ sub get_koha_field_from_marc {
 
 =head2 TransformMarcToKohaOneField
 
-=over 4
-
-$result = TransformMarcToKohaOneField( $kohatable, $kohafield, $record, $result, $frameworkcode )
-
-=back
+  $result = TransformMarcToKohaOneField( $kohatable, $kohafield, $record, $result, $frameworkcode )
 
 =cut
 
@@ -2247,16 +2239,12 @@ sub TransformMarcToKohaOneField {
 
 =head2 PrepareItemrecordDisplay
 
-=over 4
-
-PrepareItemrecordDisplay($itemrecord,$bibnum,$itemumber,$frameworkcode);
+  PrepareItemrecordDisplay($itemrecord,$bibnum,$itemumber,$frameworkcode);
 
 Returns a hash with all the fields for Display a given item data in a template
 
 The $frameworkcode returns the item for the given frameworkcode, ONLY if bibnum is not provided
 
-=back
-
 =cut
 
 sub PrepareItemrecordDisplay {
@@ -2294,14 +2282,15 @@ sub PrepareItemrecordDisplay {
                 $subfield_data{repeatable} = $tagslib->{$tag}->{$subfield}->{repeatable};
                 $subfield_data{hidden}     = "display:none"
                   if $tagslib->{$tag}->{$subfield}->{hidden};
-                my ( $x, $value );
+                my ( $x, $defaultvalue );
                 if ($itemrecord) {
-                    ( $x, $value ) = _find_value( $tag, $subfield, $itemrecord );
+                    ( $x, $defaultvalue ) = _find_value( $tag, $subfield, $itemrecord );
                 }
-                if ( !defined $value ) {
-                    $value = q||;
+                $defaultvalue = $tagslib->{$tag}->{$subfield}->{defaultvalue} unless $defaultvalue;
+                if ( !defined $defaultvalue ) {
+                    $defaultvalue = q||;
                 }
-                $value =~ s/"/&quot;/g;
+                $defaultvalue =~ s/"/&quot;/g;
 
                 # search for itemcallnumber if applicable
                 if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
@@ -2310,7 +2299,7 @@ sub PrepareItemrecordDisplay {
                     my $CNsubfield = substr( C4::Context->preference('itemcallnumber'), 3, 1 );
                     my $temp = $itemrecord->field($CNtag) if ($itemrecord);
                     if ($temp) {
-                        $value = $temp->subfield($CNsubfield);
+                        $defaultvalue = $temp->subfield($CNsubfield);
                     }
                 }
                 if (   $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
@@ -2318,7 +2307,7 @@ sub PrepareItemrecordDisplay {
                     && $defaultvalues->{'callnumber'} ) {
                     my $temp = $itemrecord->field($subfield) if ($itemrecord);
                     unless ($temp) {
-                        $value = $defaultvalues->{'callnumber'} if $defaultvalues;
+                        $defaultvalue = $defaultvalues->{'callnumber'} if $defaultvalues;
                     }
                 }
                 if (   ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' )
@@ -2326,7 +2315,15 @@ sub PrepareItemrecordDisplay {
                     && $defaultvalues->{'branchcode'} ) {
                     my $temp = $itemrecord->field($subfield) if ($itemrecord);
                     unless ($temp) {
-                        $value = $defaultvalues->{branchcode} if $defaultvalues;
+                        $defaultvalue = $defaultvalues->{branchcode} if $defaultvalues;
+                    }
+                }
+                if (   ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.location' )
+                    && $defaultvalues
+                    && $defaultvalues->{'location'} ) {
+                    my $temp = $itemrecord->field($subfield) if ($itemrecord);
+                    unless ($temp) {
+                        $defaultvalue = $defaultvalues->{location} if $defaultvalues;
                     }
                 }
                 if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
@@ -2367,6 +2364,19 @@ sub PrepareItemrecordDisplay {
                             push @authorised_values, $itemtype;
                             $authorised_lib{$itemtype} = $description;
                         }
+                        #---- 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
+                                        ($class_source eq $default_source);
+                            push @authorised_values, $class_source;
+                            $authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'};
+                        }
 
                         #---- "true" authorised value
                     } else {
@@ -2381,14 +2391,14 @@ sub PrepareItemrecordDisplay {
                     $subfield_data{marc_value} = CGI::scrolling_list(
                         -name     => 'field_value',
                         -values   => \@authorised_values,
-                        -default  => "$value",
+                        -default  => "$defaultvalue",
                         -labels   => \%authorised_lib,
                         -size     => 1,
                         -tabindex => '',
                         -multiple => 0,
                     );
                 } else {
-                    $subfield_data{marc_value} = "<input type=\"text\" name=\"field_value\" value=\"$value\" size=\"50\" maxlength=\"255\" />";
+                    $subfield_data{marc_value} = "<input type=\"text\" name=\"field_value\" value=\"$defaultvalue\" size=\"50\" maxlength=\"255\" />";
                 }
                 push( @loop_data, \%subfield_data );
             }
@@ -2440,19 +2450,19 @@ sub PrepareItemrecordDisplay {
 
 =head2 ModZebra
 
-=over 4
+  ModZebra( $biblionumber, $op, $server, $oldRecord, $newRecord );
 
-ModZebra( $biblionumber, $op, $server, $oldRecord, $newRecord );
+$biblionumber is the biblionumber we want to index
 
-    $biblionumber is the biblionumber we want to index
-    $op is specialUpdate or delete, and is used to know what we want to do
-    $server is the server that we want to update
-    $oldRecord is the MARC::Record containing the previous version of the record.  This is used only when 
-      NoZebra=1, as NoZebra indexing needs to know the previous version of a record in order to
-      do an update.
-    $newRecord is the MARC::Record containing the new record. It is usefull only when NoZebra=1, and is used to know what to add to the nozebra database. (the record in mySQL being, if it exist, the previous record, the one just before the modif. We need both : the previous and the new one.
-    
-=back
+$op is specialUpdate or delete, and is used to know what we want to do
+
+$server is the server that we want to update
+
+$oldRecord is the MARC::Record containing the previous version of the record.  This is used only when 
+NoZebra=1, as NoZebra indexing needs to know the previous version of a record in order to
+do an update.
+
+$newRecord is the MARC::Record containing the new record. It is usefull only when NoZebra=1, and is used to know what to add to the nozebra database. (the record in mySQL being, if it exist, the previous record, the one just before the modif. We need both : the previous and the new one.
 
 =cut
 
@@ -2522,9 +2532,9 @@ sub ModZebra {
 
 =head2 GetNoZebraIndexes
 
-    %indexes = GetNoZebraIndexes;
-    
-    return the data from NoZebraIndexes syspref.
+  %indexes = GetNoZebraIndexes;
+
+return the data from NoZebraIndexes syspref.
 
 =cut
 
@@ -2546,13 +2556,15 @@ sub GetNoZebraIndexes {
 
 =head2 _DelBiblioNoZebra($biblionumber,$record,$server);
 
-    function to delete a biblio in NoZebra indexes
-    This function does NOT delete anything in database : it reads all the indexes entries
-    that have to be deleted & delete them in the hash
-    The SQL part is done either :
-    - after the Add if we are modifying a biblio (delete + add again)
-    - immediatly after this sub if we are doing a true deletion.
-    $server can be 'biblioserver' or 'authorityserver' : it indexes biblios or authorities (in the same table, $server being part of the table itself
+function to delete a biblio in NoZebra indexes
+This function does NOT delete anything in database : it reads all the indexes entries
+that have to be deleted & delete them in the hash
+
+The SQL part is done either :
+ - after the Add if we are modifying a biblio (delete + add again)
+ - immediatly after this sub if we are doing a true deletion.
+
+$server can be 'biblioserver' or 'authorityserver' : it indexes biblios or authorities (in the same table, $server being part of the table itself
 
 =cut
 
@@ -2664,9 +2676,11 @@ sub _DelBiblioNoZebra {
     return %result;
 }
 
-=head2 _AddBiblioNoZebra($biblionumber, $record, $server, %result);
+=head2 _AddBiblioNoZebra
+
+  _AddBiblioNoZebra($biblionumber, $record, $server, %result);
 
-    function to add a biblio in NoZebra indexes
+function to add a biblio in NoZebra indexes
 
 =cut
 
@@ -2804,9 +2818,7 @@ sub _AddBiblioNoZebra {
 
 =head2 _find_value
 
-=over 4
-
-($indicators, $value) = _find_value($tag, $subfield, $record,$encoding);
+  ($indicators, $value) = _find_value($tag, $subfield, $record,$encoding);
 
 Find the given $subfield in the given $tag in the given
 MARC::Record $record.  If the subfield is found, returns
@@ -2817,8 +2829,6 @@ PROPOSITION :
 Such a function is used in addbiblio AND additem and serial-edit and maybe could be used in Authorities.
 I suggest we export it from this module.
 
-=back
-
 =cut
 
 sub _find_value {
@@ -2847,15 +2857,12 @@ sub _find_value {
 
 =head2 _koha_marc_update_bib_ids
 
-=over 4
 
-_koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
+  _koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
 
 Internal function to add or update biblionumber and biblioitemnumber to
 the MARC XML.
 
-=back
-
 =cut
 
 sub _koha_marc_update_bib_ids {
@@ -2915,11 +2922,7 @@ sub _koha_marc_update_bib_ids {
 
 =head2 _koha_marc_update_biblioitem_cn_sort
 
-=over 4
-
-_koha_marc_update_biblioitem_cn_sort($marc, $biblioitem, $frameworkcode);
-
-=back
+  _koha_marc_update_biblioitem_cn_sort($marc, $biblioitem, $frameworkcode);
 
 Given a MARC bib record and the biblioitem hash, update the
 subfield that contains a copy of the value of biblioitems.cn_sort.
@@ -2954,14 +2957,10 @@ sub _koha_marc_update_biblioitem_cn_sort {
 
 =head2 _koha_add_biblio
 
-=over 4
-
-my ($biblionumber,$error) = _koha_add_biblio($dbh,$biblioitem);
+  my ($biblionumber,$error) = _koha_add_biblio($dbh,$biblioitem);
 
 Internal function to add a biblio ($biblio is a hash with the values)
 
-=back
-
 =cut
 
 sub _koha_add_biblio {
@@ -2970,8 +2969,10 @@ sub _koha_add_biblio {
     my $error;
 
     # set the series flag
-    my $serial = 0;
-    if ( $biblio->{'seriestitle'} ) { $serial = 1 }
+    unless (defined $biblio->{'serial'}){
+       $biblio->{'serial'} = 0;
+       if ( $biblio->{'seriestitle'} ) { $biblio->{'serial'} = 1 }
+    }
 
     my $query = "INSERT INTO biblio
         SET frameworkcode = ?,
@@ -2988,7 +2989,7 @@ sub _koha_add_biblio {
     my $sth = $dbh->prepare($query);
     $sth->execute(
         $frameworkcode, $biblio->{'author'},      $biblio->{'title'},         $biblio->{'unititle'}, $biblio->{'notes'},
-        $serial,        $biblio->{'seriestitle'}, $biblio->{'copyrightdate'}, $biblio->{'abstract'}
+        $biblio->{'serial'},        $biblio->{'seriestitle'}, $biblio->{'copyrightdate'}, $biblio->{'abstract'}
     );
 
     my $biblionumber = $dbh->{'mysql_insertid'};
@@ -3005,14 +3006,10 @@ sub _koha_add_biblio {
 
 =head2 _koha_modify_biblio
 
-=over 4
-
-my ($biblionumber,$error) == _koha_modify_biblio($dbh,$biblio,$frameworkcode);
+  my ($biblionumber,$error) == _koha_modify_biblio($dbh,$biblio,$frameworkcode);
 
 Internal function for updating the biblio table
 
-=back
-
 =cut
 
 sub _koha_modify_biblio {
@@ -3049,15 +3046,11 @@ sub _koha_modify_biblio {
 
 =head2 _koha_modify_biblioitem_nonmarc
 
-=over 4
-
-my ($biblioitemnumber,$error) = _koha_modify_biblioitem_nonmarc( $dbh, $biblioitem );
+  my ($biblioitemnumber,$error) = _koha_modify_biblioitem_nonmarc( $dbh, $biblioitem );
 
 Updates biblioitems row except for marc and marcxml, which should be changed
 via ModBiblioMarc
 
-=back
-
 =cut
 
 sub _koha_modify_biblioitem_nonmarc {
@@ -3118,14 +3111,10 @@ sub _koha_modify_biblioitem_nonmarc {
 
 =head2 _koha_add_biblioitem
 
-=over 4
-
-my ($biblioitemnumber,$error) = _koha_add_biblioitem( $dbh, $biblioitem );
+  my ($biblioitemnumber,$error) = _koha_add_biblioitem( $dbh, $biblioitem );
 
 Internal function to add a biblioitem
 
-=back
-
 =cut
 
 sub _koha_add_biblioitem {
@@ -3187,16 +3176,13 @@ sub _koha_add_biblioitem {
 
 =head2 _koha_delete_biblio
 
-=over 4
-
-$error = _koha_delete_biblio($dbh,$biblionumber);
+  $error = _koha_delete_biblio($dbh,$biblionumber);
 
 Internal sub for deleting from biblio table -- also saves to deletedbiblio
 
 C<$dbh> - the database handle
-C<$biblionumber> - the biblionumber of the biblio to be deleted
 
-=back
+C<$biblionumber> - the biblionumber of the biblio to be deleted
 
 =cut
 
@@ -3237,17 +3223,13 @@ sub _koha_delete_biblio {
 
 =head2 _koha_delete_biblioitems
 
-=over 4
-
-$error = _koha_delete_biblioitems($dbh,$biblioitemnumber);
+  $error = _koha_delete_biblioitems($dbh,$biblioitemnumber);
 
 Internal sub for deleting from biblioitems table -- also saves to deletedbiblioitems
 
 C<$dbh> - the database handle
 C<$biblionumber> - the biblioitemnumber of the biblioitem to be deleted
 
-=back
-
 =cut
 
 # FIXME: add error handling
@@ -3289,11 +3271,11 @@ sub _koha_delete_biblioitems {
 
 =head2 ModBiblioMarc
 
-    &ModBiblioMarc($newrec,$biblionumber,$frameworkcode);
-    
-    Add MARC data for a biblio to koha 
-    
-    Function exported, but should NOT be used, unless you really know what you're doing
+  &ModBiblioMarc($newrec,$biblionumber,$frameworkcode);
+
+Add MARC data for a biblio to koha 
+
+Function exported, but should NOT be used, unless you really know what you're doing
 
 =cut
 
@@ -3314,7 +3296,7 @@ sub ModBiblioMarc {
     # deal with UNIMARC field 100 (encoding) : create it if needed & set encoding to unicode
     if ( $encoding eq "UNIMARC" ) {
         my $string = $record->subfield( 100, "a" );
-        if ( ($string) && ( length( $record->subfield( 100, "a" ) ) == 35 ) ) {
+        if ( ($string) && ( length( $record->subfield( 100, "a" ) ) == 36 ) ) {
             my $f100 = $record->field(100);
             $record->delete_field($f100);
         } else {
@@ -3327,6 +3309,15 @@ sub ModBiblioMarc {
             $record->insert_grouped_field( MARC::Field->new( 100, "", "", "a" => $string ) );
         }
     }
+
+    #enhancement 5374: update transaction date (005) for marc21/unimarc
+    if($encoding =~ /MARC21|UNIMARC/) {
+      my @a= (localtime) [5,4,3,2,1,0]; $a[0]+=1900; $a[1]++;
+        # YY MM DD HH MM SS (update year and month)
+      my $f005= $record->field('005');
+      $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
+    }
+
     my $oldRecord;
     if ( C4::Context->preference("NoZebra") ) {
 
@@ -3343,27 +3334,27 @@ sub ModBiblioMarc {
 
 =head2 z3950_extended_services
 
-z3950_extended_services($serviceType,$serviceOptions,$record);
+  z3950_extended_services($serviceType,$serviceOptions,$record);
 
-    z3950_extended_services is used to handle all interactions with Zebra's extended serices package, which is employed to perform all management of the MARC data stored in Zebra.
+z3950_extended_services is used to handle all interactions with Zebra's extended serices package, which is employed to perform all management of the MARC data stored in Zebra.
 
 C<$serviceType> one of: itemorder,create,drop,commit,update,xmlupdate
 
 C<$serviceOptions> a has of key/value pairs. For instance, if service_type is 'update', $service_options should contain:
 
   action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate.
+ action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate.
 
 and maybe
 
-    recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number).
-    syntax => the record syntax (transfer syntax)
-    databaseName = Database from connection object
+  recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number).
+  syntax => the record syntax (transfer syntax)
+  databaseName = Database from connection object
 
-    To set serviceOptions, call set_service_options($serviceType)
+To set serviceOptions, call set_service_options($serviceType)
 
 C<$record> the record, if one is needed for the service type
 
-    A record should be in XML. You can convert it to XML from MARC by running it through marc2xml().
+A record should be in XML. You can convert it to XML from MARC by running it through marc2xml().
 
 =cut
 
@@ -3418,7 +3409,7 @@ sub z3950_extended_services {
 
 =head2 set_service_options
 
-my $serviceOptions = set_service_options($serviceType);
+  my $serviceOptions = set_service_options($serviceType);
 
 C<$serviceType> itemorder,create,drop,commit,update,xmlupdate
 
@@ -3447,24 +3438,23 @@ sub set_service_options {
     return $serviceOptions;
 }
 
-=head3 get_biblio_authorised_values
+=head2 get_biblio_authorised_values
 
-  find the types and values for all authorised values assigned to this biblio.
+find the types and values for all authorised values assigned to this biblio.
 
-  parameters:
+parameters:
     biblionumber
     MARC::Record of the bib
 
-  returns: a hashref mapping the authorised value to the value set for this biblionumber
-
-      $authorised_values = {
-                             'Scent'     => 'flowery',
-                             'Audience'  => 'Young Adult',
-                             'itemtypes' => 'SER',
-                           };
+returns: a hashref mapping the authorised value to the value set for this biblionumber
 
-  Notes: forlibrarian should probably be passed in, and called something different.
+  $authorised_values = {
+                       'Scent'     => 'flowery',
+                       'Audience'  => 'Young Adult',
+                       'itemtypes' => 'SER',
+                        };
 
+Notes: forlibrarian should probably be passed in, and called something different.
 
 =cut
 
@@ -3516,7 +3506,7 @@ __END__
 
 =head1 AUTHOR
 
-Koha Developement team <info@koha.org>
+Koha Development Team <http://koha-community.org/>
 
 Paul POULAIN paul.poulain@free.fr