Bug 21413: Unit tests
[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             }
91         }
92     );
93
94     my $item_2 = $builder->build_object(
95         {   class => 'Koha::Items',
96             value => {
97                 biblionumber     => $biblio_2->biblionumber,
98                 biblioitemnumber => $biblio_2->biblioitem->biblioitemnumber,
99                 homebranch       => $library->id,
100                 holdingbranch    => $library->id,
101                 itype            => $itemtype->itemtype,
102             }
103         }
104     );
105
106     my ( $items_2, $second_items_count ) = GetItemsForInventory();
107     is( scalar @{$items_2},     $second_items_count, 'Results and count match' );
108     is( $first_items_count + 2, $second_items_count, 'Two items added, count makes sense' );
109
110     # Add a waiting hold
111     my $reserve_id
112         = C4::Reserves::AddReserve( $library->branchcode, $patron->borrowernumber,
113         $item_1->biblionumber, '', 1, undef, undef, '', "title for fee",
114         $item_1->itemnumber, 'W' );
115
116     my ( $new_items, $new_items_count ) = GetItemsForInventory( { ignore_waiting_holds => 1 } );
117     is( $new_items_count, $first_items_count + 1, 'Item on hold skipped, count makes sense' );
118     is( $new_items->[ scalar @{$new_items} - 1 ]->{title},
119         $title_2, 'Item on hold skipped, last item is the correct one' );
120
121     $schema->storage->txn_rollback;
122 };
123
124 sub OldWay {
125     my ($tdbh)       = @_;
126     my $ldbh         = $tdbh;
127     my $minlocation  = '';
128     my $maxlocation  = '';
129     my $location     = '';
130     my $itemtype     = '';
131     my $ignoreissued = '';
132     my $datelastseen = '';
133     my $branchcode   = '';
134     my $branch       = '';
135     my $offset       = '';
136     my $size         = '';
137     my $statushash   = '';
138
139     my ( @bind_params, @where_strings );
140
141     my $select_columns = q{
142         SELECT items.itemnumber, barcode, itemcallnumber, title, author, biblio.biblionumber, biblio.frameworkcode, datelastseen, homebranch, location, notforloan, damaged, itemlost, withdrawn, stocknumber
143     };
144     my $select_count = q{SELECT COUNT(*)};
145     my $query = q{
146         FROM items
147         LEFT JOIN biblio ON items.biblionumber = biblio.biblionumber
148         LEFT JOIN biblioitems on items.biblionumber = biblioitems.biblionumber
149     };
150     if ($statushash){
151         for my $authvfield (keys %$statushash){
152             if ( scalar @{$statushash->{$authvfield}} > 0 ){
153                 my $joinedvals = join ',', @{$statushash->{$authvfield}};
154                 push @where_strings, "$authvfield in (" . $joinedvals . ")";
155             }
156         }
157     }
158
159     if ($minlocation) {
160         push @where_strings, 'itemcallnumber >= ?';
161         push @bind_params, $minlocation;
162     }
163
164     if ($maxlocation) {
165         push @where_strings, 'itemcallnumber <= ?';
166         push @bind_params, $maxlocation;
167     }
168
169     if ($datelastseen) {
170         $datelastseen = output_pref({ str => $datelastseen, dateformat => 'iso', dateonly => 1 });
171         push @where_strings, '(datelastseen < ? OR datelastseen IS NULL)';
172         push @bind_params, $datelastseen;
173     }
174
175     if ( $location ) {
176         push @where_strings, 'items.location = ?';
177         push @bind_params, $location;
178     }
179
180     if ( $branchcode ) {
181         if($branch eq "homebranch"){
182         push @where_strings, 'items.homebranch = ?';
183         }else{
184             push @where_strings, 'items.holdingbranch = ?';
185         }
186         push @bind_params, $branchcode;
187     }
188
189     if ( $itemtype ) {
190         push @where_strings, 'biblioitems.itemtype = ?';
191         push @bind_params, $itemtype;
192     }
193
194     if ( $ignoreissued) {
195         $query .= "LEFT JOIN issues ON items.itemnumber = issues.itemnumber ";
196         push @where_strings, 'issues.date_due IS NULL';
197     }
198
199     if ( @where_strings ) {
200         $query .= 'WHERE ';
201         $query .= join ' AND ', @where_strings;
202     }
203     my $count_query = $select_count . $query;
204     $query .= ' ORDER BY items.cn_sort, itemcallnumber, title';
205     $query .= " LIMIT $offset, $size" if ($offset and $size);
206     $query = $select_columns . $query;
207     my $sth = $ldbh->prepare($query);
208     $sth->execute( @bind_params );
209
210     my @results = ();
211     my $tmpresults = $sth->fetchall_arrayref({});
212     $sth = $ldbh->prepare( $count_query );
213     $sth->execute( @bind_params );
214     my ($iTotalRecords) = $sth->fetchrow_array();
215
216     my $marc_field_mapping;
217     foreach my $row (@$tmpresults) {
218
219         # Auth values
220         foreach my $field (sort keys %$row) {
221             # If the koha field is mapped to a marc field
222             my ($f, $sf) = C4::Biblio::GetMarcFromKohaField("items.$field", $row->{'frameworkcode'});
223             if (defined($f) and defined($sf)) {
224                 # We replace the code with it's description
225                 my $avs;
226                 if ( exists $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf} ) {
227                     $avs = $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf};
228                 } else {
229                     $avs = Koha::AuthorisedValues->search_by_marc_field({ frameworkcode => $row->{frameworkcode}, tagfield => $f, tagsubfield => $sf, });
230                     $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf} = $avs->unblessed;
231                 }
232                 my $authvals = { map { $_->{authorised_value} => $_->{lib} } @{ $marc_field_mapping->{$row->{frameworkcode}}{$f}{$sf} } };
233                 $row->{$field} = $authvals->{$row->{$field}} if defined $authvals && defined $row->{$field} && defined $authvals->{$row->{$field}};
234             }
235         }
236         push @results, $row;
237     }
238
239     return (\@results, $iTotalRecords);
240 }
241
242 # Helper method to set up a Biblio.
243 sub create_helper_biblio {
244     my $itemtype = shift;
245     my $title    = shift;
246     my $record   = MARC::Record->new();
247
248     $record->append_fields(
249         MARC::Field->new( '245', ' ', ' ', a => $title ),
250         MARC::Field->new( '942', ' ', ' ', c => $itemtype ),
251     );
252
253     my $biblio_id = AddBiblio( $record, '' );
254
255     return Koha::Biblios->find($biblio_id);
256 }