bug_7264: [SIGNED-OFF] Branch popup on OPAC detail.Added opac_info field to branches...
[koha_gimpoz] / C4 / Items.pm
index 2da21cd..365c1b3 100644 (file)
@@ -26,14 +26,13 @@ use C4::Context;
 use C4::Koha;
 use C4::Biblio;
 use C4::Dates qw/format_date format_date_in_iso/;
 use C4::Koha;
 use C4::Biblio;
 use C4::Dates qw/format_date format_date_in_iso/;
+use C4::Search qw/SimpleSearch/;
 use MARC::Record;
 use C4::ClassSource;
 use C4::Log;
 use MARC::Record;
 use C4::ClassSource;
 use C4::Log;
-use C4::Branch;
-require C4::Reserves;
-use C4::Charset;
-use C4::Acquisition;
 use List::MoreUtils qw/any/;
 use List::MoreUtils qw/any/;
+use Data::Dumper; # used as part of logging item record changes, not just for
+                  # debugging; so please don't remove this
 
 use vars qw($VERSION @ISA @EXPORT);
 
 
 use vars qw($VERSION @ISA @EXPORT);
 
@@ -67,15 +66,23 @@ BEGIN {
         GetItemsByBiblioitemnumber
         GetItemsInfo
        GetItemsLocationInfo
         GetItemsByBiblioitemnumber
         GetItemsInfo
        GetItemsLocationInfo
+       GetHostItemsInfo
         get_itemnumbers_of
         get_itemnumbers_of
+       get_hostitemnumbers_of
         GetItemnumberFromBarcode
         GetBarcodeFromItemnumber
         GetItemnumberFromBarcode
         GetBarcodeFromItemnumber
-      GetHiddenItemnumbers
-
+        GetHiddenItemnumbers
                DelItemCheck
                MoveItemFromBiblio 
                GetLatestAcquisitions
         CartToShelf
                DelItemCheck
                MoveItemFromBiblio 
                GetLatestAcquisitions
         CartToShelf
+
+       GetAnalyticsCount
+        GetItemHolds
+
+
+        PrepareItemrecordDisplay
+
     );
 }
 
     );
 }
 
@@ -262,10 +269,7 @@ sub AddItem {
        my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
     $item->{'itemnumber'} = $itemnumber;
 
        my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
     $item->{'itemnumber'} = $itemnumber;
 
-    # create MARC tag representing item and add to bib
-    my $new_item_marc = _marc_from_item_hash($item, $frameworkcode, $unlinked_item_subfields);
-    _add_item_field_to_biblio($new_item_marc, $item->{'biblionumber'}, $frameworkcode );
-    #_add_item_field_to_biblio($new_item_marc, $item->{'biblionumber'}, $frameworkcode );
+    ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef );
    
     logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
     
    
     logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
     
@@ -398,6 +402,8 @@ Note that only columns that can be directly
 changed from the cataloging and serials
 item editors are included in this hash.
 
 changed from the cataloging and serials
 item editors are included in this hash.
 
+Returns item record
+
 =cut
 
 my %default_values_for_mod_from_marc = (
 =cut
 
 my %default_values_for_mod_from_marc = (
@@ -416,6 +422,7 @@ my %default_values_for_mod_from_marc = (
     itemnotes            => undef, 
     itype                => undef, 
     location             => undef, 
     itemnotes            => undef, 
     itype                => undef, 
     location             => undef, 
+    permanent_location   => undef,
     materials            => undef, 
     notforloan           => 0,
     paidfor              => undef, 
     materials            => undef, 
     notforloan           => 0,
     paidfor              => undef, 
@@ -446,13 +453,13 @@ sub ModItemFromMarc {
     }
     my $unlinked_item_subfields = _get_unlinked_item_subfields( $localitemmarc, $frameworkcode );
 
     }
     my $unlinked_item_subfields = _get_unlinked_item_subfields( $localitemmarc, $frameworkcode );
 
-    return ModItem($item, $biblionumber, $itemnumber, $dbh, $frameworkcode, $unlinked_item_subfields); 
+    ModItem($item, $biblionumber, $itemnumber, $dbh, $frameworkcode, $unlinked_item_subfields); 
+    return $item;
 }
 
 =head2 ModItem
 
 }
 
 =head2 ModItem
 
-  ModItem({ column => $newvalue }, $biblionumber, 
-                  $itemnumber[, $original_item_marc]);
+  ModItem({ column => $newvalue }, $biblionumber, $itemnumber);
 
 Change one or more columns in an item record and update
 the MARC representation of the item.
 
 Change one or more columns in an item record and update
 the MARC representation of the item.
@@ -495,6 +502,9 @@ sub ModItem {
     };
 
     $item->{'itemnumber'} = $itemnumber or return undef;
     };
 
     $item->{'itemnumber'} = $itemnumber or return undef;
+
+    $item->{onloan} = undef if $item->{itemlost};
+
     _set_derived_columns_for_mod($item);
     _do_column_fixes_for_mod($item);
     # FIXME add checks
     _set_derived_columns_for_mod($item);
     _do_column_fixes_for_mod($item);
     # FIXME add checks
