View | Details | Raw Unified | Return to bug 27272
Collapse All | Expand All

(-)a/C4/Items.pm (-259 lines)
Lines 34-42 BEGIN { Link Here
34
        ModItemTransfer
34
        ModItemTransfer
35
        CheckItemPreSave
35
        CheckItemPreSave
36
        GetItemsForInventory
36
        GetItemsForInventory
37
        GetItemsInfo
38
        GetItemsLocationInfo
39
        GetHostItemsInfo
40
        get_hostitemnumbers_of
37
        get_hostitemnumbers_of
41
        GetMarcItem
38
        GetMarcItem
42
        CartToShelf
39
        CartToShelf
Lines 673-934 sub GetItemsForInventory { Link Here
673
    return (\@results, $iTotalRecords);
670
    return (\@results, $iTotalRecords);
674
}
671
}
675
672
676
=head2 GetItemsInfo
677
678
  @results = GetItemsInfo($biblionumber);
679
680
Returns information about items with the given biblionumber.
681
682
C<GetItemsInfo> returns a list of references-to-hash. Each element
683
contains a number of keys. Most of them are attributes from the
684
C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
685
Koha database. Other keys include:
686
687
=over 2
688
689
=item C<$data-E<gt>{branchname}>
690
691
The name (not the code) of the branch to which the book belongs.
692
693
=item C<$data-E<gt>{datelastseen}>
694
695
This is simply C<items.datelastseen>, except that while the date is
696
stored in YYYY-MM-DD format in the database, here it is converted to
697
DD/MM/YYYY format. A NULL date is returned as C<//>.
698
699
=item C<$data-E<gt>{datedue}>
700
701
=item C<$data-E<gt>{class}>
702
703
This is the concatenation of C<biblioitems.classification>, the book's
704
Dewey code, and C<biblioitems.subclass>.
705
706
=item C<$data-E<gt>{ocount}>
707
708
I think this is the number of copies of the book available.
709
710
=item C<$data-E<gt>{order}>
711
712
If this is set, it is set to C<One Order>.
713
714
=back
715
716
=cut
717
718
sub GetItemsInfo {
719
    my ( $biblionumber ) = @_;
720
    my $dbh   = C4::Context->dbh;
721
    require C4::Languages;
722
    my $language = C4::Languages::getlanguage();
723
    my $query = "
724
    SELECT items.*,
725
           biblio.*,
726
           biblioitems.volume,
727
           biblioitems.number,
728
           biblioitems.itemtype,
729
           biblioitems.isbn,
730
           biblioitems.issn,
731
           biblioitems.publicationyear,
732
           biblioitems.publishercode,
733
           biblioitems.volumedate,
734
           biblioitems.volumedesc,
735
           biblioitems.lccn,
736
           biblioitems.url,
737
           items.notforloan as itemnotforloan,
738
           issues.borrowernumber,
739
           issues.date_due as datedue,
740
           issues.onsite_checkout,
741
           borrowers.cardnumber,
742
           borrowers.surname,
743
           borrowers.firstname,
744
           borrowers.branchcode as bcode,
745
           serial.serialseq,
746
           serial.publisheddate,
747
           itemtypes.description,
748
           COALESCE( localization.translation, itemtypes.description ) AS translated_description,
749
           itemtypes.notforloan as notforloan_per_itemtype,
750
           holding.branchurl,
751
           holding.branchcode,
752
           holding.branchname,
753
           holding.opac_info as holding_branch_opac_info,
754
           home.opac_info as home_branch_opac_info,
755
           IF(tmp_holdsqueue.itemnumber,1,0) AS has_pending_hold
756
     FROM items
757
     LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode
758
     LEFT JOIN branches AS home ON items.homebranch=home.branchcode
759
     LEFT JOIN biblio      ON      biblio.biblionumber     = items.biblionumber
760
     LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
761
     LEFT JOIN issues USING (itemnumber)
762
     LEFT JOIN borrowers USING (borrowernumber)
763
     LEFT JOIN serialitems USING (itemnumber)
764
     LEFT JOIN serial USING (serialid)
765
     LEFT JOIN itemtypes   ON   itemtypes.itemtype         = "
766
     . (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype');
767
    $query .= q|
768
    LEFT JOIN tmp_holdsqueue USING (itemnumber)
769
    LEFT JOIN localization ON itemtypes.itemtype = localization.code
770
        AND localization.entity = 'itemtypes'
771
        AND localization.lang = ?
772
    |;
773
774
    $query .= " WHERE items.biblionumber = ? ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ;
775
    my $sth = $dbh->prepare($query);
776
    $sth->execute($language, $biblionumber);
777
    my $i = 0;
778
    my @results;
779
    my $serial;
780
781
    my $userenv = C4::Context->userenv;
782
    my $want_not_same_branch = C4::Context->preference("IndependentBranches") && !C4::Context->IsSuperLibrarian();
783
    while ( my $data = $sth->fetchrow_hashref ) {
784
        if ( $data->{borrowernumber} && $want_not_same_branch) {
785
            $data->{'NOTSAMEBRANCH'} = $data->{'bcode'} ne $userenv->{branch};
786
        }
787
788
        $serial ||= $data->{'serial'};
789
790
        my $descriptions;
791
        # get notforloan complete status if applicable
792
        $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => $data->{frameworkcode}, kohafield => 'items.notforloan', authorised_value => $data->{itemnotforloan} });
793
        $data->{notforloanvalue}     = $descriptions->{lib} // '';
794
        $data->{notforloanvalueopac} = $descriptions->{opac_description} // '';
795
796
        # get restricted status and description if applicable
797
        $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => $data->{frameworkcode}, kohafield => 'items.restricted', authorised_value => $data->{restricted} });
