Bug 6488 adding a 2nd \n to silence logs
[koha_gimpoz] / C4 / Items.pm
index 44272e2..04cb417 100644 (file)
@@ -69,15 +69,19 @@ 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
     );
 }
 
     );
 }
 
@@ -397,6 +401,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 = (
@@ -415,6 +421,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, 
@@ -445,13 +452,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.
@@ -494,6 +501,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
@@ -576,6 +586,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");
@@ -1112,16 +1123,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:
 
@@ -1157,7 +1164,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 = "
@@ -1179,7 +1186,7 @@ sub GetItemsInfo {
            itemtypes.notforloan as notforloan_per_itemtype,
            branchurl
      FROM items
            itemtypes.notforloan as notforloan_per_itemtype,
            branchurl
      FROM items
-     LEFT JOIN branches ON items.homebranch = branches.branchcode
+     LEFT JOIN branches ON items.holdingbranch = branches.branchcode
      LEFT JOIN biblio      ON      biblio.biblionumber     = items.biblionumber
      LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
      LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
      LEFT JOIN biblio      ON      biblio.biblionumber     = items.biblionumber
      LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
      LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
@@ -1206,6 +1213,7 @@ sub GetItemsInfo {
             $data->{cardnumber}     = $idata->{cardnumber};
             $data->{surname}     = $idata->{surname};
             $data->{firstname}     = $idata->{firstname};
             $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;
@@ -1220,7 +1228,7 @@ sub GetItemsInfo {
                        $serial = 1;
         }
                if ( $datedue eq '' ) {
                        $serial = 1;
         }
                if ( $datedue eq '' ) {
-            my ( $restype, $reserves ) =
+            my ( $restype, $reserves, undef ) =
               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
               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
@@ -1398,6 +1406,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
 
@@ -1485,6 +1533,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);
@@ -1534,41 +1629,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
 
@@ -1974,9 +2073,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             = ?,
@@ -1988,6 +2087,7 @@ sub _koha_new_item {
             holdingbranch       = ?,
             paidfor             = ?,
             location            = ?,
             holdingbranch       = ?,
             paidfor             = ?,
             location            = ?,
+            permanent_location            = ?,
             onloan              = ?,
             issues              = ?,
             renewals            = ?,
             onloan              = ?,
             issues              = ?,
             renewals            = ?,
@@ -2004,6 +2104,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'},
@@ -2013,7 +2114,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'},
@@ -2025,6 +2128,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'},
@@ -2040,10 +2144,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 );
 }
 
@@ -2092,35 +2201,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;
 }
@@ -2337,4 +2450,51 @@ 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;
+}
 1;
 1;