Bug 7614: Add a new method Koha::Libraries->pickup_locations
[koha.git] / t / db_dependent / Koha / Libraries.t
1 #!/usr/bin/perl
2
3 # Copyright 2015 Koha Development team
4 #
5 # This file is part of Koha
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
24 use C4::Biblio;
25 use C4::Context;
26 use C4::Items;
27
28 use Koha::Biblios;
29 use Koha::Item::Transfer::Limits;
30 use Koha::Items;
31 use Koha::Library;
32 use Koha::Libraries;
33 use Koha::Database;
34
35 use t::lib::Mocks;
36 use t::lib::TestBuilder;
37
38 my $schema = Koha::Database->new->schema;
39 $schema->storage->txn_begin;
40
41 my $builder = t::lib::TestBuilder->new;
42 my $nb_of_libraries = Koha::Libraries->search->count;
43 my $new_library_1 = Koha::Library->new({
44     branchcode => 'my_bc_1',
45     branchname => 'my_branchname_1',
46     branchnotes => 'my_branchnotes_1',
47     marcorgcode => 'US-MyLib',
48 })->store;
49 my $new_library_2 = Koha::Library->new({
50     branchcode => 'my_bc_2',
51     branchname => 'my_branchname_2',
52     branchnotes => 'my_branchnotes_2',
53 })->store;
54
55 is( Koha::Libraries->search->count,         $nb_of_libraries + 2,  'The 2 libraries should have been added' );
56
57 my $retrieved_library_1 = Koha::Libraries->find( $new_library_1->branchcode );
58 is( $retrieved_library_1->branchname, $new_library_1->branchname, 'Find a library by branchcode should return the correct library' );
59
60 $retrieved_library_1->delete;
61 is( Koha::Libraries->search->count, $nb_of_libraries + 1, 'Delete should have deleted the library' );
62
63 # Stockrotation relationship testing
64
65 my $new_library_sr = $builder->build({ source => 'Branch' });
66
67 $builder->build({
68     source => 'Stockrotationstage',
69     value  => { branchcode_id => $new_library_sr->{branchcode} },
70 });
71 $builder->build({
72     source => 'Stockrotationstage',
73     value  => { branchcode_id => $new_library_sr->{branchcode} },
74 });
75 $builder->build({
76     source => 'Stockrotationstage',
77     value  => { branchcode_id => $new_library_sr->{branchcode} },
78 });
79
80 my $srstages = Koha::Libraries->find($new_library_sr->{branchcode})
81     ->stockrotationstages;
82 is( $srstages->count, 3, 'Correctly fetched stockrotationstages associated with this branch');
83
84 isa_ok( $srstages->next, 'Koha::StockRotationStage', "Relationship correctly creates Koha::Objects." );
85
86 subtest 'pickup_locations' => sub {
87     plan tests => 2;
88
89     my $from = Koha::Library->new({
90         branchcode => 'zzzfrom',
91         branchname => 'zzzfrom',
92         branchnotes => 'zzzfrom',
93     })->store;
94     my $to = Koha::Library->new({
95         branchcode => 'zzzto',
96         branchname => 'zzzto',
97         branchnotes => 'zzzto',
98     })->store;
99
100     my ($bibnum, $title, $bibitemnum) = create_helper_biblio('DUMMY');
101     # Create item instance for testing.
102     my ($item_bibnum1, $item_bibitemnum1, $itemnumber1)
103     = AddItem({ homebranch => $from->branchcode,
104                 holdingbranch => $from->branchcode } , $bibnum);
105     my ($item_bibnum2, $item_bibitemnum2, $itemnumber2)
106     = AddItem({ homebranch => $from->branchcode,
107                 holdingbranch => $from->branchcode } , $bibnum);
108     my ($item_bibnum3, $item_bibitemnum3, $itemnumber3)
109     = AddItem({ homebranch => $from->branchcode,
110                 holdingbranch => $from->branchcode } , $bibnum);
111     my $item1 = Koha::Items->find($itemnumber1);
112     my $item2 = Koha::Items->find($itemnumber2);
113     my $item3 = Koha::Items->find($itemnumber3);
114     my $biblio = Koha::Biblios->find($bibnum);
115     my $itemtype = $biblio->itemtype;
116
117     subtest 'UseBranchTransferLimits = OFF' => sub {
118         plan tests => 5;
119
120         t::lib::Mocks::mock_preference('UseBranchTransferLimits', 0);
121         t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype');
122         t::lib::Mocks::mock_preference('item-level_itypes', 1);
123         Koha::Item::Transfer::Limits->delete;
124         Koha::Item::Transfer::Limit->new({
125             fromBranch => $from->branchcode,
126             toBranch => $to->branchcode,
127             itemtype => $biblio->itemtype,
128         })->store;
129         my $total_pickup = Koha::Libraries->search({
130             pickup_location => 1
131         })->count;
132         my $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
133         is(C4::Context->preference('UseBranchTransferLimits'), 0, 'Given system '
134            .'preference UseBranchTransferLimits is switched OFF,');
135         is(@{$pickup}, $total_pickup, 'Then the total number of pickup locations '
136            .'equal number of libraries with pickup_location => 1');
137
138         t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype');
139         t::lib::Mocks::mock_preference('item-level_itypes', 1);
140         $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
141         is(@{$pickup}, $total_pickup, '...when '
142            .'BranchTransferLimitsType = itemtype and item-level_itypes = 1');
143         t::lib::Mocks::mock_preference('item-level_itypes', 0);
144         $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
145         is(@{$pickup}, $total_pickup, '...as well as when '
146            .'BranchTransferLimitsType = itemtype and item-level_itypes = 0');
147         t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'ccode');
148         $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
149         is(@{$pickup}, $total_pickup, '...as well as when '
150            .'BranchTransferLimitsType = ccode');
151         t::lib::Mocks::mock_preference('item-level_itypes', 1);
152     };
153
154     subtest 'UseBranchTransferLimits = ON' => sub {
155         plan tests => 4;
156         t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1);
157
158         is(C4::Context->preference('UseBranchTransferLimits'), 1, 'Given system '
159            .'preference UseBranchTransferLimits is switched ON,');
160
161         subtest 'Given BranchTransferLimitsType = itemtype and '
162                .'item-level_itypes = ON' => sub {
163             plan tests => 11;
164
165             t::lib::Mocks::mock_preference('BranchTransferLimitsType','itemtype');
166             t::lib::Mocks::mock_preference('item-level_itypes', 1);
167             Koha::Item::Transfer::Limits->delete;
168             my $limit = Koha::Item::Transfer::Limit->new({
169                 fromBranch => $from->branchcode,
170                 toBranch => $to->branchcode,
171                 itemtype => $item1->effective_itemtype,
172             })->store;
173             ok($item1->effective_itemtype eq $item2->effective_itemtype
174                && $item1->effective_itemtype eq $item3->effective_itemtype,
175                'Given all items of a biblio have same the itemtype,');
176             is($limit->itemtype, $item1->effective_itemtype, 'and given there '
177                .'is an existing transfer limit for that itemtype,');
178             my $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
179             my $found = 0;
180             foreach my $lib (@{$pickup}) {
181                 if ($lib->{'branchcode'} eq $limit->toBranch) {
182                     $found = 1;
183                 }
184             }
185             is($found, 0, 'Then the to-library of which the limit applies for, '
186                .'is not included in the list of pickup libraries.');
187             $pickup = Koha::Libraries->pickup_locations({ item => $item1 });
188             $found = 0;
189             foreach my $lib (@{$pickup}) {
190                 if ($lib->{'branchcode'} eq $limit->toBranch) {
191                     $found = 1;
192                 }
193             }
194             is($found, 0, 'The same applies when asking pickup locations of '
195                .'a single item.');
196             my $others = Koha::Libraries->search({
197                 pickup_location => 1,
198                 branchcode => { 'not in' => [$limit->toBranch] }})->count;
199             is(@{$pickup}, $others, 'However, the number of other pickup '
200                .'libraries is correct.');
201             $item2->itype('BK')->store;
202             ok($item1->effective_itemtype ne $item2->effective_itemtype,
203                'Given one of the item in this biblio has a different itemtype,');
204             is(Koha::Item::Transfer::Limits->search({
205                 itemtype => $item2->effective_itemtype })->count, 0, 'and it is'
206                .' not restricted by transfer limits,');
207             $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
208             $found = 0;
209             foreach my $lib (@{$pickup}) {
210                 if ($lib->{'branchcode'} eq $limit->toBranch) {
211                     $found = 1;
212                 }
213             }
214             is($found, 1, 'Then the to-library of which the limit applies for, '
215                .'is included in the list of pickup libraries.');
216             $pickup = Koha::Libraries->pickup_locations({ item => $item2 });
217             $found = 0;
218             foreach my $lib (@{$pickup}) {
219                 if ($lib->{'branchcode'} eq $limit->toBranch) {
220                     $found = 1;
221                 }
222             }
223             is($found, 1, 'The same applies when asking pickup locations of '
224                .'a that particular item.');
225             Koha::Item::Transfer::Limits->delete;
226             $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
227             $found = 0;
228             foreach my $lib (@{$pickup}) {
229                 if ($lib->{'branchcode'} eq $limit->toBranch) {
230                     $found = 1;
231                 }
232             }
233             is($found, 1, 'Given we deleted transfer limit, the previously '
234                .'transfer-limited library is included in the list.');
235             $pickup = Koha::Libraries->pickup_locations({ item => $item1 });
236             $found = 0;
237             foreach my $lib (@{$pickup}) {
238                 if ($lib->{'branchcode'} eq $limit->toBranch) {
239                     $found = 1;
240                 }
241             }
242             is($found, 1, 'The same applies when asking pickup locations of '
243                .'a single item.');
244         };
245
246         subtest 'Given BranchTransferLimitsType = itemtype and '
247                .'item-level_itypes = OFF' => sub {
248             plan tests => 9;
249
250             t::lib::Mocks::mock_preference('BranchTransferLimitsType','itemtype');
251             t::lib::Mocks::mock_preference('item-level_itypes', 0);
252             $biblio->biblioitem->itemtype('BK')->store;
253             Koha::Item::Transfer::Limits->delete;
254             my $limit = Koha::Item::Transfer::Limit->new({
255                 fromBranch => $from->branchcode,
256                 toBranch => $to->branchcode,
257                 itemtype => $item1->effective_itemtype,
258             })->store;
259
260             ok($item1->effective_itemtype eq 'BK',
261                'Given items use biblio-level itemtype,');
262             is($limit->itemtype, $item1->effective_itemtype, 'and given there '
263                .'is an existing transfer limit for that itemtype,');
264             my $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
265             my $found = 0;
266             foreach my $lib (@{$pickup}) {
267                 if ($lib->{'branchcode'} eq $limit->toBranch) {
268                     $found = 1;
269                 }
270             }
271             is($found, 0, 'Then the to-library of which the limit applies for, '
272                .'is not included in the list of pickup libraries.');
273             $pickup = Koha::Libraries->pickup_locations({ item => $item1 });
274             $found = 0;
275             foreach my $lib (@{$pickup}) {
276                 if ($lib->{'branchcode'} eq $limit->toBranch) {
277                     $found = 1;
278                 }
279             }
280             is($found, 0, 'The same applies when asking pickup locations of '
281                .'a single item.');
282             my $others = Koha::Libraries->search({
283                 pickup_location => 1,
284                 branchcode => { 'not in' => [$limit->toBranch] }})->count;
285             is(@{$pickup}, $others, 'However, the number of other pickup '
286                .'libraries is correct.');
287             Koha::Item::Transfer::Limits->delete;
288             $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
289             $found = 0;
290             foreach my $lib (@{$pickup}) {
291                 if ($lib->{'branchcode'} eq $limit->toBranch) {
292                     $found = 1;
293                 }
294             }
295             is($found, 1, 'Given we deleted transfer limit, the previously '
296                .'transfer-limited library is included in the list.');
297             $limit = Koha::Item::Transfer::Limit->new({
298                 fromBranch => $from->branchcode,
299                 toBranch => $to->branchcode,
300                 itemtype => $item1->itype,
301             })->store;
302             ok($item1->itype ne $item1->effective_itemtype
303                && $limit->itemtype eq $item1->itype, 'Given we have added a limit'
304                .' matching ITEM-level itemtype,');
305             $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
306             $found = 0;
307             foreach my $lib (@{$pickup}) {
308                 if ($lib->{'branchcode'} eq $limit->toBranch) {
309                     $found = 1;
310                 }
311             }
312             is($found, 1, 'Then the limited branch is still included as a pickup'
313                .' library.');
314             $pickup = Koha::Libraries->pickup_locations({ item => $item1 });
315             $found = 0;
316             foreach my $lib (@{$pickup}) {
317                 if ($lib->{'branchcode'} eq $limit->toBranch) {
318                     $found = 1;
319                 }
320             }
321             is($found, 1, 'The same applies when asking pickup locations of '
322                .'a single item.');
323         };
324
325         subtest 'Given BranchTransferLimitsType = ccode' => sub {
326             plan tests => 10;
327
328             t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'ccode');
329             $item1->ccode('hi')->store;
330             $item2->ccode('hi')->store;
331             $item3->ccode('hi')->store;
332             Koha::Item::Transfer::Limits->delete;
333             my $limit = Koha::Item::Transfer::Limit->new({
334                 fromBranch => $from->branchcode,
335                 toBranch => $to->branchcode,
336                 ccode => $item1->ccode,
337             })->store;
338
339             is($limit->ccode, $item1->ccode, 'Given there '
340                .'is an existing transfer limit for that ccode,');
341             my $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
342             my $found = 0;
343             foreach my $lib (@{$pickup}) {
344                 if ($lib->{'branchcode'} eq $limit->toBranch) {
345                     $found = 1;
346                 }
347             }
348             is($found, 0, 'Then the to-library of which the limit applies for, '
349                .'is not included in the list of pickup libraries.');
350             $pickup = Koha::Libraries->pickup_locations({ item => $item1 });
351             $found = 0;
352             foreach my $lib (@{$pickup}) {
353                 if ($lib->{'branchcode'} eq $limit->toBranch) {
354                     $found = 1;
355                 }
356             }
357             is($found, 0, 'The same applies when asking pickup locations of '
358                .'a single item.');
359             my $others = Koha::Libraries->search({
360                 pickup_location => 1,
361                 branchcode => { 'not in' => [$limit->toBranch] }})->count;
362             is(@{$pickup}, $others, 'However, the number of other pickup '
363                .'libraries is correct.');
364             $item3->ccode('yo')->store;
365             ok($item1->ccode ne $item3->ccode,
366                'Given one of the item in this biblio has a different ccode,');
367             is(Koha::Item::Transfer::Limits->search({
368                 ccode => $item3->ccode })->count, 0, 'and it is'
369                .' not restricted by transfer limits,');
370             $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
371             $found = 0;
372             foreach my $lib (@{$pickup}) {
373                 if ($lib->{'branchcode'} eq $limit->toBranch) {
374                     $found = 1;
375                 }
376             }
377             is($found, 1, 'Then the to-library of which the limit applies for, '
378                .'is included in the list of pickup libraries.');
379             $pickup = Koha::Libraries->pickup_locations({ item => $item3 });
380             $found = 0;
381             foreach my $lib (@{$pickup}) {
382                 if ($lib->{'branchcode'} eq $limit->toBranch) {
383                     $found = 1;
384                 }
385             }
386             is($found, 1, 'The same applies when asking pickup locations of '
387                .'a that particular item.');
388             Koha::Item::Transfer::Limits->delete;
389             $pickup = Koha::Libraries->pickup_locations({ biblio => $bibnum });
390             $found = 0;
391             foreach my $lib (@{$pickup}) {
392                 if ($lib->{'branchcode'} eq $limit->toBranch) {
393                     $found = 1;
394                 }
395             }
396             is($found, 1, 'Given we deleted transfer limit, the previously '
397                .'transfer-limited library is included in the list.');
398             $pickup = Koha::Libraries->pickup_locations({ item => $item1 });
399             $found = 0;
400             foreach my $lib (@{$pickup}) {
401                 if ($lib->{'branchcode'} eq $limit->toBranch) {
402                     $found = 1;
403                 }
404             }
405             is($found, 1, 'The same applies when asking pickup locations of '
406                .'a single item.');
407         };
408     };
409 };
410
411 sub create_helper_biblio {
412     my $itemtype = shift;
413     my ($bibnum, $title, $bibitemnum);
414     my $bib = MARC::Record->new();
415     $title = 'Silence in the library';
416     $bib->append_fields(
417         MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
418         MARC::Field->new('245', ' ', ' ', a => $title),
419         MARC::Field->new('942', ' ', ' ', c => $itemtype),
420     );
421     return ($bibnum, $title, $bibitemnum) = AddBiblio($bib, '');
422 }
423
424 $schema->storage->txn_rollback;
425
426 subtest '->get_effective_marcorgcode' => sub {
427
428     plan tests => 4;
429
430     $schema->storage->txn_begin;
431
432     my $library_1 = $builder->build_object({ class => 'Koha::Libraries',
433                                              value => { marcorgcode => 'US-MyLib' } });
434     my $library_2 = $builder->build_object({ class => 'Koha::Libraries',
435                                              value => { marcorgcode => undef } });
436
437     t::lib::Mocks::mock_preference('MARCOrgCode', 'US-Default');
438
439     is( $library_1->get_effective_marcorgcode, 'US-MyLib',
440        'If defined, use library\'s own marc org code');
441     is( $library_2->get_effective_marcorgcode, 'US-Default',
442        'If not defined library\' marc org code, use the one from system preferences');
443
444     t::lib::Mocks::mock_preference('MARCOrgCode', 'Blah');
445     is( $library_2->get_effective_marcorgcode, 'Blah',
446        'Fallback is always MARCOrgCode syspref');
447
448     $library_2->marcorgcode('ThisIsACode')->store();
449     is( $library_2->get_effective_marcorgcode, 'ThisIsACode',
450        'Pick library_2 code');
451
452     $schema->storage->txn_rollback;
453 };