798
        $data->{restrictedvalue}     = $descriptions->{lib} // '';
799
        $data->{restrictedvalueopac} = $descriptions->{opac_description} // '';
800
801
        # my stack procedures
802
        $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => $data->{frameworkcode}, kohafield => 'items.stack', authorised_value => $data->{stack} });
803
        $data->{stack}          = $descriptions->{lib} // '';
804
805
        # Find the last 3 people who borrowed this item.
806
        my $sth2 = $dbh->prepare("SELECT * FROM old_issues,borrowers
807
                                    WHERE itemnumber = ?
808
                                    AND old_issues.borrowernumber = borrowers.borrowernumber
809
                                    ORDER BY returndate DESC
810
                                    LIMIT 3");
811
        $sth2->execute($data->{'itemnumber'});
812
        my $ii = 0;
813
        while (my $data2 = $sth2->fetchrow_hashref()) {
814
            $data->{"timestamp$ii"} = $data2->{'timestamp'} if $data2->{'timestamp'};
815
            $data->{"card$ii"}      = $data2->{'cardnumber'} if $data2->{'cardnumber'};
816
            $data->{"borrower$ii"}  = $data2->{'borrowernumber'} if $data2->{'borrowernumber'};
817
            $ii++;
818
        }
819
820
        $results[$i] = $data;
821
        $i++;
822
    }
823
824
    return $serial
825
        ? sort { ($b->{'publisheddate'} || $b->{'enumchron'} || "") cmp ($a->{'publisheddate'} || $a->{'enumchron'} || "") } @results
826
        : @results;
827
}
828
829
=head2 GetItemsLocationInfo
830
831
  my @itemlocinfo = GetItemsLocationInfo($biblionumber);
832
833
Returns the branch names, shelving location and itemcallnumber for each item attached to the biblio in question
834
835
C<GetItemsInfo> returns a list of references-to-hash. Data returned:
836
837
=over 2
838
839
=item C<$data-E<gt>{homebranch}>
840
841
Branch Name of the item's homebranch
842
843
=item C<$data-E<gt>{holdingbranch}>
844
845
Branch Name of the item's holdingbranch
846
847
=item C<$data-E<gt>{location}>
848
849
Item's shelving location code
850
851
=item C<$data-E<gt>{location_intranet}>
852
853
The intranet description for the Shelving Location as set in authorised_values 'LOC'
854
855
=item C<$data-E<gt>{location_opac}>
856
857
The OPAC description for the Shelving Location as set in authorised_values 'LOC'.  Falls back to intranet description if no OPAC 
858
description is set.
859
860
=item C<$data-E<gt>{itemcallnumber}>
861
862
Item's itemcallnumber
863
864
=item C<$data-E<gt>{cn_sort}>
865
866
Item's call number normalized for sorting
867
868
=back
869
870
=cut
871
872
sub GetItemsLocationInfo {
873
        my $biblionumber = shift;
874
        my @results;
875
876
	my $dbh = C4::Context->dbh;
877
	my $query = "SELECT a.branchname as homebranch, b.branchname as holdingbranch, 
878
			    location, itemcallnumber, cn_sort
879
		     FROM items, branches as a, branches as b
880
		     WHERE homebranch = a.branchcode AND holdingbranch = b.branchcode 
881
		     AND biblionumber = ?
882
		     ORDER BY cn_sort ASC";
883
	my $sth = $dbh->prepare($query);
884
        $sth->execute($biblionumber);
885
886
        while ( my $data = $sth->fetchrow_hashref ) {
887
             my $av = Koha::AuthorisedValues->search({ category => 'LOC', authorised_value => $data->{location} });
888
             $av = $av->count ? $av->next : undef;
889
             $data->{location_intranet} = $av ? $av->lib : '';
890
             $data->{location_opac}     = $av ? $av->opac_description : '';
891
	     push @results, $data;
892
	}
893
	return @results;
894
}
895
896
=head2 GetHostItemsInfo
897
898
    $hostiteminfo = GetHostItemsInfo($hostfield);