@@ -507,18 +517,11 @@ sub ModItem {
     # update items table
     _koha_modify_item($item);
 
     # update items table
     _koha_modify_item($item);
 
-    # update biblio MARC XML
-    my $whole_item = GetItem($itemnumber) or die "FAILED GetItem($itemnumber)";
+    # request that bib be reindexed so that searching on current
+    # item status is possible
+    ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
 
 
-    unless (defined $unlinked_item_subfields) {
-        $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($whole_item->{'more_subfields_xml'});
-    }
-    my $new_item_marc = _marc_from_item_hash($whole_item, $frameworkcode, $unlinked_item_subfields) 
-        or die "FAILED _marc_from_item_hash($whole_item, $frameworkcode)";
-    
-    #_replace_item_field_in_biblio($new_item_marc, $biblionumber, $itemnumber, $frameworkcode);
-       ($new_item_marc       eq '0') and die "$new_item_marc is '0', not hashref";  # logaction line would crash anyway
-    logaction("CATALOGUING", "MODIFY", $itemnumber, $new_item_marc->as_formatted) if C4::Context->preference("CataloguingLog");
+    logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item)) if C4::Context->preference("CataloguingLog");
 }
 
 =head2 ModItemTransfer
 }
 
 =head2 ModItemTransfer
@@ -584,6 +587,7 @@ sub DelItem {
     # backup the record
     my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
     $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
     # backup the record
     my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
     $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
+    # This last update statement makes that the timestamp column in deleteditems is updated too. If you remove these lines, please add a line to update the timestamp separately. See Bugzilla report 7146 and Biblio.pm (DelBiblio).
 
     #search item field code
     logaction("CATALOGUING", "DELETE", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
 
     #search item field code
     logaction("CATALOGUING", "DELETE", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
@@ -633,6 +637,7 @@ item that has a given branch code.
 
 sub CheckItemPreSave {
     my $item_ref = shift;
 
 sub CheckItemPreSave {
     my $item_ref = shift;
+    require C4::Branch;
 
     my %errors = ();
 
 
     my %errors = ();
 
@@ -649,7 +654,7 @@ sub CheckItemPreSave {
 
     # check for valid home branch
     if (exists $item_ref->{'homebranch'} and defined $item_ref->{'homebranch'}) {
 
     # check for valid home branch
     if (exists $item_ref->{'homebranch'} and defined $item_ref->{'homebranch'}) {
-        my $branch_name = GetBranchName($item_ref->{'homebranch'});
+        my $branch_name = C4::Branch::GetBranchName($item_ref->{'homebranch'});
         unless (defined $branch_name) {
             # relies on fact that branches.branchname is a non-NULL column,
             # so GetBranchName returns undef only if branch does not exist
         unless (defined $branch_name) {
             # relies on fact that branches.branchname is a non-NULL column,
             # so GetBranchName returns undef only if branch does not exist
@@ -659,7 +664,7 @@ sub CheckItemPreSave {
 
     # check for valid holding branch
     if (exists $item_ref->{'holdingbranch'} and defined $item_ref->{'holdingbranch'}) {
 
     # check for valid holding branch
     if (exists $item_ref->{'holdingbranch'} and defined $item_ref->{'holdingbranch'}) {
-        my $branch_name = GetBranchName($item_ref->{'holdingbranch'});
+        my $branch_name = C4::Branch::GetBranchName($item_ref->{'holdingbranch'});
         unless (defined $branch_name) {
             # relies on fact that branches.branchname is a non-NULL column,
             # so GetBranchName returns undef only if branch does not exist
         unless (defined $branch_name) {
             # relies on fact that branches.branchname is a non-NULL column,
             # so GetBranchName returns undef only if branch does not exist
@@ -1120,16 +1125,12 @@ sub GetItemsByBiblioitemnumber {
 
 =head2 GetItemsInfo
 
 
 =head2 GetItemsInfo
 
-  @results = GetItemsInfo($biblionumber, $type);
-
-Returns information about books with the given biblionumber.
+  @results = GetItemsInfo($biblionumber);
 
 
-C<$type> may be either C<intra> or anything else. If it is not set to
-C<intra>, then the search will exclude lost, very overdue, and
-withdrawn items.
+Returns information about items with the given biblionumber.
 
 C<GetItemsInfo> returns a list of references-to-hash. Each element
 
 C<GetItemsInfo> returns a list of references-to-hash. Each element
-contains a number of keys. Most of them are table items from the
+contains a number of keys. Most of them are attributes from the
 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
 Koha database. Other keys include:
 
 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
 Koha database. Other keys include:
 
@@ -1165,7 +1166,7 @@ If this is set, it is set to C<One Order>.
 =cut
 
 sub GetItemsInfo {
 =cut
 
 sub GetItemsInfo {
-    my ( $biblionumber, $type ) = @_;
+    my ( $biblionumber ) = @_;
     my $dbh   = C4::Context->dbh;
     # note biblioitems.* must be avoided to prevent large marc and marcxml fields from killing performance.
     my $query = "
     my $dbh   = C4::Context->dbh;
     # note biblioitems.* must be avoided to prevent large marc and marcxml fields from killing performance.
     my $query = "
@@ -1185,14 +1186,17 @@ sub GetItemsInfo {
            items.notforloan as itemnotforloan,
            itemtypes.description,
            itemtypes.notforloan as notforloan_per_itemtype,
            items.notforloan as itemnotforloan,
            itemtypes.description,
            itemtypes.notforloan as notforloan_per_itemtype,
-           branchurl
+           holding.branchurl,
+           holding.branchname,
+           holding.opac_info as branch_opac_info
      FROM items
      FROM items
-     LEFT JOIN branches ON items.homebranch = branches.branchcode
+     LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode
+     LEFT JOIN branches AS home ON items.homebranch=home.branchcode
      LEFT JOIN biblio      ON      biblio.biblionumber     = items.biblionumber
      LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
      LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
      . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype');
      LEFT JOIN biblio      ON      biblio.biblionumber     = items.biblionumber
      LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
      LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
      . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype');
-    $query .= " WHERE items.biblionumber = ? ORDER BY branches.branchname,items.dateaccessioned desc" ;
+    $query .= " WHERE items.biblionumber = ? ORDER BY home.branchname,items.dateaccessioned desc" ;
     my $sth = $dbh->prepare($query);
     $sth->execute($biblionumber);
     my $i = 0;
     my $sth = $dbh->prepare($query);
     $sth->execute($biblionumber);
     my $i = 0;
@@ -1207,13 +1211,13 @@ sub GetItemsInfo {
        my $ssth = $dbh->prepare("SELECT serialseq,publisheddate from serialitems left join serial on serialitems.serialid=serial.serialid where serialitems.itemnumber=? "); 
        while ( my $data = $sth->fetchrow_hashref ) {
         my $datedue = '';
        my $ssth = $dbh->prepare("SELECT serialseq,publisheddate from serialitems left join serial on serialitems.serialid=serial.serialid where serialitems.itemnumber=? "); 
        while ( my $data = $sth->fetchrow_hashref ) {
         my $datedue = '';
-        my $count_reserves;
         $isth->execute( $data->{'itemnumber'} );
         if ( my $idata = $isth->fetchrow_hashref ) {
             $data->{borrowernumber} = $idata->{borrowernumber};
             $data->{cardnumber}     = $idata->{cardnumber};
             $data->{surname}     = $idata->{surname};
             $data->{firstname}     = $idata->{firstname};
         $isth->execute( $data->{'itemnumber'} );
         if ( my $idata = $isth->fetchrow_hashref ) {
             $data->{borrowernumber} = $idata->{borrowernumber};
             $data->{cardnumber}     = $idata->{cardnumber};
             $data->{surname}     = $idata->{surname};
             $data->{firstname}     = $idata->{firstname};
+            $data->{lastreneweddate} = $idata->{lastreneweddate};
             $datedue                = $idata->{'date_due'};
         if (C4::Context->preference("IndependantBranches")){
         my $userenv = C4::Context->userenv;
             $datedue                = $idata->{'date_due'};
         if (C4::Context->preference("IndependantBranches")){
         my $userenv = C4::Context->userenv;
@@ -1227,14 +1231,6 @@ sub GetItemsInfo {
                        ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
                        $serial = 1;
         }
                        ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
                        $serial = 1;
         }
-               if ( $datedue eq '' ) {
-            my ( $restype, $reserves ) =
-              C4::Reserves::CheckReserves( $data->{'itemnumber'} );
-# Previous conditional check with if ($restype) is not needed because a true
-# result for one item will result in subsequent items defaulting to this true
-# value.
-            $count_reserves = $restype;
-        }
         #get branch information.....
         my $bsth = $dbh->prepare(
             "SELECT * FROM branches WHERE branchcode = ?
         #get branch information.....
         my $bsth = $dbh->prepare(
             "SELECT * FROM branches WHERE branchcode = ?
@@ -1245,7 +1241,6 @@ sub GetItemsInfo {
             $data->{'branchname'} = $bdata->{'branchname'};
         }
         $data->{'datedue'}        = $datedue;
             $data->{'branchname'} = $bdata->{'branchname'};
         }
         $data->{'datedue'}        = $datedue;
-        $data->{'count_reserves'} = $count_reserves;
 
         # get notforloan complete status if applicable
         my $sthnflstatus = $dbh->prepare(
 
         # get notforloan complete status if applicable
         my $sthnflstatus = $dbh->prepare(
@@ -1406,6 +1401,46 @@ sub GetItemsLocationInfo {
        return @results;
 }
 
        return @results;
 }
 
+=head2 GetHostItemsInfo
+
+       $hostiteminfo = GetHostItemsInfo($hostfield);
+       Returns the iteminfo for items linked to records via a host field
+
+=cut
+
+sub GetHostItemsInfo {
+       my ($record) = @_;
+       my @returnitemsInfo;
+
+       if (C4::Context->preference('marcflavour') eq 'MARC21' ||
+        C4::Context->preference('marcflavour') eq 'NORMARC'){
+           foreach my $hostfield ( $record->field('773') ) {
+               my $hostbiblionumber = $hostfield->subfield("0");
+               my $linkeditemnumber = $hostfield->subfield("9");
+               my @hostitemInfos = GetItemsInfo($hostbiblionumber);
+               foreach my $hostitemInfo (@hostitemInfos){
+                       if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){
+                               push (@returnitemsInfo,$hostitemInfo);
+                               last;
+                       }
+               }
+           }
+       } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC'){
+           foreach my $hostfield ( $record->field('461') ) {
+               my $hostbiblionumber = $hostfield->subfield("0");
+               my $linkeditemnumber = $hostfield->subfield("9");
+               my @hostitemInfos = GetItemsInfo($hostbiblionumber);
+               foreach my $hostitemInfo (@hostitemInfos){
+                       if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){
+                               push (@returnitemsInfo,$hostitemInfo);
+                               last;
+                       }
+               }
+           }
+       }
+       return @returnitemsInfo;
+}
+
 
 =head2 GetLastAcquisitions
 
 
 =head2 GetLastAcquisitions
 
@@ -1493,6 +1528,53 @@ sub get_itemnumbers_of {
     return \%itemnumbers_of;
 }
 
     return \%itemnumbers_of;
 }
 
+=head2 get_hostitemnumbers_of
+
+  my @itemnumbers_of = get_hostitemnumbers_of($biblionumber);
+
+Given a biblionumber, return the list of corresponding itemnumbers that are linked to it via host fields
+
+Return a reference on a hash where key is a biblionumber and values are
+references on array of itemnumbers.
+
+=cut
+
+
+sub get_hostitemnumbers_of {
+       my ($biblionumber) = @_;
+       my $marcrecord = GetMarcBiblio($biblionumber);
+        my (@returnhostitemnumbers,$tag, $biblio_s, $item_s);
+       
+       my $marcflavor = C4::Context->preference('marcflavour');
+       if ($marcflavor eq 'MARC21' || $marcflavor eq 'NORMARC') {
+        $tag='773';
+        $biblio_s='0';
+        $item_s='9';
+    } elsif ($marcflavor eq 'UNIMARC') {
+        $tag='461';
+        $biblio_s='0';
+        $item_s='9';
+    }
+
+    foreach my $hostfield ( $marcrecord->field($tag) ) {
+        my $hostbiblionumber = $hostfield->subfield($biblio_s);
+        my $linkeditemnumber = $hostfield->subfield($item_s);
+        my @itemnumbers;
+        if (my $itemnumbers = get_itemnumbers_of($hostbiblionumber)->{$hostbiblionumber})
+        {
+            @itemnumbers = @$itemnumbers;
+        }
+        foreach my $itemnumber (@itemnumbers){
+            if ($itemnumber eq $linkeditemnumber){
+                push (@returnhostitemnumbers,$itemnumber);
+                last;
+            }
+        }
+    }
+    return @returnhostitemnumbers;
+}
+
+
 =head2 GetItemnumberFromBarcode
 
   $result = GetItemnumberFromBarcode($barcode);
 =head2 GetItemnumberFromBarcode
 
   $result = GetItemnumberFromBarcode($barcode);
@@ -1542,41 +1624,45 @@ sub GetHiddenItemnumbers {
     my @resultitems;
 
     my $yaml = C4::Context->preference('OpacHiddenItems');
     my @resultitems;
 
     my $yaml = C4::Context->preference('OpacHiddenItems');
+    $yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
     my $hidingrules;
     eval {
     my $hidingrules;
     eval {
-       $hidingrules = YAML::Load($yaml);
+        $hidingrules = YAML::Load($yaml);
     };
     if ($@) {
     };
     if ($@) {
-       warn "Unable to parse OpacHiddenItems syspref : $@";
-       return ();
-    } else {
+        warn "Unable to parse OpacHiddenItems syspref : $@";
+        return ();
+    }
     my $dbh = C4::Context->dbh;
 
     my $dbh = C4::Context->dbh;
 
-       # For each item
-       foreach my $item (@items) {
+    # For each item
+    foreach my $item (@items) {
 
 
-           # We check each rule
-           foreach my $field (keys %$hidingrules) {
-               my $query = "SELECT $field from items where itemnumber = ?";
-               my $sth = $dbh->prepare($query);        
-               $sth->execute($item->{'itemnumber'});
-               my ($result) = $sth->fetchrow;
+        # We check each rule
+        foreach my $field (keys %$hidingrules) {
+            my $val;
+            if (exists $item->{$field}) {
+                $val = $item->{$field};
+            }
+            else {
+                my $query = "SELECT $field from items where itemnumber = ?";
+                $val = $dbh->selectrow_array($query, undef, $item->{'itemnumber'});
+            }
+            $val = '' unless defined $val;
 
 
-               # If the results matches the values in the yaml file
-               if (any { $result eq $_ } @{$hidingrules->{$field}}) {
+            # If the results matches the values in the yaml file
+            if (any { $val eq $_ } @{$hidingrules->{$field}}) {
 
 
-                   # We add the itemnumber to the list
-                   push @resultitems, $item->{'itemnumber'};       
+                # We add the itemnumber to the list
+                push @resultitems, $item->{'itemnumber'};
 
 
-                   # If at least one rule matched for an item, no need to test the others
-                   last;
-               }
-           }
-       }
-       return @resultitems;
+                # If at least one rule matched for an item, no need to test the others
+                last;
+            }
+        }
     }
     }
-
- }
+    return @resultitems;
+}
 
 =head3 get_item_authorised_values
 
 
 =head3 get_item_authorised_values
 
@@ -1982,9 +2068,9 @@ sub _koha_new_item {
             homebranch          = ?,
             price               = ?,
             replacementprice    = ?,
             homebranch          = ?,
             price               = ?,
             replacementprice    = ?,
-            replacementpricedate = NOW(),
+            replacementpricedate = ?,
             datelastborrowed    = ?,
             datelastborrowed    = ?,
-            datelastseen        = NOW(),
+            datelastseen        = ?,
             stack               = ?,
             notforloan          = ?,
             damaged             = ?,
             stack               = ?,
             notforloan          = ?,
             damaged             = ?,
@@ -1996,6 +2082,7 @@ sub _koha_new_item {
             holdingbranch       = ?,
             paidfor             = ?,
             location            = ?,
             holdingbranch       = ?,
             paidfor             = ?,
             location            = ?,
+            permanent_location            = ?,
             onloan              = ?,
             issues              = ?,
             renewals            = ?,
             onloan              = ?,
             issues              = ?,
             renewals            = ?,
@@ -2012,6 +2099,7 @@ sub _koha_new_item {
             stocknumber         = ?
           ";
     my $sth = $dbh->prepare($query);
             stocknumber         = ?
           ";
     my $sth = $dbh->prepare($query);
+    my $today = C4::Dates->today('iso');
    $sth->execute(
             $item->{'biblionumber'},
             $item->{'biblioitemnumber'},
    $sth->execute(
             $item->{'biblionumber'},
             $item->{'biblioitemnumber'},
@@ -2021,7 +2109,9 @@ sub _koha_new_item {
             $item->{'homebranch'},
             $item->{'price'},
             $item->{'replacementprice'},
             $item->{'homebranch'},
             $item->{'price'},
             $item->{'replacementprice'},
+            $item->{'replacementpricedate'} || $today,
             $item->{datelastborrowed},
             $item->{datelastborrowed},
+            $item->{datelastseen} || $today,
             $item->{stack},
             $item->{'notforloan'},
             $item->{'damaged'},
             $item->{stack},
             $item->{'notforloan'},
             $item->{'damaged'},
@@ -2033,6 +2123,7 @@ sub _koha_new_item {
             $item->{'holdingbranch'},
             $item->{'paidfor'},
             $item->{'location'},
             $item->{'holdingbranch'},
             $item->{'paidfor'},
             $item->{'location'},
+            $item->{'permanent_location'},
             $item->{'onloan'},
             $item->{'issues'},
             $item->{'renewals'},
             $item->{'onloan'},
             $item->{'issues'},
             $item->{'renewals'},
@@ -2048,10 +2139,15 @@ sub _koha_new_item {
             $item->{'copynumber'},
             $item->{'stocknumber'},
     );
             $item->{'copynumber'},
             $item->{'stocknumber'},
     );
-    my $itemnumber = $dbh->{'mysql_insertid'};
+
+    my $itemnumber;
     if ( defined $sth->errstr ) {
         $error.="ERROR in _koha_new_item $query".$sth->errstr;
     }
     if ( defined $sth->errstr ) {
         $error.="ERROR in _koha_new_item $query".$sth->errstr;
     }
+    else {
+        $itemnumber = $dbh->{'mysql_insertid'};
+    }
+
     return ( $itemnumber, $error );
 }
 
     return ( $itemnumber, $error );
 }
 
@@ -2074,59 +2170,19 @@ sub MoveItemFromBiblio {
     $sth = $dbh->prepare("UPDATE items SET biblioitemnumber = ?, biblionumber = ? WHERE itemnumber = ? AND biblionumber = ?");
     my $return = $sth->execute($tobiblioitem, $tobiblio, $itemnumber, $frombiblio);
     if ($return == 1) {
     $sth = $dbh->prepare("UPDATE items SET biblioitemnumber = ?, biblionumber = ? WHERE itemnumber = ? AND biblionumber = ?");
     my $return = $sth->execute($tobiblioitem, $tobiblio, $itemnumber, $frombiblio);
     if ($return == 1) {
-
-       # Getting framework
-       my $frameworkcode = GetFrameworkCode($frombiblio);
-
-       # Getting marc field for itemnumber
-       my ($itemtag, $itemsubfield) = GetMarcFromKohaField('items.itemnumber', $frameworkcode);
-
-       # Getting the record we want to move the item from
-       my $record = GetMarcBiblio($frombiblio);
-
-       # The item we want to move
-       my $item;
-
-       # For each item
-       foreach my $fielditem ($record->field($itemtag)){
-               # If it is the item we want to move
-               if ($fielditem->subfield($itemsubfield) == $itemnumber) {
-                   # We save it
-                   $item = $fielditem;
-                   # Then delete it from the record
-                   $record->delete_field($fielditem) 
-               }
-       }
-
-       # If we found an item (should always true, except in case of database-marcxml inconsistency)
-       if ($item) {
-
+        ModZebra( $tobiblio, "specialUpdate", "biblioserver", undef, undef );
+        ModZebra( $frombiblio, "specialUpdate", "biblioserver", undef, undef );
            # Checking if the item we want to move is in an order 
            # Checking if the item we want to move is in an order 
-           my $order = GetOrderFromItemnumber($itemnumber);
+        require C4::Acquisition;
+        my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber);
            if ($order) {
            if ($order) {
-               # Replacing the biblionumber within the order if necessary
-               $order->{'biblionumber'} = $tobiblio;
-               ModOrder($order);
+                   # Replacing the biblionumber within the order if necessary
+                   $order->{'biblionumber'} = $tobiblio;
+               C4::Acquisition::ModOrder($order);
            }
            }
-
-           # Saving the modification
-           #ModBiblioMarc($record, $frombiblio, $frameworkcode);
-
-           # Getting the record we want to move the item to
-           #$record = GetMarcBiblio($tobiblio);
-
-           # Inserting the previously saved item
-           #$record->insert_fields_ordered($item);     
-
-           # Saving the modification
-           #ModBiblioMarc($record, $tobiblio, $frameworkcode);
-
-       } else {
-           return undef;
+        return $tobiblio;
        }
        }
-    } else {
-       return undef;
-    }
+    return;
 }
 
 =head2 DelItemCheck
 }
 
 =head2 DelItemCheck
@@ -2141,35 +2197,39 @@ sub DelItemCheck {
     my ( $dbh, $biblionumber, $itemnumber ) = @_;
     my $error;
 
     my ( $dbh, $biblionumber, $itemnumber ) = @_;
     my $error;
 
+        my $countanalytics=GetAnalyticsCount($itemnumber);
+
+
     # check that there is no issue on this item before deletion.
     my $sth=$dbh->prepare("select * from issues i where i.itemnumber=?");
     $sth->execute($itemnumber);
 
     my $item = GetItem($itemnumber);
     # check that there is no issue on this item before deletion.
     my $sth=$dbh->prepare("select * from issues i where i.itemnumber=?");
     $sth->execute($itemnumber);
 
     my $item = GetItem($itemnumber);
-    my $onloan = $sth->fetchrow;
-    if ($onloan) {
-        $error = "book_on_loan";
+    my $onloan=$sth->fetchrow;
+
+    if ($onloan){
+        $error = "book_on_loan" 
     }
     }
-    elsif (C4::Context->preference("IndependantBranches") and (C4::Context->userenv->{branch} ne $item->{C4::Context->preference("HomeOrHoldingBranch")||'homebranch'})){
+    elsif ( !(C4::Context->userenv->{flags} & 1) and
+            C4::Context->preference("IndependantBranches") and
+           (C4::Context->userenv->{branch} ne
+             $item->{C4::Context->preference("HomeOrHoldingBranch")||'homebranch'}) )
+    {
         $error = "not_same_branch";
         $error = "not_same_branch";
-    } 
-    else {
-       if ($onloan){ 
-           $error = "book_on_loan" 
-       }
-       else {
-           # check it doesnt have a waiting reserve
-           $sth=$dbh->prepare("SELECT * FROM reserves WHERE (found = 'W' or found = 'T') AND itemnumber = ?");
-           $sth->execute($itemnumber);
-           my $reserve=$sth->fetchrow;
-           if ($reserve) {
-               $error = "book_reserved";
-           } 
-           else {
-               DelItem($dbh, $biblionumber, $itemnumber);
-               return 1;
-           }
-       }
+    }
+       else{
+        # check it doesnt have a waiting reserve
+        $sth=$dbh->prepare("SELECT * FROM reserves WHERE (found = 'W' or found = 'T') AND itemnumber = ?");
+        $sth->execute($itemnumber);
+        my $reserve=$sth->fetchrow;
+        if ($reserve){
+            $error = "book_reserved";
+        } elsif ($countanalytics > 0){
+               $error = "linked_analytics";
+       } else {
+            DelItem($dbh, $biblionumber, $itemnumber);
+            return 1;
+        }
     }
     return $error;
 }
     }
     return $error;
 }
@@ -2203,7 +2263,6 @@ sub _koha_modify_item {
         $error.="ERROR in _koha_modify_item $query".$dbh->errstr;
         warn $error;
     }
         $error.="ERROR in _koha_modify_item $query".$dbh->errstr;
         warn $error;
     }
-    ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef );
     return ($item->{'itemnumber'},$error);
 }
 
     return ($item->{'itemnumber'},$error);
 }
 
@@ -2288,68 +2347,6 @@ sub _marc_from_item_hash {
     return $item_marc;
 }
 
     return $item_marc;
 }
 
-=head2 _add_item_field_to_biblio
-
-  _add_item_field_to_biblio($item_marc, $biblionumber, $frameworkcode);
-
-Adds the fields from a MARC record containing the
-representation of a Koha item record to the MARC
-biblio record.  The input C<$item_marc> record
-is expect to contain just one field, the embedded
-item information field.
-
-=cut
-
-sub _add_item_field_to_biblio {
-    my ($item_marc, $biblionumber, $frameworkcode) = @_;
-
-    my $biblio_marc = GetMarcBiblio($biblionumber);
-    foreach my $field ($item_marc->fields()) {
-        $biblio_marc->append_fields($field);
-    }
-
-    ModBiblioMarc($biblio_marc, $biblionumber, $frameworkcode);
-}
-
-=head2 _replace_item_field_in_biblio
-
-  &_replace_item_field_in_biblio($item_marc, $biblionumber, $itemnumber, $frameworkcode)
-
-Given a MARC::Record C<$item_marc> containing one tag with the MARC 
-representation of the item, examine the biblio MARC
-for the corresponding tag for that item and 
-replace it with the tag from C<$item_marc>.
-
-=cut
-
-sub _replace_item_field_in_biblio {
-    my ($ItemRecord, $biblionumber, $itemnumber, $frameworkcode) = @_;
-    my $dbh = C4::Context->dbh;
-    
-    # get complete MARC record & replace the item field by the new one
-    my $completeRecord = GetMarcBiblio($biblionumber);
-    my ($itemtag,$itemsubfield) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
-    my $itemField = $ItemRecord->field($itemtag);
-    my @items = $completeRecord->field($itemtag);
-    my $found = 0;
-    foreach (@items) {
-        if ($_->subfield($itemsubfield) eq $itemnumber) {
-            $_->replace_with($itemField);
-            $found = 1;
-        }
-    }
-  
-    unless ($found) { 
-        # If we haven't found the matching field,
-        # just add it.  However, this means that
-        # there is likely a bug.
-        $completeRecord->append_fields($itemField);
-    }
-
-    # save the record
-    #ModBiblioMarc($completeRecord, $biblionumber, $frameworkcode);
-}
-
 =head2 _repack_item_errors
 
 Add an error message hash generated by C<CheckItemPreSave>
 =head2 _repack_item_errors
 
 Add an error message hash generated by C<CheckItemPreSave>
@@ -2436,9 +2433,9 @@ sub _get_unlinked_subfields_xml {
 
 sub  _parse_unlinked_item_subfields_from_xml {
     my $xml = shift;
 
 sub  _parse_unlinked_item_subfields_from_xml {
     my $xml = shift;
-
+    require C4::Charset;
     return unless defined $xml and $xml ne "";
     return unless defined $xml and $xml ne "";
-    my $marc = MARC::Record->new_from_xml(StripNonXmlChars($xml),'UTF-8');
+    my $marc = MARC::Record->new_from_xml(C4::Charset::StripNonXmlChars($xml),'UTF-8');
     my $unlinked_subfields = [];
     my @fields = $marc->fields();
     if ($#fields > -1) {
     my $unlinked_subfields = [];
     my @fields = $marc->fields();
     if ($#fields > -1) {
@@ -2449,4 +2446,317 @@ sub  _parse_unlinked_item_subfields_from_xml {
     return $unlinked_subfields;
 }
 
     return $unlinked_subfields;
 }
 
+=head2 GetAnalyticsCount
+
+  $count= &GetAnalyticsCount($itemnumber)
+
+counts Usage of itemnumber in Analytical bibliorecords. 
+
+=cut
+
+sub GetAnalyticsCount {
+    my ($itemnumber) = @_;
+    if (C4::Context->preference('NoZebra')) {
+        # Read the index Koha-Auth-Number for this authid and count the lines
+        my $result = C4::Search::NZanalyse("hi=$itemnumber");
+        my @tab = split /;/,$result;
+        return scalar @tab;
+    } else {
+        ### ZOOM search here
+        my $query;
+        $query= "hi=".$itemnumber;
+                my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
+        return ($result);
+    }
+}
+
+=head2 GetItemHolds
+
+=over 4
+$holds = &GetItemHolds($biblionumber, $itemnumber);
+
+=back
+
+This function return the count of holds with $biblionumber and $itemnumber
+
+=cut
+
+sub GetItemHolds {
+    my ($biblionumber, $itemnumber) = @_;
+    my $holds;
+    my $dbh            = C4::Context->dbh;
+    my $query          = "SELECT count(*)
+        FROM  reserves
+        WHERE biblionumber=? AND itemnumber=?";
+    my $sth = $dbh->prepare($query);
+    $sth->execute($biblionumber, $itemnumber);
+    $holds = $sth->fetchrow;
+    return $holds;
+}
+=head1  OTHER FUNCTIONS
+
+=head2 _find_value
+
+  ($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
+the (indicators, value) pair; otherwise, (undef, undef) is
+returned.
+
+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.
+
+=cut
+
+sub _find_value {
+    my ( $tagfield, $insubfield, $record, $encoding ) = @_;
+    my @result;
+    my $indicator;
+    if ( $tagfield < 10 ) {
+        if ( $record->field($tagfield) ) {
+            push @result, $record->field($tagfield)->data();
+        } else {
+            push @result, "";
+        }
+    } else {
+        foreach my $field ( $record->field($tagfield) ) {
+            my @subfields = $field->subfields();
+            foreach my $subfield (@subfields) {
+                if ( @$subfield[0] eq $insubfield ) {
+                    push @result, @$subfield[1];
+                    $indicator = $field->indicator(1) . $field->indicator(2);
+                }
+            }
+        }
+    }
+    return ( $indicator, @result );
+}
+
+
+=head2 PrepareItemrecordDisplay
+
+  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
+
+=cut
+
+sub PrepareItemrecordDisplay {
+
+    my ( $bibnum, $itemnum, $defaultvalues, $frameworkcode ) = @_;
+
+    my $dbh = C4::Context->dbh;
+    $frameworkcode = &GetFrameworkCode($bibnum) if $bibnum;
+    my ( $itemtagfield, $itemtagsubfield ) = &GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+    my $tagslib = &GetMarcStructure( 1, $frameworkcode );
+
+    # return nothing if we don't have found an existing framework.
+    return q{} unless $tagslib;
+    my $itemrecord;
+    if ($itemnum) {
+        $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum );
+    }
+    my @loop_data;
+    my $authorised_values_sth = $dbh->prepare( "SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib" );
+    foreach my $tag ( sort keys %{$tagslib} ) {
+        my $previous_tag = '';
+        if ( $tag ne '' ) {
+
+            # loop through each subfield
+            my $cntsubf;
+            foreach my $subfield ( sort keys %{ $tagslib->{$tag} } ) {
+                next if ( subfield_is_koha_internal_p($subfield) );
+                next if ( $tagslib->{$tag}->{$subfield}->{'tab'} ne "10" );
+                my %subfield_data;
+                $subfield_data{tag}           = $tag;
+                $subfield_data{subfield}      = $subfield;
+                $subfield_data{countsubfield} = $cntsubf++;
+                $subfield_data{kohafield}     = $tagslib->{$tag}->{$subfield}->{'kohafield'};
+
+                #        $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib};
+                $subfield_data{marc_lib}   = $tagslib->{$tag}->{$subfield}->{lib};
+                $subfield_data{mandatory}  = $tagslib->{$tag}->{$subfield}->{mandatory};
+                $subfield_data{repeatable} = $tagslib->{$tag}->{$subfield}->{repeatable};
+                $subfield_data{hidden}     = "display:none"
+                  if $tagslib->{$tag}->{$subfield}->{hidden};
+                my ( $x, $defaultvalue );
+                if ($itemrecord) {
+                    ( $x, $defaultvalue ) = _find_value( $tag, $subfield, $itemrecord );
+                }
+                $defaultvalue = $tagslib->{$tag}->{$subfield}->{defaultvalue} unless $defaultvalue;
+                if ( !defined $defaultvalue ) {
+                    $defaultvalue = q||;
+                }
+                $defaultvalue =~ s/"/&quot;/g;
+
+                # search for itemcallnumber if applicable
+                if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
+                    && C4::Context->preference('itemcallnumber') ) {
+                    my $CNtag      = substr( C4::Context->preference('itemcallnumber'), 0, 3 );
+                    my $CNsubfield = substr( C4::Context->preference('itemcallnumber'), 3, 1 );
+                    if ($itemrecord) {
+                        my $temp = $itemrecord->field($CNtag);
+                        if ($temp) {
+                            $defaultvalue = $temp->subfield($CNsubfield);
+                        }
+                    }
+                }
+                if (   $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
+                    && $defaultvalues
+                    && $defaultvalues->{'callnumber'} ) {
+                    my $temp;
+                    if ($itemrecord) {
+                        $temp = $itemrecord->field($subfield);
+                    }
+                    unless ($temp) {
+                        $defaultvalue = $defaultvalues->{'callnumber'} if $defaultvalues;
+                    }
+                }
+                if (   ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' )
+                    && $defaultvalues
+                    && $defaultvalues->{'branchcode'} ) {
+                    my $temp;
+                    if ($itemrecord) {
+                        $temp = $itemrecord->field($subfield);
+                    }
+                    unless ($temp) {
+                        $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} ) {
+                    my @authorised_values;
+                    my %authorised_lib;
+
+                    # builds list, depending on authorised value...
+                    #---- branch
+                    if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
+                        if (   ( C4::Context->preference("IndependantBranches") )
+                            && ( C4::Context->userenv->{flags} % 2 != 1 ) ) {
+                            my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname" );
+                            $sth->execute( C4::Context->userenv->{branch} );
+                            push @authorised_values, ""
+                              unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
+                            while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) {
+                                push @authorised_values, $branchcode;
+                                $authorised_lib{$branchcode} = $branchname;
+                            }
+                        } else {
+                            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;
+                            }
+                        }
+
+                        #----- itemtypes
+                    } elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
+                        my $sth = $dbh->prepare( "SELECT itemtype,description FROM itemtypes ORDER BY description" );
+                        $sth->execute;
+                        push @authorised_values, ""
+                          unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
+                        while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) {
+                            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 {
+                        $authorised_values_sth->execute( $tagslib->{$tag}->{$subfield}->{authorised_value} );
+                        push @authorised_values, ""
+                          unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
+                        while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) {
+                            push @authorised_values, $value;
+                            $authorised_lib{$value} = $lib;
+                        }
+                    }
+                    $subfield_data{marc_value} = CGI::scrolling_list(
+                        -name     => 'field_value',
+                        -values   => \@authorised_values,
+                        -default  => "$defaultvalue",
+                        -labels   => \%authorised_lib,
+                        -size     => 1,
+                        -tabindex => '',
+                        -multiple => 0,
+                    );
+                } elsif ( $tagslib->{$tag}->{$subfield}->{value_builder} ) {
+                        # opening plugin
+                        my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $tagslib->{$tag}->{$subfield}->{'value_builder'};
+                        if (do $plugin) {
+                            my $temp;
+                            my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef );
+                            my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef );
+                            $subfield_data{random}     = int(rand(1000000));    # why do we need 2 different randoms?
+                            my $index_subfield = int(rand(1000000));
+                            $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield;
+                            $subfield_data{marc_value} = qq[<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255"
+                                onfocus="Focus$function_name($subfield_data{random}, '$subfield_data{id}');"
+                                 onblur=" Blur$function_name($subfield_data{random}, '$subfield_data{id}');" />
+                                <a href="#" class="buttonDot" onclick="Clic$function_name('$subfield_data{id}'); return false;" title="Tag Editor">...</a>
+                                $javascript];
+                        } else {
+                            warn "Plugin Failed: $plugin";
+                            $subfield_data{marc_value} = qq(<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" />); # supply default input form
+                        }
+                }
+                elsif ( $tag eq '' ) {       # it's an hidden field
+                    $subfield_data{marc_value} = qq(<input type="hidden" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />);
+                }
+                elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) {   # FIXME: shouldn't input type be "hidden" ?
+                    $subfield_data{marc_value} = qq(<input type="text" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />);
+                }
+                elsif ( length($defaultvalue) > 100
+                            or (C4::Context->preference("marcflavour") eq "UNIMARC" and
+                                  300 <= $tag && $tag < 400 && $subfield eq 'a' )
+                            or (C4::Context->preference("marcflavour") eq "MARC21"  and
+                                  500 <= $tag && $tag < 600                     )
+                          ) {
+                    # oversize field (textarea)
+                    $subfield_data{marc_value} = qq(<textarea tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255">$defaultvalue</textarea>\n");
+                } else {
+                    $subfield_data{marc_value} = "<input type=\"text\" name=\"field_value\" value=\"$defaultvalue\" size=\"50\" maxlength=\"255\" />";
+                }
+                push( @loop_data, \%subfield_data );
+            }
+        }
+    }
+    my $itemnumber;
+    if ( $itemrecord && $itemrecord->field($itemtagfield) ) {
+        $itemnumber = $itemrecord->subfield( $itemtagfield, $itemtagsubfield );
+    }
+    return {
+        'itemtagfield'    => $itemtagfield,
+        'itemtagsubfield' => $itemtagsubfield,
+        'itemnumber'      => $itemnumber,
+        'iteminformation' => \@loop_data
+    };
+}
+
 1;
 1;