fix for bug 1771: Template errors with remote itemtype image
[koha.git] / C4 / Items.pm
index a315e94..d785dc5 100644 (file)
@@ -841,28 +841,35 @@ sub GetItemLocation {
 
 =over 4
 
-$items = GetLostItems($where,$orderby);
+$items = GetLostItems( $where, $orderby );
 
 =back
 
-This function get the items lost into C<$items>.
+This function gets a list of lost items.
 
 =over 2
 
 =item input:
+
 C<$where> is a hashref. it containts a field of the items table as key
-and the value to match as value.
-C<$orderby> is a field of the items table.
+and the value to match as value. For example:
+
+{ barcode    => 'abc123',
+  homebranch => 'CPL',    }
+
+C<$orderby> is a field of the items table by which the resultset
+should be orderd.
 
 =item return:
-C<$items> is a reference to an array full of hasref which keys are items' table column.
+
+C<$items> is a reference to an array full of hashrefs with columns
+from the "items" table as keys.
 
 =item usage in the perl script:
 
-my %where;
-$where{barcode} = 0001548;
-my $items = GetLostItems( \%where, "homebranch" );
-$template->param(itemsloop => $items);
+my $where = { barcode => '0001548' };
+my $items = GetLostItems( $where, "homebranch" );
+$template->param( itemsloop => $items );
 
 =back
 
@@ -876,38 +883,49 @@ sub GetLostItems {
 
     my $query   = "
         SELECT *
-        FROM   items
-        WHERE  itemlost IS NOT NULL
-          AND  itemlost <> 0
+        FROM   items, biblio, authorised_values
+        WHERE
+                       items.biblionumber = biblio.biblionumber
+                       AND items.itemlost = authorised_values.authorised_value
+                       AND authorised_values.category = 'LOST'
+               AND itemlost IS NOT NULL
+               AND itemlost <> 0
+          
     ";
+    my @query_parameters;
     foreach my $key (keys %$where) {
-        $query .= " AND " . $key . " LIKE '%" . $where->{$key} . "%'";
+        $query .= " AND $key LIKE ?";
+        push @query_parameters, "%$where->{$key}%";
+    }
+    if ( defined $orderby ) {
+        $query .= ' ORDER BY ?';
+        push @query_parameters, $orderby;
     }
-    $query .= " ORDER BY ".$orderby if defined $orderby;
 
     my $sth = $dbh->prepare($query);
-    $sth->execute;
-    my @items;
+    $sth->execute( @query_parameters );
+    my $items = [];
     while ( my $row = $sth->fetchrow_hashref ){
-        push @items, $row;
+        push @$items, $row;
     }
-    return \@items;
+    return $items;
 }
 
 =head2 GetItemsForInventory
 
 =over 4
 
-$itemlist = GetItemsForInventory($minlocation,$maxlocation,$datelastseen,$offset,$size)
+$itemlist = GetItemsForInventory($minlocation, $maxlocation, $location, $itemtype $datelastseen, $branch, $offset, $size);
 
 =back
 
 Retrieve a list of title/authors/barcode/callnumber, for biblio inventory.
 
-The sub returns a list of hashes, containing itemnumber, author, title, barcode & item callnumber.
-It is ordered by callnumber,title.
+The sub returns a reference to a list of hashes, each containing
+itemnumber, author, title, barcode, item callnumber, and date last
+seen. It is ordered by callnumber then title.
 
-The minlocation & maxlocation parameters are used to specify a range of item callnumbers
+The required minlocation & maxlocation parameters are used to specify a range of item callnumbers
 the datelastseen can be used to specify that you want to see items not seen since a past date only.
 offset & size can be used to retrieve only a part of the whole listing (defaut behaviour)
 
@@ -916,39 +934,42 @@ offset & size can be used to retrieve only a part of the whole listing (defaut b
 sub GetItemsForInventory {
     my ( $minlocation, $maxlocation,$location, $itemtype, $datelastseen, $branch, $offset, $size ) = @_;
     my $dbh = C4::Context->dbh;
-    my $sth;
+
+    my $query = <<'END_SQL';
+SELECT itemnumber, barcode, itemcallnumber, title, author, biblio.biblionumber, datelastseen
+FROM items
+  LEFT JOIN biblio ON items.biblionumber = biblio.biblionumber
+  LEFT JOIN biblioitems on items.biblionumber = biblioitems.biblionumber
+WHERE itemcallnumber >= ?
+  AND itemcallnumber <= ?
+END_SQL
+    my @bind_params = ( $minlocation, $maxlocation );
+
     if ($datelastseen) {
-        $datelastseen=format_date_in_iso($datelastseen);  
-        my $query =
-                "SELECT itemnumber,barcode,itemcallnumber,title,author,biblio.biblionumber,datelastseen
-                 FROM items
-                   LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
-                   LEFT JOIN biblioitems on items.biblionumber=biblioitems.biblionumber
-                 WHERE itemcallnumber>= ?
-                   AND itemcallnumber <=?
-                   AND (datelastseen< ? OR datelastseen IS NULL)";
-        $query.= " AND items.location=".$dbh->quote($location) if $location;
-        $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
-        $query.= " AND biblioitems.itemtype=".$dbh->quote($itemtype) if $itemtype;
-        $query .= " ORDER BY itemcallnumber,title";
-        $sth = $dbh->prepare($query);
-        $sth->execute( $minlocation, $maxlocation, $datelastseen );
+        $datelastseen = format_date_in_iso($datelastseen);  
+        $query .= ' AND (datelastseen < ? OR datelastseen IS NULL) ';
+        push @bind_params, $datelastseen;
+    }
+
+    if ( $location ) {
+        $query.= ' AND items.location = ? ';
+        push @bind_params, $location;
     }
-    else {
-        my $query ="
-                SELECT itemnumber,barcode,itemcallnumber,biblio.biblionumber,title,author,datelastseen
-                FROM items 
-                    LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber 
-                   LEFT JOIN biblioitems on items.biblionumber=biblioitems.biblionumber
-                WHERE itemcallnumber>= ?
-                  AND itemcallnumber <=?";
-        $query.= " AND items.location=".$dbh->quote($location) if $location;
-        $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
-        $query.= " AND biblioitems.itemtype=".$dbh->quote($itemtype) if $itemtype;
-        $query .= " ORDER BY itemcallnumber,title";
-        $sth = $dbh->prepare($query);
-        $sth->execute( $minlocation, $maxlocation );
+    
+    if ( $branch ) {
+        $query.= ' AND items.homebranch = ? ';
+        push @bind_params, $branch;
     }
+    
+    if ( $itemtype ) {
+        $query.= ' AND biblioitems.itemtype = ? ';
+        push @bind_params, $itemtype;
+    }
+
+    $query .= ' ORDER BY itemcallnumber, title';
+    my $sth = $dbh->prepare($query);
+    $sth->execute( @bind_params );
+
     my @results;
     $size--;
     while ( my $row = $sth->fetchrow_hashref ) {
@@ -1202,6 +1223,7 @@ sub GetItemsInfo {
             my ($lib) = $sthnflstatus->fetchrow;
             $data->{notforloanvalue} = $lib;
         }
+               $data->{itypenotforloan} = $data->{notforloan} if (C4::Context->preference('item-level_itypes'));
 
         # my stack procedures
         my $stackstatus = $dbh->prepare(
@@ -1244,7 +1266,7 @@ sub GetItemsInfo {
     }
     $sth->finish;
        if($serial) {
-               return( sort { $b->{'publisheddate'} cmp $a->{'publisheddate'} } @results );
+               return( sort { ($b->{'publisheddate'} || $b->{'enumchron'}) cmp ($a->{'publisheddate'} || $a->{'enumchron'}) } @results );
        } else {
        return (@results);
        }
@@ -1310,6 +1332,106 @@ sub GetItemnumberFromBarcode {
     return ($result);
 }
 
+=head3 get_item_authorised_values
+
+  find the types and values for all authorised values assigned to this item.
+
+  parameters:
+    itemnumber
+
+  returns: a hashref malling the authorised value to the value set for this itemnumber
+
+    $authorised_values = {
+             'CCODE'      => undef,
+             'DAMAGED'    => '0',
+             'LOC'        => '3',
+             'LOST'       => '0'
+             'NOT_LOAN'   => '0',
+             'RESTRICTED' => undef,
+             'STACK'      => undef,
+             'WITHDRAWN'  => '0',
+             'branches'   => 'CPL',
+             'cn_source'  => undef,
+             'itemtypes'  => 'SER',
+           };
+
+   Notes: see C4::Biblio::get_biblio_authorised_values for a similar method at the biblio level.
+
+=cut
+
+sub get_item_authorised_values {
+    my $itemnumber = shift;
+
+    # assume that these entries in the authorised_value table are item level.
+    my $query = q(SELECT distinct authorised_value, kohafield
+                    FROM marc_subfield_structure
+                    WHERE kohafield like 'item%'
+                      AND authorised_value != '' );
+
+    my $itemlevel_authorised_values = C4::Context->dbh->selectall_hashref( $query, 'authorised_value' );
+    my $iteminfo = GetItem( $itemnumber );
+    # warn( Data::Dumper->Dump( [ $itemlevel_authorised_values ], [ 'itemlevel_authorised_values' ] ) );
+    my $return;
+    foreach my $this_authorised_value ( keys %$itemlevel_authorised_values ) {
+        my $field = $itemlevel_authorised_values->{ $this_authorised_value }->{'kohafield'};
+        $field =~ s/^items\.//;
+        if ( exists $iteminfo->{ $field } ) {
+            $return->{ $this_authorised_value } = $iteminfo->{ $field };
+        }
+    }
+    # warn( Data::Dumper->Dump( [ $return ], [ 'return' ] ) );
+    return $return;
+}
+
+=head3 get_authorised_value_images
+
+  find a list of icons that are appropriate for display based on the
+  authorised values for a biblio.
+
+  parameters: listref of authorised values, such as comes from
+    get_item_ahtorised_values or
+    from C4::Biblio::get_biblio_authorised_values
+
+  returns: listref of hashrefs for each image. Each hashref looks like
+    this:
+
+      { imageurl => '/intranet-tmpl/prog/img/itemtypeimg/npl/WEB.gif',
+        label    => '',
+        category => '',
+        value    => '', }
+
+  Notes: Currently, I put on the full path to the images on the staff
+  side. This should either be configurable or not done at all. Since I
+  have to deal with 'intranet' or 'opac' in
+  get_biblio_authorised_values, perhaps I should be passing it in.
+
+=cut
+
+sub get_authorised_value_images {
+    my $authorised_values = shift;
+
+    my @imagelist;
+
+    my $authorised_value_list = GetAuthorisedValues();
+    # warn ( Data::Dumper->Dump( [ $authorised_value_list ], [ 'authorised_value_list' ] ) );
+    foreach my $this_authorised_value ( @$authorised_value_list ) {
+        if ( exists $authorised_values->{ $this_authorised_value->{'category'} }
+             && $authorised_values->{ $this_authorised_value->{'category'} } eq $this_authorised_value->{'authorised_value'} ) {
+            # warn ( Data::Dumper->Dump( [ $this_authorised_value ], [ 'this_authorised_value' ] ) );
+            if ( defined $this_authorised_value->{'imageurl'} ) {
+                push @imagelist, { imageurl => C4::Koha::getitemtypeimagelocation( 'intranet', $this_authorised_value->{'imageurl'} ),
+                                   label    => $this_authorised_value->{'lib'},
+                                   category => $this_authorised_value->{'category'},
+                                   value    => $this_authorised_value->{'authorised_value'}, };
+            }
+        }
+    }
+
+    # warn ( Data::Dumper->Dump( [ \@imagelist ], [ 'imagelist' ] ) );
+    return \@imagelist;
+
+}
+
 =head1 LIMITED USE FUNCTIONS
 
 The following functions, while part of the public API,
@@ -1668,8 +1790,10 @@ sub _koha_new_item {
             ccode               = ?,
             itype               = ?,
             materials           = ?,
-                       uri                 = ?,
-            more_subfields_xml  = ?
+            uri = ?,
+            enumchron           = ?,
+            more_subfields_xml  = ?,
+            copynumber          = ?
           ";
     my $sth = $dbh->prepare($query);
    $sth->execute(
@@ -1703,7 +1827,9 @@ sub _koha_new_item {
             $item->{'itype'},
             $item->{'materials'},
             $item->{'uri'},
+            $item->{'enumchron'},
             $item->{'more_subfields_xml'},
+            $item->{'copynumber'},
     );
     my $itemnumber = $dbh->{'mysql_insertid'};
     if ( defined $sth->errstr ) {
@@ -1859,7 +1985,6 @@ 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);
     }
@@ -1989,7 +2114,8 @@ sub _get_unlinked_subfields_xml {
         # use of tag 999 is arbitrary, and doesn't need to match the item tag
         # used in the framework
         $marc->append_fields(MARC::Field->new('999', ' ', ' ', @$unlinked_item_subfields));
-        $xml = $marc->as_xml();
+        $marc->encoding("UTF-8");    
+        $xml = $marc->as_xml("USMARC");
     }
 
     return $xml;
@@ -2009,7 +2135,7 @@ sub  _parse_unlinked_item_subfields_from_xml {
     my $xml = shift;
 
     return unless defined $xml and $xml ne "";
-    my $marc = MARC::Record->new_from_xml(StripNonXmlChars($xml), 'UTF-8', C4::Context->preference("marcflavour"));
+    my $marc = MARC::Record->new_from_xml(StripNonXmlChars($xml),'UTF-8');
     my $unlinked_subfields = [];
     my @fields = $marc->fields();
     if ($#fields > -1) {