Bug 21413: Fix condition to avoid operator bnding isssues
[koha.git] / t / db_dependent / Items / GetItemsForInventory.t
1 #!/usr/bin/perl
2 #
3 # This file is part of Koha.
4 #
5 # Copyright (c) 2015   Mark Tompsett
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21
22 use Test::More tests => 7;
23 use t::lib::TestBuilder;
24
25 use C4::Biblio qw(AddBiblio);
26 use C4::Reserves;
27 use Koha::AuthorisedValues;
28 use Koha::Biblios;
29 use Koha::Database;
30 use MARC::Record;
31
32 BEGIN {
33     use_ok('C4::Context');
34     use_ok('C4::Items');
35     use_ok('C4::Biblio');
36     use_ok('C4::Koha');
37 }
38
39 can_ok('C4::Items','GetItemsForInventory');
40
41 my $schema  = Koha::Database->new->schema;
42 my $builder = t::lib::TestBuilder->new;
43
44 subtest 'Old version is unchanged' => sub {
45
46     plan tests => 1;
47
48     $schema->storage->txn_begin;
49
50     my $dbh = $schema->storage->dbh;
51
52     my ($oldResults, $oldCount) = OldWay($dbh);
53     my ($newResults, $newCount) = GetItemsForInventory;
54
55     is_deeply($newResults,$oldResults,"Inventory results unchanged.");
56
57     $schema->storage->txn_rollback;
58 };
59
60 subtest 'Skip items with waiting holds' => sub {
61
62     plan tests => 5;
63
64     $schema->storage->txn_begin;
65
66     my $library = $builder->build_object( { class => 'Koha::Libraries' } );
67     my $itemtype
68         = $builder->build_object( { class => 'Koha::ItemTypes', value => { rentalcharge => 0 } } );
69     my $patron = $builder->build_object(
70         { class => 'Koha::Patrons', value => { branchcode => $library->id } } );
71
72     my $title_1 = 'Title 1';
73     my $title_2 = 'Title 2';
74
75     my $biblio_1 = create_helper_biblio( $itemtype->itemtype, $title_1 );
76     my $biblio_2 = create_helper_biblio( $itemtype->itemtype, $title_2 );
77
78     my ( $items_1, $first_items_count ) = GetItemsForInventory();
79     is( scalar @{$items_1}, $first_items_count, 'Results and count match' );
80
81     # Add two items, so we don't depend on existing data
82     my $item_1 = $builder->build_object(
83         {   class => 'Koha::Items',
84             value => {
85                 biblionumber     => $biblio_1->biblionumber,
86                 biblioitemnumber => $biblio_1->biblioitem->biblioitemnumber,
87                 homebranch       => $library->id,
88                 holdingbranch    => $library->id,
89                 itype            => $itemtype->itemtype,
90                 reserves         => undef
91             }
92         }
93     );
94
95     my $item_2 = $builder->build_object(
96         {   class => 'Koha::Items',
97             value => {
98                 biblionumber     => $biblio_2->biblionumber,
99                 biblioitemnumber => $biblio_2->biblioitem->biblioitemnumber,
100                 homebranch       => $library->id,
101                 holdingbranch    => $library->id,
102                 itype            => $itemtype->itemtype,
103                 reserves         => undef
104             }
105         }
106     );
107
108     my ( $items_2, $second_items_count ) = GetItemsForInventory();
109     is( scalar @{$items_2},     $second_items_count, 'Results and count match' );
110     is( $first_items_count + 2, $second_items_count, 'Two items added, count makes sense' );
111
112     # Add a waiting hold
113     my $reserve_id
114         = C4::Reserves::AddReserve( $library->branchcode, $patron->borrowernumber,
115         $item_1->biblionumber, '', 1, undef, undef, '', "title for fee",
116         $item_1->itemnumber, 'W' );
117
118     my ( $new_items, $new_items_count ) = GetItemsForInventory( { ignore_waiting_holds => 1 } );
119     is( $new_items_count, $first_items_count + 1, 'Item on hold skipped, count makes sense' );
120     is( $new_items->[ scalar @{$new_items} - 1 ]->{title},
121         $title_2, 'Item on hold skipped, last item is the correct one' );
122
123     $schema->storage->txn_rollback;
124 };
125
126 sub OldWay {
127     my ($tdbh)       = @_;
128     my $ldbh         = $tdbh;
129     my $minlocation  = '';
130     my $maxlocation  = '';
131     my $location     = '';
132     my $itemtype     = '';
133     my $ignoreissued = '';
134     my $datelastseen = '';
135     my $branchcode   = '';
136     my $branch       = '';
137     my $offset       = '';
138     my $size         = '';
139     my $statushash   = '';
140
141     my ( @bind_params, @where_strings );
142
143     my $select_columns = q{
144         SELECT items.itemnumber, barcode, itemcallnumber, title, author, biblio.biblionumber, biblio.frameworkcode, datelastseen, homebranch, location, notforloan, damaged, itemlost, withdrawn, stocknumber
145     };
146     my $select_count = q{SELECT COUNT(*)};
147     my $query = q{
148         FROM items
149         LEFT JOIN biblio ON items.biblionumber = biblio.biblionumber
150         LEFT JOIN biblioitems on items.biblionumber = biblioitems.biblionumber
151     };
152     if ($statushash){
153         for my $authvfield (keys %$statushash){
154             if ( scalar @{$statushash->{$authvfield}} > 0 ){
155                 my $joinedvals = join ',', @{$statushash->{$authvfield}};
156                 push @where_strings, "$authvfield in (" . $joinedvals . ")";
157             }
158         }
159     }
160
161     if ($minlocation) {
162         push @where_strings, 'itemcallnumber >= ?';
163         push @bind_params, $minlocation;
164     }
165
166     if ($maxlocation) {
167         push @where_strings, 'itemcallnumber <= ?';
168         push @bind_params, $maxlocation;
169     }
170
171     if ($datelastseen) {
172         $datelastseen = output_pref({ str => $datelastseen, dateformat => 'iso', dateonly => 1 });
173         push @where_strings, '(datelastseen < ? OR datelastseen IS NULL)';
174         push @bind_params, $datelastseen;
175     }
176
177     if ( $location ) {
178         push @where_strings, 'items.location = ?';
179         push @bind_params, $location;
180     }
181
182     if ( $branchcode ) {
183         if($branch eq "homebranch"){
184         push @where_strings, 'items.homebranch = ?';
185         }else{
186             push @where_strings, 'items.holdingbranch = ?';
187         }
188         push @bind_params, $branchcode;
189     }
190
191     if ( $itemtype ) {
192         push @where_strings, 'biblioitems.itemtype = ?';
193         push @bind_params, $itemtype;
194     }
195
196     if ( $ignoreissued) {
197         $query .= "LEFT JOIN issues ON items.itemnumber = issues.itemnumber ";
198         push @where_strings, 'issues.date_due IS NULL';
199     }
200
201     if ( @where_strings ) {
202         $query .= 'WHERE ';
203         $query .= join ' AND ', @where_strings;
204     }
205     my $count_query = $select_count . $query;
206     $query .= ' ORDER BY items.cn_sort, itemcallnumber, title';
207     $query .= " LIMIT $offset, $size" if ($offset and $size);
208     $query = $select_columns . $query;
209     my $sth = $ldbh->prepare($query);
210     $sth->execute( @bind_params );
211
212     my @results = ();
213     my $tmpresults = $sth->fetchall_arrayref({});
214     $sth = $ldbh->prepare( $count_query );
215     $sth->execute( @bind_params );
216     my ($iTotalRecords) = $sth->fetchrow_array();
217
218     my $marc_field_mapping;
219     foreach my $row (@$tmpresults) {
220
221         # Auth values
222         foreach my $field (sort keys %$row) {
223             # If the koha field is mapped to a marc field
224             my ($f, $sf) = C4::Biblio::GetMarcFromKohaField("items.$field", $row->{'frameworkcode'});
225             if (defined($f) and defined($sf)) {
226                 # We replace the code with it's description
227                 my $avs;
228                 if ( exists $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf} ) {
229                     $avs = $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf};
230                 } else {
231                     $avs = Koha::AuthorisedValues->search_by_marc_field({ frameworkcode => $row->{frameworkcode}, tagfield => $f, tagsubfield => $sf, });
232                     $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf} = $avs->unblessed;
233                 }
234                 my $authvals = { map { $_->{authorised_value} => $_->{lib} } @{ $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf} } };
235                 $row->{$field} = $authvals->{$row->{$field}} if defined $authvals && defined $row->{$field} && defined $authvals->{$row->{$field}};
236             }
237         }
238         push @results, $row;
239     }
240
241     return (\@results, $iTotalRecords);
242 }
243
244 # Helper method to set up a Biblio.
245 sub create_helper_biblio {
246     my $itemtype = shift;
247     my $title    = shift;
248     my $record   = MARC::Record->new();
249
250     $record->append_fields(
251         MARC::Field->new( '245', ' ', ' ', a => $title ),
252         MARC::Field->new( '942', ' ', ' ', c => $itemtype ),
253     );
254
255     my $biblio_id = AddBiblio( $record, '' );
256
257     return Koha::Biblios->find($biblio_id);
258 }