bug 5579: tweaks to bulkmarcimport.pl
[koha.git] / C4 / Items.pm
index 0ea8b86..44272e2 100644 (file)
@@ -33,6 +33,9 @@ use C4::Branch;
 require C4::Reserves;
 use C4::Charset;
 use C4::Acquisition;
+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);
 
@@ -65,9 +68,11 @@ BEGIN {
         GetItemInfosOf
         GetItemsByBiblioitemnumber
         GetItemsInfo
+       GetItemsLocationInfo
         get_itemnumbers_of
         GetItemnumberFromBarcode
         GetBarcodeFromItemnumber
+      GetHiddenItemnumbers
 
                DelItemCheck
                MoveItemFromBiblio 
@@ -259,9 +264,7 @@ sub AddItem {
        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 );
+    ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef );
    
     logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
     
@@ -367,7 +370,7 @@ sub AddItemBatchFromMarc {
     }
 
     # update the MARC biblio
-    $biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode );
#   $biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode );
 
     return (\@itemnumbers, \@errors);
 }
@@ -442,18 +445,6 @@ sub ModItemFromMarc {
     }
     my $unlinked_item_subfields = _get_unlinked_item_subfields( $localitemmarc, $frameworkcode );
 
-    my $dbh = C4::Context->dbh;
-    my $frameworkcode = GetFrameworkCode( $biblionumber );
-       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($localitemmarc, $frameworkcode);
-   
     return ModItem($item, $biblionumber, $itemnumber, $dbh, $frameworkcode, $unlinked_item_subfields); 
 }
 
@@ -515,18 +506,11 @@ sub ModItem {
     # 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
@@ -587,23 +571,13 @@ sub DelItem {
 
     # get the MARC record
     my $record = GetMarcBiblio($biblionumber);
-    my $frameworkcode = GetFrameworkCode($biblionumber);
+    ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
 
     # backup the record
     my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
     $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
 
     #search item field code
-    my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
-    my @fields = $record->field($itemtag);
-
-    # delete the item specified
-    foreach my $field (@fields) {
-        if ( $field->subfield($itemsubfield) eq $itemnumber ) {
-            $record->delete_field($field);
-        }
-    }
-    &ModBiblioMarc( $record, $biblionumber, $frameworkcode );
     logaction("CATALOGUING", "DELETE", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
 }
 
@@ -1359,6 +1333,72 @@ sub GetItemsInfo {
        }
 }
 
+=head2 GetItemsLocationInfo
+
+  my @itemlocinfo = GetItemsLocationInfo($biblionumber);
+
+Returns the branch names, shelving location and itemcallnumber for each item attached to the biblio in question
+
+C<GetItemsInfo> returns a list of references-to-hash. Data returned:
+
+=over 2
+
+=item C<$data-E<gt>{homebranch}>
+
+Branch Name of the item's homebranch
+
+=item C<$data-E<gt>{holdingbranch}>
+
+Branch Name of the item's holdingbranch
+
+=item C<$data-E<gt>{location}>
+
+Item's shelving location code
+
+=item C<$data-E<gt>{location_intranet}>
+
+The intranet description for the Shelving Location as set in authorised_values 'LOC'
+
+=item C<$data-E<gt>{location_opac}>
+
+The OPAC description for the Shelving Location as set in authorised_values 'LOC'.  Falls back to intranet description if no OPAC 
+description is set.
+
+=item C<$data-E<gt>{itemcallnumber}>
+
+Item's itemcallnumber
+
+=item C<$data-E<gt>{cn_sort}>
+
+Item's call number normalized for sorting
+
+=back
+  
+=cut
+
+sub GetItemsLocationInfo {
+        my $biblionumber = shift;
+        my @results;
+
+       my $dbh = C4::Context->dbh;
+       my $query = "SELECT a.branchname as homebranch, b.branchname as holdingbranch, 
+                           location, itemcallnumber, cn_sort
+                    FROM items, branches as a, branches as b
+                    WHERE homebranch = a.branchcode AND holdingbranch = b.branchcode 
+                    AND biblionumber = ?
+                    ORDER BY cn_sort ASC";
+       my $sth = $dbh->prepare($query);
+        $sth->execute($biblionumber);
+
+        while ( my $data = $sth->fetchrow_hashref ) {
+             $data->{location_intranet} = GetKohaAuthorisedValueLib('LOC', $data->{location});
+             $data->{location_opac}= GetKohaAuthorisedValueLib('LOC', $data->{location}, 1);
+            push @results, $data;
+       }
+       return @results;
+}
+
+
 =head2 GetLastAcquisitions
 
   my $lastacq = GetLastAcquisitions({'branches' => ('branch1','branch2'), 
@@ -1479,6 +1519,57 @@ sub GetBarcodeFromItemnumber {
     return ($result);
 }
 
+=head2 GetHiddenItemnumbers
+
+=over 4
+
+$result = GetHiddenItemnumbers(@items);
+
+=back
+
+=cut
+
+sub GetHiddenItemnumbers {
+    my (@items) = @_;
+    my @resultitems;
+
+    my $yaml = C4::Context->preference('OpacHiddenItems');
+    my $hidingrules;
+    eval {
+       $hidingrules = YAML::Load($yaml);
+    };
+    if ($@) {
+       warn "Unable to parse OpacHiddenItems syspref : $@";
+       return ();
+    } else {
+    my $dbh = C4::Context->dbh;
+
+       # 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;
+
+               # If the results matches the values in the yaml file
+               if (any { $result eq $_ } @{$hidingrules->{$field}}) {
+
+                   # 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;
+    }
+
+ }
+
 =head3 get_item_authorised_values
 
 find the types and values for all authorised values assigned to this item.
@@ -1909,7 +2000,8 @@ sub _koha_new_item {
             uri = ?,
             enumchron           = ?,
             more_subfields_xml  = ?,
-            copynumber          = ?
+            copynumber          = ?,
+            stocknumber         = ?
           ";
     my $sth = $dbh->prepare($query);
    $sth->execute(
@@ -1946,6 +2038,7 @@ sub _koha_new_item {
             $item->{'enumchron'},
             $item->{'more_subfields_xml'},
             $item->{'copynumber'},
+            $item->{'stocknumber'},
     );
     my $itemnumber = $dbh->{'mysql_insertid'};
     if ( defined $sth->errstr ) {
@@ -1973,59 +2066,18 @@ 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) {
-
-       # 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 
-           my $order = GetOrderFromItemnumber($itemnumber);
+        my $order = GetOrderFromItemnumber($itemnumber);
            if ($order) {
-               # Replacing the biblionumber within the order if necessary
-               $order->{'biblionumber'} = $tobiblio;
+                   # Replacing the biblionumber within the order if necessary
+                   $order->{'biblionumber'} = $tobiblio;
                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
@@ -2186,68 +2238,6 @@ sub _marc_from_item_hash {
     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>