[3.0.x] (bug #4263) fix the edition of items with repeatable subfields
[koha.git] / C4 / Items.pm
index c69d693..d19caf9 100644 (file)
@@ -49,6 +49,7 @@ BEGIN {
         ModDateLastSeen
         ModItemTransfer
         DelItem
+        DelItemCheck
     
         CheckItemPreSave
     
@@ -173,8 +174,12 @@ sub AddItemFromMarc {
 
     # parse item hash from MARC
     my $frameworkcode = GetFrameworkCode( $biblionumber );
-    my $item = &TransformMarcToKoha( $dbh, $source_item_marc, $frameworkcode );
-    my $unlinked_item_subfields = _get_unlinked_item_subfields($source_item_marc, $frameworkcode);
+       my ($itemtag,$itemsubfield)=GetMarcFromKohaField("items.itemnumber",$frameworkcode);
+       
+       my $localitemmarc=MARC::Record->new;
+       $localitemmarc->append_fields($source_item_marc->field($itemtag));
+    my $item = &TransformMarcToKoha( $dbh, $localitemmarc, $frameworkcode ,'items');
+    my $unlinked_item_subfields = _get_unlinked_item_subfields($localitemmarc, $frameworkcode);
     return AddItem($item, $biblionumber, $dbh, $frameworkcode, $unlinked_item_subfields);
 }
 
@@ -412,12 +417,16 @@ sub ModItemFromMarc {
 
     my $dbh = C4::Context->dbh;
     my $frameworkcode = GetFrameworkCode( $biblionumber );
-    my $item = &TransformMarcToKoha( $dbh, $item_marc, $frameworkcode );
+       my ($itemtag,$itemsubfield)=GetMarcFromKohaField("items.itemnumber",$frameworkcode);
+       
+       my $localitemmarc=MARC::Record->new;
+       $localitemmarc->append_fields($item_marc->field($itemtag));
+    my $item = &TransformMarcToKoha( $dbh, $localitemmarc, $frameworkcode, 'items');
     foreach my $item_field (keys %default_values_for_mod_from_marc) {
         $item->{$item_field} = $default_values_for_mod_from_marc{$item_field} unless exists $item->{$item_field};
     }
-    my $unlinked_item_subfields = _get_unlinked_item_subfields($item_marc, $frameworkcode);
-   
+    my $unlinked_item_subfields = _get_unlinked_item_subfields($localitemmarc, $frameworkcode);
+
     return ModItem($item, $biblionumber, $itemnumber, $dbh, $frameworkcode, $unlinked_item_subfields); 
 }
 
@@ -586,6 +595,47 @@ sub DelItem {
     logaction("CATALOGUING", "DELETE", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
 }
 
+=head2 DelItemCheck
+
+=over 4
+
+DelItemCheck($dbh, $biblionumber, $itemnumber);
+
+=back
+
+Exported function (core API) for deleting an item record in Koha if there no current issue.
+
+=cut
+
+sub DelItemCheck {
+    my ( $dbh, $biblionumber, $itemnumber ) = @_;
+    my $error;
+
+    # 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 $onloan=$sth->fetchrow;
+
+    $sth->finish();
+    if ($onloan){
+        $error = "book_on_loan" 
+    }else{
+        # check it doesnt have a waiting reserve
+        $sth=$dbh->prepare("SELECT * FROM reserves WHERE found = 'W' AND itemnumber = ?");
+        $sth->execute($itemnumber);
+        my $reserve=$sth->fetchrow;
+        $sth->finish();
+        if ($reserve){
+            $error = "book_reserved";
+        }else{
+            DelItem($dbh, $biblionumber, $itemnumber);
+            return 1;
+        }
+    }
+    return $error;
+}
+
 =head2 CheckItemPreSave
 
 =over 4
@@ -933,23 +983,24 @@ sub GetLostItems {
 
     my $query   = "
         SELECT *
-        FROM   items, biblio, authorised_values
+        FROM   items
+            LEFT JOIN biblio ON (items.biblionumber = biblio.biblionumber)
+            LEFT JOIN biblioitems ON (items.biblionumber = biblioitems.biblionumber)
+            LEFT JOIN authorised_values ON (items.itemlost = authorised_values.authorised_value)
         WHERE
-                       items.biblionumber = biblio.biblionumber
-                       AND items.itemlost = authorised_values.authorised_value
-                       AND authorised_values.category = 'LOST'
+               authorised_values.category = 'LOST'
                AND itemlost IS NOT NULL
                AND itemlost <> 0
-          
     ";
     my @query_parameters;
     foreach my $key (keys %$where) {
         $query .= " AND $key LIKE ?";
         push @query_parameters, "%$where->{$key}%";
     }
-    if ( defined $orderby ) {
-        $query .= ' ORDER BY ?';
-        push @query_parameters, $orderby;
+    my @ordervalues = qw/title author homebranch itype barcode price replacementprice lib datelastseen location/;
+    
+    if ( defined $orderby && grep($orderby, @ordervalues)) {
+        $query .= ' ORDER BY '.$orderby;
     }
 
     my $sth = $dbh->prepare($query);
@@ -982,40 +1033,61 @@ offset & size can be used to retrieve only a part of the whole listing (defaut b
 =cut
 
 sub GetItemsForInventory {
-    my ( $minlocation, $maxlocation,$location, $itemtype, $datelastseen, $branch, $offset, $size ) = @_;
+    my ( $minlocation, $maxlocation,$location, $itemtype, $ignoreissued, $datelastseen, $branch, $offset, $size ) = @_;
     my $dbh = C4::Context->dbh;
+    my ( @bind_params, @where_strings );
 
     my $query = <<'END_SQL';
-SELECT itemnumber, barcode, itemcallnumber, title, author, biblio.biblionumber, datelastseen
+SELECT items.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 ($minlocation) {
+        push @where_strings, 'itemcallnumber >= ?';
+        push @bind_params, $minlocation;
+    }
+
+    if ($maxlocation) {
+        push @where_strings, 'itemcallnumber <= ?';
+        push @bind_params, $maxlocation;
+    }
 
     if ($datelastseen) {
         $datelastseen = format_date_in_iso($datelastseen);  
-        $query .= ' AND (datelastseen < ? OR datelastseen IS NULL) ';
+        push @where_strings, '(datelastseen < ? OR datelastseen IS NULL)';
         push @bind_params, $datelastseen;
     }
 
     if ( $location ) {
-        $query.= ' AND items.location = ? ';
+        push @where_strings, 'items.location = ?';
         push @bind_params, $location;
     }
     
     if ( $branch ) {
-        $query.= ' AND items.homebranch = ? ';
+        push @where_strings, 'items.homebranch = ?';
         push @bind_params, $branch;
     }
     
     if ( $itemtype ) {
-        $query.= ' AND biblioitems.itemtype = ? ';
+        push @where_strings, 'biblioitems.itemtype = ?';
         push @bind_params, $itemtype;
     }
+    if ( $ignoreissued) {
+        $query .= "LEFT JOIN issues ON items.itemnumber = issues.itemnumber ";
+        push @where_strings, 'issues.date_due IS NULL';
+    }
+
+    if ( $ignoreissued) {
+        $query .= "LEFT JOIN issues ON items.itemnumber = issues.itemnumber ";
+        push @where_strings, 'issues.date_due IS NULL';
+    }
 
+    if ( @where_strings ) {
+        $query .= 'WHERE ';
+        $query .= join ' AND ', @where_strings;
+    }
     $query .= ' ORDER BY itemcallnumber, title';
     my $sth = $dbh->prepare($query);
     $sth->execute( @bind_params );
@@ -1217,7 +1289,7 @@ sub GetItemsInfo {
     $sth->execute($biblionumber);
     my $i = 0;
     my @results;
-    my ( $date_due, $count_reserves, $serial );
+    my $serial;
 
     my $isth    = $dbh->prepare(
         "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname,borrowers.branchcode as bcode
@@ -1226,6 +1298,7 @@ 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 $count_reserves;
         my $datedue = '';
         $isth->execute( $data->{'itemnumber'} );
         if ( my $idata = $isth->fetchrow_hashref ) {
@@ -1454,7 +1527,7 @@ sub get_item_authorised_values {
   authorised values for a biblio.
 
   parameters: listref of authorised values, such as comes from
-    get_item_ahtorised_values or
+    get_item_authorised_values or
     from C4::Biblio::get_biblio_authorised_values
 
   returns: listref of hashrefs for each image. Each hashref looks like
@@ -1546,6 +1619,7 @@ sub GetMarcItem {
             defined($itemrecord->{$_}) && $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : ()  
         } keys %{ $itemrecord } 
     };
+
     my $itemmarc = TransformKohaToMarc($mungeditem);
 
     my $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($mungeditem->{'items.more_subfields_xml'});
@@ -2008,14 +2082,19 @@ sub _marc_from_item_hash {
     foreach my $item_field (keys %{ $mungeditem }) {
         my ($tag, $subfield) = GetMarcFromKohaField($item_field, $frameworkcode);
         next unless defined $tag and defined $subfield; # skip if not mapped to MARC field
-        if (my $field = $item_marc->field($tag)) {
-            $field->add_subfields($subfield => $mungeditem->{$item_field});
-        } else {
-            my $add_subfields = [];
-            if (defined $unlinked_item_subfields and ref($unlinked_item_subfields) eq 'ARRAY' and $#$unlinked_item_subfields > -1) {
-                $add_subfields = $unlinked_item_subfields;
+
+        
+        my @values = split(/\s?\|\s?/, $mungeditem->{$item_field}, -1);
+        foreach my $value (@values){
+            if (my $field = $item_marc->field($tag)) {
+                $field->add_subfields($subfield => $value);
+            } else {
+                my $add_subfields = [];
+                if (defined $unlinked_item_subfields and ref($unlinked_item_subfields) eq 'ARRAY' and $#$unlinked_item_subfields > -1) {
+                    $add_subfields = $unlinked_item_subfields;
+                }
+                $item_marc->add_fields( $tag, " ", " ", $subfield =>  $value, @$add_subfields);
             }
-            $item_marc->add_fields( $tag, " ", " ", $subfield =>  $mungeditem->{$item_field}, @$add_subfields);
         }
     }
 
@@ -2067,7 +2146,7 @@ replace it with the tag from C<$item_marc>.
 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);