899
    Returns the iteminfo for items linked to records via a host field
900
901
=cut
902
903
sub GetHostItemsInfo {
904
    my ($record) = @_;
905
    my @returnitemsInfo;
906
907
    if( !C4::Context->preference('EasyAnalyticalRecords') ) {
908
        return @returnitemsInfo;
909
    }
910
911
    my @fields;
912
    if( C4::Context->preference('marcflavour') eq 'MARC21' ) {
913
        @fields = $record->field('773');
914
    } elsif( C4::Context->preference('marcflavour') eq 'UNIMARC') {
915
        @fields = $record->field('461');
916
    }
917
918
    foreach my $hostfield ( @fields ) {
919
        my $hostbiblionumber = $hostfield->subfield("0");
920
        my $linkeditemnumber = $hostfield->subfield("9");
921
        my @hostitemInfos = GetItemsInfo($hostbiblionumber);
922
        foreach my $hostitemInfo (@hostitemInfos) {
923
            if( $hostitemInfo->{itemnumber} eq $linkeditemnumber ) {
924
                push @returnitemsInfo, $hostitemInfo;
925
                last;
926
            }
927
        }
928
    }
929
    return @returnitemsInfo;
930
}
931
932
=head2 get_hostitemnumbers_of
673
=head2 get_hostitemnumbers_of
933
674
934
  my @itemnumbers_of = get_hostitemnumbers_of($biblionumber);
675
  my @itemnumbers_of = get_hostitemnumbers_of($biblionumber);
