Bug 15758: Koha::Libraries - Ultimate duel for C4::Branch
[koha.git] / C4 / Items.pm
index a0dfb29..0bca944 100644 (file)
@@ -37,7 +37,11 @@ use Data::Dumper; # used as part of logging item record changes, not just for
 use Koha::DateUtils qw/dt_from_string/;
 use Koha::Database;
 
-use Koha::Database;
+use Koha::Biblioitems;
+use Koha::Items;
+use Koha::SearchEngine;
+use Koha::SearchEngine::Search;
+use Koha::Libraries;
 
 use vars qw(@ISA @EXPORT);
 
@@ -77,6 +81,7 @@ BEGIN {
         GetItemnumberFromBarcode
         GetBarcodeFromItemnumber
         GetHiddenItemnumbers
+        ItemSafeToDelete
         DelItemCheck
     MoveItemFromBiblio
     GetLatestAcquisitions
@@ -251,7 +256,7 @@ sub AddItemFromMarc {
        
        my $localitemmarc=MARC::Record->new;
        $localitemmarc->append_fields($source_item_marc->field($itemtag));
-    my $item = &TransformMarcToKoha( $dbh, $localitemmarc, $frameworkcode ,'items');
+    my $item = &TransformMarcToKoha( $localitemmarc, $frameworkcode ,'items');
     my $unlinked_item_subfields = _get_unlinked_item_subfields($localitemmarc, $frameworkcode);
     return AddItem($item, $biblionumber, $dbh, $frameworkcode, $unlinked_item_subfields);
 }
@@ -383,7 +388,7 @@ sub AddItemBatchFromMarc {
         $temp_item_marc->append_fields($item_field);
     
         # add biblionumber and biblioitemnumber
-        my $item = TransformMarcToKoha( $dbh, $temp_item_marc, $frameworkcode, 'items' );
+        my $item = TransformMarcToKoha( $temp_item_marc, $frameworkcode, 'items' );
         my $unlinked_item_subfields = _get_unlinked_item_subfields($temp_item_marc, $frameworkcode);
         $item->{'more_subfields_xml'} = _get_unlinked_subfields_xml($unlinked_item_subfields);
         $item->{'biblionumber'} = $biblionumber;
@@ -447,13 +452,14 @@ Returns item record
 
 =cut
 
-our %default_values_for_mod_from_marc;
-
 sub _build_default_values_for_mod_marc {
     my ($frameworkcode) = @_;
-    return $default_values_for_mod_from_marc{$frameworkcode}
-      if exists $default_values_for_mod_from_marc{$frameworkcode};
-    my $marc_structure = C4::Biblio::GetMarcStructure( 1, $frameworkcode );
+
+    my $cache     = Koha::Caches->get_instance();
+    my $cache_key = "default_value_for_mod_marc-$frameworkcode";
+    my $cached    = $cache->get_from_cache($cache_key);
+    return $cached if $cached;
+
     my $default_values = {
         barcode                  => undef,
         booksellerid             => undef,
@@ -485,15 +491,18 @@ sub _build_default_values_for_mod_marc {
         uri                      => undef,
         withdrawn                => 0,
     };
+    my %default_values_for_mod_from_marc;
     while ( my ( $field, $default_value ) = each %$default_values ) {
         my $kohafield = $field;
         $kohafield =~ s|^([^\.]+)$|items.$1|;
-        $default_values_for_mod_from_marc{$frameworkcode}{$field} =
+        $default_values_for_mod_from_marc{$field} =
           $default_value
           if C4::Koha::IsKohaFieldLinked(
             { kohafield => $kohafield, frameworkcode => $frameworkcode } );
     }
-    return $default_values_for_mod_from_marc{$frameworkcode};
+
+    $cache->set_in_cache($cache_key, \%default_values_for_mod_from_marc);
+    return \%default_values_for_mod_from_marc;
 }
 
 sub ModItemFromMarc {
@@ -507,8 +516,8 @@ sub ModItemFromMarc {
 
     my $localitemmarc = MARC::Record->new;
     $localitemmarc->append_fields( $item_marc->field($itemtag) );
-    my $item = &TransformMarcToKoha( $dbh, $localitemmarc, $frameworkcode, 'items' );
-    my $default_values = _build_default_values_for_mod_marc();
+    my $item = &TransformMarcToKoha( $localitemmarc, $frameworkcode, 'items' );
+    my $default_values = _build_default_values_for_mod_marc($frameworkcode);
     foreach my $item_field ( keys %$default_values ) {
         $item->{$item_field} = $default_values->{$item_field}
           unless exists $item->{$item_field};
@@ -730,7 +739,6 @@ item that has a given branch code.
 
 sub CheckItemPreSave {
     my $item_ref = shift;
-    require C4::Branch;
 
     my %errors = ();
 
@@ -747,20 +755,16 @@ sub CheckItemPreSave {
 
     # check for valid home branch
     if (exists $item_ref->{'homebranch'} and defined $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
+        my $home_library = Koha::Libraries->find( $item_ref->{homebranch} );
+        unless (defined $home_library) {
             $errors{'invalid_homebranch'} = $item_ref->{'homebranch'};
         }
     }
 
     # check for valid holding branch
     if (exists $item_ref->{'holdingbranch'} and defined $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
+        my $holding_library = Koha::Libraries->find( $item_ref->{holdingbranch} );
+        unless (defined $holding_library) {
             $errors{'invalid_holdingbranch'} = $item_ref->{'holdingbranch'};
         }
     }
@@ -1332,6 +1336,7 @@ sub GetItemsInfo {
            COALESCE( localization.translation, itemtypes.description ) AS translated_description,
            itemtypes.notforloan as notforloan_per_itemtype,
            holding.branchurl,
+           holding.branchcode,
            holding.branchname,
            holding.opac_info as holding_branch_opac_info,
            home.opac_info as home_branch_opac_info
@@ -1636,36 +1641,42 @@ references on array of itemnumbers.
 
 
 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';
+    my ($biblionumber) = @_;
+    my $marcrecord = GetMarcBiblio($biblionumber);
+
+    return unless $marcrecord;
+
+    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})
+        if ( my $itemnumbers =
+            get_itemnumbers_of($hostbiblionumber)->{$hostbiblionumber} )
         {
             @itemnumbers = @$itemnumbers;
         }
-        foreach my $itemnumber (@itemnumbers){
-            if ($itemnumber eq $linkeditemnumber){
-                push (@returnhostitemnumbers,$itemnumber);
+        foreach my $itemnumber (@itemnumbers) {
+            if ( $itemnumber eq $linkeditemnumber ) {
+                push( @returnhostitemnumbers, $itemnumber );
                 last;
             }
         }
     }
+
     return @returnhostitemnumbers;
 }
 
@@ -1760,104 +1771,6 @@ sub GetHiddenItemnumbers {
     return @resultitems;
 }
 
-=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_authorised_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,
@@ -2308,68 +2221,102 @@ sub MoveItemFromBiblio {
     return;
 }
 
-=head2 DelItemCheck
+=head2 ItemSafeToDelete
 
-   DelItemCheck($dbh, $biblionumber, $itemnumber);
+   ItemSafeToDelete( $biblionumber, $itemnumber);
 
-Exported function (core API) for deleting an item record in Koha if there no current issue.
+Exported function (core API) for checking whether an item record is safe to delete.
 
-=cut
+returns 1 if the item is safe to delete,
 
-sub DelItemCheck {
-    my ( $dbh, $biblionumber, $itemnumber ) = @_;
+"book_on_loan" if the item is checked out,
 
-    $dbh ||= C4::Context->dbh;
+"not_same_branch" if the item is blocked by independent branches,
 
-    my $error;
+"book_reserved" if the there are holds aganst the item, or
+
+"linked_analytics" if the item has linked analytic records.
+
+=cut
+
+sub ItemSafeToDelete {
+    my ( $biblionumber, $itemnumber ) = @_;
+    my $status;
+    my $dbh = C4::Context->dbh;
 
-        my $countanalytics=GetAnalyticsCount($itemnumber);
+    my $error;
 
+    my $countanalytics = GetAnalyticsCount($itemnumber);
 
     # check that there is no issue on this item before deletion.
-    my $sth = $dbh->prepare(q{
+    my $sth = $dbh->prepare(
+        q{
         SELECT COUNT(*) FROM issues
         WHERE itemnumber = ?
-    });
+    }
+    );
     $sth->execute($itemnumber);
     my ($onloan) = $sth->fetchrow;
 
     my $item = GetItem($itemnumber);
 
-    if ($onloan){
-        $error = "book_on_loan" 
+    if ($onloan) {
+        $status = "book_on_loan";
     }
     elsif ( defined C4::Context->userenv
         and !C4::Context->IsSuperLibrarian()
         and C4::Context->preference("IndependentBranches")
         and ( C4::Context->userenv->{branch} ne $item->{'homebranch'} ) )
     {
-        $error = "not_same_branch";
+        $status = "not_same_branch";
     }
-       else{
+    else {
         # check it doesn't have a waiting reserve
-        $sth = $dbh->prepare(q{
+        $sth = $dbh->prepare(
+            q{
             SELECT COUNT(*) 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(
-                {
-                    biblionumber => $biblionumber,
-                    itemnumber   => $itemnumber
-                }
-            );
-            return 1;
+        if ($reserve) {
+            $status = "book_reserved";
+        }
+        elsif ( $countanalytics > 0 ) {
+            $status = "linked_analytics";
+        }
+        else {
+            $status = 1;
         }
     }
-    return $error;
+    return $status;
+}
+
+=head2 DelItemCheck
+
+   DelItemCheck( $biblionumber, $itemnumber);
+
+Exported function (core API) for deleting an item record in Koha if there no current issue.
+
+DelItemCheck wraps ItemSafeToDelete around DelItem.
+
+=cut
+
+sub DelItemCheck {
+    my ( $biblionumber, $itemnumber ) = @_;
+    my $status = ItemSafeToDelete( $biblionumber, $itemnumber );
+
+    if ( $status == 1 ) {
+        DelItem(
+            {
+                biblionumber => $biblionumber,
+                itemnumber   => $itemnumber
+            }
+        );
+    }
+    return $status;
 }
 
 =head2 _koha_modify_item
@@ -2601,12 +2548,12 @@ counts Usage of itemnumber in Analytical bibliorecords.
 
 sub GetAnalyticsCount {
     my ($itemnumber) = @_;
-    require C4::Search;
 
     ### ZOOM search here
     my $query;
     $query= "hi=".$itemnumber;
-            my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
+    my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
+    my ($err,$res,$result) = $searcher->simple_search_compat($query,0,10);
     return ($result);
 }
 
@@ -3138,34 +3085,6 @@ sub PrepareItemrecordDisplay {
     };
 }
 
-=head2 columns
-
-  my @columns = C4::Items::columns();
-
-Returns an array of items' table columns on success,
-and an empty array on failure.
-
-=cut
-
-sub columns {
-    my $rs = Koha::Database->new->schema->resultset('Item');
-    return $rs->result_source->columns;
-}
-
-=head2 biblioitems_columns
-
-  my @columns = C4::Items::biblioitems_columns();
-
-Returns an array of biblioitems' table columns on success,
-and an empty array on failure.
-
-=cut
-
-sub biblioitems_columns {
-    my $rs = Koha::Database->new->schema->resultset('Biblioitem');
-    return $rs->result_source->columns;
-}
-
 sub ToggleNewStatus {
     my ( $params ) = @_;
     my @rules = @{ $params->{rules} };
@@ -3173,8 +3092,8 @@ sub ToggleNewStatus {
 
     my $dbh = C4::Context->dbh;
     my @errors;
-    my @item_columns = map { "items.$_" } C4::Items::columns;
-    my @biblioitem_columns = map { "biblioitems.$_" } C4::Items::biblioitems_columns;
+    my @item_columns = map { "items.$_" } Koha::Items->columns;
+    my @biblioitem_columns = map { "biblioitems.$_" } Koha::Biblioitems->columns;
     my $report;
     for my $rule ( @rules ) {
         my $age = $rule->{age};