(-)a/t/db_dependent/Items.t (-80 / +2 lines)
Lines 19-25 use Modern::Perl; Link Here
19
use Data::Dumper;
19
use Data::Dumper;
20
20
21
use MARC::Record;
21
use MARC::Record;
22
use C4::Items qw( ModItemTransfer GetItemsInfo SearchItems AddItemFromMarc ModItemFromMarc get_hostitemnumbers_of Item2Marc );
22
use C4::Items qw( ModItemTransfer SearchItems AddItemFromMarc ModItemFromMarc get_hostitemnumbers_of Item2Marc );
23
use C4::Biblio qw( GetMarcFromKohaField AddBiblio );
23
use C4::Biblio qw( GetMarcFromKohaField AddBiblio );
24
use C4::Circulation qw( AddIssue );
24
use C4::Circulation qw( AddIssue );
25
use Koha::Items;
25
use Koha::Items;
Lines 34-40 use Koha::AuthorisedValues; Link Here
34
use t::lib::Mocks;
34
use t::lib::Mocks;
35
use t::lib::TestBuilder;
35
use t::lib::TestBuilder;
36
36
37
use Test::More tests => 12;
37
use Test::More tests => 11;
38
38
39
use Test::Warn;
39
use Test::Warn;
40
40
Lines 190-273 subtest 'ModItemTransfer tests' => sub { Link Here
190
    $schema->storage->txn_rollback;
190
    $schema->storage->txn_rollback;
191
};
191
};
192
192
193
subtest 'GetItemsInfo tests' => sub {
194
195
    plan tests => 9;
196
197
    $schema->storage->txn_begin;
198
199
    my $builder = t::lib::TestBuilder->new;
200
    my $library1 = $builder->build({
201
        source => 'Branch',
202
    });
203
    my $library2 = $builder->build({
204
        source => 'Branch',
205
    });
206
    my $itemtype = $builder->build({
207
        source => 'Itemtype',
208
    });
209
210
    Koha::AuthorisedValues->delete;
211
    my $av1 = Koha::AuthorisedValue->new(
212
        {
213
            category         => 'RESTRICTED',
214
            authorised_value => '1',
215
            lib              => 'Restricted Access',
216
            lib_opac         => 'Restricted Access OPAC',
217
        }
218
    )->store();
219
220
    # Add a biblio
221
    my $biblio = $builder->build_sample_biblio();
222
    # Add an item
223
    my $itemnumber = $builder->build_sample_item(
224
        {
225
            biblionumber  => $biblio->biblionumber,
226
            homebranch    => $library1->{branchcode},
227
            holdingbranch => $library2->{branchcode},
228
            itype         => $itemtype->{itemtype},
229
            restricted    => 1,
230
        }
231
    )->itemnumber;
232
233
    my $library = Koha::Libraries->find( $library1->{branchcode} );
234
    $library->opac_info("homebranch OPAC info");
235
    $library->store;
236
237
    $library = Koha::Libraries->find( $library2->{branchcode} );
238
    $library->opac_info("holdingbranch OPAC info");
239
    $library->store;
240
241
    my @results = GetItemsInfo( $biblio->biblionumber );
242
    ok( @results, 'GetItemsInfo returns results');
243
244
    is( $results[0]->{ home_branch_opac_info }, "homebranch OPAC info",
245
        'GetItemsInfo returns the correct home branch OPAC info notice' );
246
    is( $results[0]->{ holding_branch_opac_info }, "holdingbranch OPAC info",
247
        'GetItemsInfo returns the correct holding branch OPAC info notice' );
248
    is( exists( $results[0]->{ onsite_checkout } ), 1,
249
        'GetItemsInfo returns a onsite_checkout key' );
250
    is( $results[0]->{ restricted }, 1,
251
        'GetItemsInfo returns a restricted value code' );
252
    is( $results[0]->{ restrictedvalue }, "Restricted Access",
253
        'GetItemsInfo returns a restricted value description (staff)' );
254
    is( $results[0]->{ restrictedvalueopac }, "Restricted Access OPAC",
255
        'GetItemsInfo returns a restricted value description (OPAC)' );
256
257
    #place item into holds queue
258
    my $dbh = C4::Context->dbh;
259
    @results = GetItemsInfo( $biblio->biblionumber );
260
    is( $results[0]->{ has_pending_hold }, "0",
261
        'Hold not marked as pending/unavailable if nothing in tmp_holdsqueue for item' );
262
263
    $dbh->do(q{INSERT INTO tmp_holdsqueue (biblionumber, itemnumber, surname, borrowernumber ) VALUES (?, ?, "Zorro", 42)}, undef, $biblio->biblionumber, $itemnumber);
264
    @results = GetItemsInfo( $biblio->biblionumber );
265
    is( $results[0]->{ has_pending_hold }, "1",
266
        'Hold marked as pending/unavailable if tmp_holdsqueue is not empty for item' );
267
268
    $schema->storage->txn_rollback;
269
};
270
271
subtest q{Test Koha::Database->schema()->resultset('Item')->itemtype()} => sub {
193
subtest q{Test Koha::Database->schema()->resultset('Item')->itemtype()} => sub {
272
194
273
    plan tests => 4;
195
    plan tests => 4;
(-)a/t/db_dependent/Items/GetHostItemsInfo.t (-42 lines)
Lines 1-41 Link Here
1
use Modern::Perl;
2
3
use Test::More tests => 1;
4
use t::lib::Mocks;
5
use t::lib::TestBuilder;
6
7
use C4::Items qw( GetHostItemsInfo );
8
use Koha::Database;
9
10
my $schema = Koha::Database->new->schema;
11
$schema->storage->txn_begin;
12
13
subtest 'GetHostItemsInfo' => sub {
14
    plan tests => 3;
15
16
    my $builder = t::lib::TestBuilder->new;
17
    my $bib1 = $builder->build_sample_biblio;
18
    my $itm1 = $builder->build_sample_item({ biblionumber => $bib1->biblionumber });
19
    my $itm2 = $builder->build_sample_item({ biblionumber => $bib1->biblionumber });
20
    my $marc = MARC::Record->new;
21
    $marc->append_fields(
22
        MARC::Field->new( '461', '', '', 0 => $bib1->biblionumber, 9 => $itm1->itemnumber ),
23
        MARC::Field->new( '773', '', '', 0 => $bib1->biblionumber, 9 => $itm1->itemnumber ),
24
        MARC::Field->new( '773', '', '', 0 => $bib1->biblionumber, 9 => $itm2->itemnumber ),
25
    );
26
27
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
28
    t::lib::Mocks::mock_preference('EasyAnalyticalRecords', 0);
29
    my @a = C4::Items::GetHostItemsInfo( $marc );
30
    is( @a, 0, 'GetHostItemsInfo returns empty list when pref is disabled' );
31
32
    t::lib::Mocks::mock_preference('EasyAnalyticalRecords', 1);
33
    @a = C4::Items::GetHostItemsInfo( $marc );
34
    is( @a, 2, 'GetHostItemsInfo returns two items for MARC21' );
35
36
    t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
37
    @a = C4::Items::GetHostItemsInfo( $marc );
38
    is( @a, 1, 'GetHostItemsInfo returns one item for UNIMARC' );
39
};
40
41
$schema->storage->txn_rollback;
42
- 

Return to bug 27272