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

(-)a/Koha/Item.pm (+97 lines)
Lines 23-28 use Carp; Link Here
23
23
24
use Koha::Database;
24
use Koha::Database;
25
25
26
use C4::Circulation;
27
use C4::Context;
28
use C4::Members;
29
use C4::Reserves;
30
use Koha::Holds;
31
use Koha::Issues;
32
use Koha::Item::Availability;
26
use Koha::Patrons;
33
use Koha::Patrons;
27
use Koha::Libraries;
34
use Koha::Libraries;
28
35
Lines 50-55 sub effective_itemtype { Link Here
50
    return $self->_result()->effective_itemtype();
57
    return $self->_result()->effective_itemtype();
51
}
58
}
52
59
60
=head3 get_availability
61
62
my $available = $item->get_availability();
63
64
Gets availability of the item. Note that this subroutine does not check patron
65
status. Since availability is a broad term, we cannot claim the item is
66
"available" and cover all the possible cases. Instead, this subroutine simply
67
checks if the item is not onloan, not reserved, not notforloan, not withdrawn,
68
not lost or not damaged.
69
70
Returns Koha::Item::Availability object.
71
72
Use $item->is_available() for a simple Boolean value.
73
74
=cut
75
76
sub get_availability {
77
    my ( $self ) = @_;
78
79
    my $availability = Koha::Item::Availability->new->set_available;
80
81
    if ($self->onloan) {
82
        my $issue = Koha::Issues->search({ itemnumber => $self->itemnumber })->next;
83
        $availability->set_unavailable("onloan", $issue->date_due) if $issue;
84
    }
85
86
    $availability->set_unavailable("withdrawn") if $self->withdrawn;
87
    $availability->set_unavailable("itemlost") if $self->itemlost;
88
    $availability->set_unavailable("restricted") if $self->restricted;
89
90
    if ($self->damaged) {
91
        if (C4::Context->preference('AllowHoldsOnDamagedItems')) {
92
            $availability->push_description("damaged");
93
        } else {
94
            $availability->set_unavailable("damaged");
95
        }
96
    }
97
98
    my $itemtype;
99
    if (C4::Context->preference('item-level_itypes')) {
100
        $itemtype = Koha::ItemTypes->find( $self->itype );
101
    } else {
102
        my $biblioitem = Koha::Biblioitems->find( $self->biblioitemnumber );
103
        $itemtype = Koha::ItemTypes->find( $biblioitem->itemype );
104
    }
105
106
    if ($self->notforloan > 0 || $itemtype && $itemtype->notforloan) {
107
        $availability->set_unavailable("notforloan");
108
    } elsif ($self->notforloan < 0) {
109
        $availability->set_unavailable("ordered");
110
    }
111
112
    if (Koha::Holds->search( [
113
            { itemnumber => $self->itemnumber },
114
            { found => [ '=', 'W', 'T' ] }
115
            ], { order_by => 'priority' } )->count()) {
116
        $availability->set_unavailable("reserved");
117
    }
118
119
    return $availability;
120
}
121
122
=head3 hold_queue_length
123
124
=cut
125
126
sub hold_queue_length {
127
    my ( $self ) = @_;
128
129
    my $reserves = Koha::Holds->search({ itemnumber => $self->itemnumber });
130
    return $reserves->count() if $reserves;
131
    return 0;
132
}
133
53
=head3 home_branch
134
=head3 home_branch
54
135
55
=cut
136
=cut
Lines 74-79 sub holding_branch { Link Here
74
    return $self->{_holding_branch};
155
    return $self->{_holding_branch};
75
}
156
}
76
157
158
=head3 is_available
159
160
my $available = $item->is_available();
161
162
See Koha::Item->get_availability() for documentation.
163
164
=cut
165
166
sub is_available {
167
    my ( $self, $status ) = @_;
168
169
    my $availability = $self->get_availability();
170
171
    return $availability->{available};
172
}
173
77
=head3 last_returned_by
174
=head3 last_returned_by
78
175
79
Gets and sets the last borrower to return an item.
176
Gets and sets the last borrower to return an item.
(-)a/Koha/Item/Availability.pm (+198 lines)
Line 0 Link Here
1
package Koha::Item::Availability;
2
3
# Copyright KohaSuomi 2016
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use Koha::Logger;
23
24
=head1 NAME
25
26
Koha::Item::Availability - Koha Item Availability object class
27
28
=head1 SYNOPSIS
29
30
  my $item = Koha::Items->find(1337);
31
  my $availability = $item->get_availability();
32
  # ref($availability) eq 'Koha::Item::Availability'
33
34
  print $availability->get_description() unless $availability->{available}
35
36
=head1 DESCRIPTION
37
38
This class stores item availability information aiming to having one consistent
39
item availability object instead of many different types of HASHES and Boolean
40
values.
41
42
See Koha::Item for availability subroutines.
43
44
=head2 Class Methods
45
46
=cut
47
48
=head3 new
49
50
Returns a new Koha::Item::Availability object.
51
52
=cut
53
54
sub new {
55
    my ( $class ) = @_;
56
57
    my $self = {
58
        availability_description        => [],
59
        availability_needs_confirmation => undef,
60
        available                       => undef,
61
        expected_available              => undef,
62
    };
63
64
    bless( $self, $class );
65
}
66
67
=head3 push_description
68
69
$availability->push_description("notforloan");
70
$availability->push_description("withdrawn);
71
72
# $availability->{availability_description} = ["notforloan", "withdrawn"]
73
74
Pushes a new description to $availability object. Does not duplicate existing
75
descriptions.
76
77
Returns updated Koha::Item::Availability object.
78
79
=cut
80
81
sub push_description {
82
    my ($self, $description) = @_;
83
84
    return $self unless $description;
85
86
    if (ref($description) eq 'ARRAY') {
87
        foreach my $desc (@$description) {
88
            if (grep(/^$desc$/, $self->{availability_description})){
89
                next;
90
            }
91
            push $self->{availability_description}, $desc;
92
        }
93
    } else {
94
        if (!grep(/^$description$/, $self->{availability_description})){
95
            push $self->{availability_description}, $description;
96
        }
97
    }
98
99
    return $self;
100
}
101
102
=head3 reset
103
104
$availability->reset;
105
106
Resets the object.
107
108
=cut
109
110
sub reset {
111
    my ( $self ) = @_;
112
113
    $self->{available} = undef;
114
    $self->{availability_needs_confirmation} = undef;
115
    $self->{expected_available} = undef;
116
    $self->{availability_description} = [];
117
    return $self;
118
}
119
120
=head3 set_available
121
122
$availability->set_available;
123
124
Sets the Koha::Item::Availability object status to available.
125
   $availability->{available} == 1
126
127
Overrides old availability status, but does not override other stored data in
128
the object. Create a new Koha::Item::Availability object to get a fresh start.
129
Appends any previously defined availability descriptions with push_description().
130
131
Returns updated Koha::Item::Availability object.
132
133
=cut
134
135
sub set_available {
136
    my ($self, $description) = @_;
137
138
    return $self->_update_availability_status(1, 0, $description);
139
}
140
141
=head3 set_needs_confirmation
142
143
$availability->set_needs_confirmation("unbelieveable_reason", "2016-07-07");
144
145
Sets the Koha::Item::Availability object status to unavailable,
146
but needs confirmation.
147
   $availability->{available} == 0
148
   $availability->{availability_needs_confirmation} == 1
149
150
Overrides old availability statuses, but does not override other stored data in
151
the object. Create a new Koha::Item::Availability object to get a fresh start.
152
Appends any previously defined availability descriptions with push_description().
153
Allows you to define expected availability date in C<$expected>.
154
155
Returns updated Koha::Item::Availability object.
156
157
=cut
158
159
sub set_needs_confirmation {
160
    my ($self, $description, $expected) = @_;
161
162
    return $self->_update_availability_status(0, 1, $description, $expected);
163
}
164
165
=head3 set_unavailable
166
167
$availability->set_unavailable("onloan", "2016-07-07");
168
169
Sets the Koha::Item::Availability object status to unavailable.
170
   $availability->{available} == 0
171
172
Overrides old availability status, but does not override other stored data in
173
the object. Create a new Koha::Item::Availability object to get a fresh start.
174
Appends any previously defined availability descriptions with push_description().
175
Allows you to define expected availability date in C<$expected>.
176
177
Returns updated Koha::Item::Availability object.
178
179
=cut
180
181
sub set_unavailable {
182
    my ($self, $description, $expected) = @_;
183
184
    return $self->_update_availability_status(0, 0, $description, $expected);
185
}
186
187
sub _update_availability_status {
188
    my ( $self, $available, $needs, $desc, $expected ) = @_;
189
190
    $self->{available} = $available;
191
    $self->{availability_needs_confirmation} = $needs;
192
    $self->{expected_available} = $expected;
193
    $self->push_description($desc);
194
195
    return $self;
196
}
197
198
1;
(-)a/Koha/REST/V1/Availability.pm (+88 lines)
Line 0 Link Here
1
package Koha::REST::V1::Availability;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Controller';
21
use Mojo::JSON;
22
23
use Koha::Holds;
24
use Koha::Items;
25
26
sub items {
27
    my ($c, $args, $cb) = @_;
28
29
    my @items;
30
    if ($args->{'itemnumber'}) {
31
        push @items, _item_availability(@{$args->{'itemnumber'}});
32
    }
33
    if ($args->{'biblionumber'}) {
34
        my $found_items = Koha::Items->search({ biblionumber => {
35
                            '=', \@{$args->{'biblionumber'}}
36
                            } })->as_list();
37
        my @itemnumbers;
38
        foreach my $item (@$found_items) {
39
            push @itemnumbers, $item->itemnumber;
40
        }
41
42
        push @items, _item_availability(@itemnumbers);
43
    }
44
45
    return $c->$cb({ error => "Item(s) not found"}, 404) unless scalar @items;
46
    return $c->$cb([ @items ], 200);
47
}
48
49
sub _item_availability {
50
    my (@itemnumbers) = @_;
51
52
    my @items;
53
54
    foreach my $itemnumber (@itemnumbers) {
55
        my $item = Koha::Items->find($itemnumber);
56
57
        unless ($item) {
58
            next;
59
        }
60
61
        my $status = $item->get_availability();
62
        delete $status->{availability_needs_confirmation};
63
        $status->{available} = $status->{available}
64
                             ? Mojo::JSON->true
65
                             : Mojo::JSON->false;
66
67
        my $holds;
68
        $holds->{'hold_queue_length'} = $item->hold_queue_length();
69
70
        my $iteminfo = {
71
            itemnumber => $item->itemnumber,
72
            barcode => $item->barcode,
73
            biblionumber => $item->biblionumber,
74
            biblioitemnumber => $item->biblioitemnumber,
75
            holdingbranch => $item->holdingbranch,
76
            homebranch => $item->homebranch,
77
            location => $item->location,
78
            itemcallnumber => $item->itemcallnumber,
79
        };
80
81
        # merge availability, hold information and item information
82
        push @items, { %{$status}, %{$holds}, %{$iteminfo} };
83
    }
84
85
    return @items;
86
}
87
88
1;
(-)a/api/v1/definitions/availabilities.json (+4 lines)
Line 0 Link Here
1
{
2
  "type": "array",
3
  "items": { "$ref": "availability.json" }
4
}
(-)a/api/v1/definitions/availability.json (+57 lines)
Line 0 Link Here
1
{
2
  "type": "object",
3
  "properties": {
4
    "available": {
5
      "type": "boolean",
6
      "description": "availability status"
7
    },
8
    "availability_description": {
9
      "type": "array",
10
      "items": {
11
        "type": ["string"],
12
        "description": "information on item's availability, reasons for unavailability"
13
      },
14
      "description": "more information on item's availability"
15
    },
16
    "barcode": {
17
      "type": ["string", "null"],
18
      "description": "item barcode"
19
    },
20
    "biblioitemnumber": {
21
      "type": "string",
22
      "description": "internally assigned biblio item identifier"
23
    },
24
    "biblionumber": {
25
      "type": "string",
26
      "description": "internally assigned biblio identifier"
27
    },
28
    "expected_available": {
29
      "type": ["string", "null"],
30
      "description": "date this item is expected to be available"
31
    },
32
    "holdQueueLength": {
33
      "type": ["integer", "null"],
34
      "description": "number of holdings placed on title/item"
35
    },
36
    "holdingbranch": {
37
      "type": ["string", "null"],
38
      "description": "library that is currently in possession item"
39
    },
40
    "homebranch": {
41
      "type": ["string", "null"],
42
      "description": "library that owns this item"
43
    },
44
    "itemcallnumber": {
45
      "type": ["string", "null"],
46
      "description": "call number for this item"
47
    },
48
    "itemnumber": {
49
      "type": "string",
50
      "description": "internally assigned item identifier"
51
    },
52
    "location": {
53
      "type": ["string", "null"],
54
      "description": "authorized value for the shelving location for this item"
55
    }
56
  }
57
}
(-)a/api/v1/definitions/index.json (+2 lines)
Lines 1-4 Link Here
1
{
1
{
2
    "availability": { "$ref": "availability.json" },
3
    "availabilities": { "$ref": "availabilities.json" },
2
    "patron": { "$ref": "patron.json" },
4
    "patron": { "$ref": "patron.json" },
3
    "holds": { "$ref": "holds.json" },
5
    "holds": { "$ref": "holds.json" },
4
    "hold": { "$ref": "hold.json" },
6
    "hold": { "$ref": "hold.json" },
(-)a/api/v1/swagger.json (-1 / +49 lines)
Lines 14-19 Link Here
14
  },
14
  },
15
  "basePath": "/api/v1",
15
  "basePath": "/api/v1",
16
  "paths": {
16
  "paths": {
17
    "/availability/items": {
18
      "get": {
19
        "operationId": "itemsAvailability",
20
        "tags": ["items", "availability"],
21
        "parameters": [
22
          { "$ref": "#/parameters/itemnumbersQueryParam" },
23
          { "$ref": "#/parameters/biblionumbersQueryParam" }
24
        ],
25
        "consumes": ["application/json"],
26
        "produces": ["application/json"],
27
        "responses": {
28
          "200": {
29
            "description": "Availability information on item(s)",
30
            "schema": {
31
              "$ref": "#/definitions/availabilities"
32
            }
33
          },
34
          "400": {
35
            "description": "Missing or wrong parameters",
36
            "schema": { "$ref": "#/definitions/error" }
37
          },
38
          "404": {
39
            "description": "No item(s) found",
40
            "schema": { "$ref": "#/definitions/error" }
41
          }
42
        }
43
      }
44
    },
17
    "/patrons": {
45
    "/patrons": {
18
      "get": {
46
      "get": {
19
        "operationId": "listPatrons",
47
        "operationId": "listPatrons",
Lines 360-368 Link Here
360
    }
388
    }
361
  },
389
  },
362
  "definitions": {
390
  "definitions": {
363
    "$ref": "./definitions/index.json"
391
    "$ref": "definitions/index.json"
364
  },
392
  },
365
  "parameters": {
393
  "parameters": {
394
    "biblionumbersQueryParam": {
395
      "name": "biblionumber",
396
      "in": "query",
397
      "description": "Internal biblios identifier",
398
      "type": "array",
399
      "items": {
400
        "type": "integer"
401
      },
402
      "collectionFormat": "ssv"
403
    },
366
    "borrowernumberPathParam": {
404
    "borrowernumberPathParam": {
367
      "name": "borrowernumber",
405
      "name": "borrowernumber",
368
      "in": "path",
406
      "in": "path",
Lines 383-388 Link Here
383
      "description": "Internal item identifier",
421
      "description": "Internal item identifier",
384
      "required": true,
422
      "required": true,
385
      "type": "integer"
423
      "type": "integer"
424
    },
425
    "itemnumbersQueryParam": {
426
      "name": "itemnumber",
427
      "in": "query",
428
      "description": "Internal items identifier",
429
      "type": "array",
430
      "items": {
431
        "type": "integer"
432
      },
433
      "collectionFormat": "ssv"
386
    }
434
    }
387
  }
435
  }
388
}
436
}
(-)a/t/Koha/Item/Availability.t (+42 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright KohaSuomi 2016
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
use Test::More tests => 7;
22
23
use C4::Context;
24
25
use_ok('Koha::Item::Availability');
26
27
my $availability = Koha::Item::Availability->new->set_available;
28
29
is($availability->{available}, 1, "Available");
30
$availability->set_needs_confirmation;
31
is($availability->{availability_needs_confirmation}, 1, "Needs confirmation");
32
$availability->set_unavailable;
33
is($availability->{available}, 0, "Not available");
34
35
$availability->push_description("such available");
36
$availability->push_description("wow");
37
38
is($availability->{availability_description}[0], "such available", "Found correct description 1/2");
39
is($availability->{availability_description}[1], "wow", "Found correct description 2/2");
40
41
$availability->reset;
42
is($availability->{available}, undef, "Availability reset");
(-)a/t/db_dependent/Items.t (-2 / +81 lines)
Lines 20-26 use Modern::Perl; Link Here
20
20
21
use MARC::Record;
21
use MARC::Record;
22
use C4::Biblio;
22
use C4::Biblio;
23
use C4::Circulation;
24
use C4::Reserves;
23
use Koha::Database;
25
use Koha::Database;
26
use Koha::Hold;
27
use Koha::Issue;
28
use Koha::Item::Availability;
24
use Koha::Library;
29
use Koha::Library;
25
30
26
use t::lib::Mocks;
31
use t::lib::Mocks;
Lines 30-35 use Test::More tests => 10; Link Here
30
35
31
use Test::Warn;
36
use Test::Warn;
32
37
38
my @USERENV = (1,'test','MASTERTEST','Test','Test','t','Test',0,);
39
my $BRANCH_IDX = 5;
40
C4::Context->_new_userenv ('DUMMY_SESSION_ID');
41
C4::Context->set_userenv ( @USERENV );
42
33
BEGIN {
43
BEGIN {
34
    use_ok('C4::Items');
44
    use_ok('C4::Items');
35
    use_ok('Koha::Items');
45
    use_ok('Koha::Items');
Lines 432-438 subtest 'SearchItems test' => sub { Link Here
432
442
433
subtest 'Koha::Item(s) tests' => sub {
443
subtest 'Koha::Item(s) tests' => sub {
434
444
435
    plan tests => 5;
445
    plan tests => 25;
436
446
437
    $schema->storage->txn_begin();
447
    $schema->storage->txn_begin();
438
448
Lines 443-448 subtest 'Koha::Item(s) tests' => sub { Link Here
443
    my $library2 = $builder->build({
453
    my $library2 = $builder->build({
444
        source => 'Branch',
454
        source => 'Branch',
445
    });
455
    });
456
    my $borrower = $builder->build({
457
        source => 'Borrower',
458
    });
459
    my $itemtype = $builder->build({
460
        source => 'Itemtype',
461
        value => {
462
            notforloan => 1
463
        }
464
    });
446
465
447
    # Create a biblio and item for testing
466
    # Create a biblio and item for testing
448
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
467
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
Lines 461-466 subtest 'Koha::Item(s) tests' => sub { Link Here
461
    is( ref($holdingbranch), 'Koha::Library', "Got Koha::Library from holding_branch method" );
480
    is( ref($holdingbranch), 'Koha::Library', "Got Koha::Library from holding_branch method" );
462
    is( $holdingbranch->branchcode(), $library2->{branchcode}, "Home branch code matches holdingbranch" );
481
    is( $holdingbranch->branchcode(), $library2->{branchcode}, "Home branch code matches holdingbranch" );
463
482
483
    # Availability tests
484
    my $availability = $item->get_availability();
485
    is (ref($availability), 'Koha::Item::Availability', 'Got Koha::Item::Availability');
486
    is( $availability->{available}, 1, "Item is available" );
487
488
    $item->set({ onloan => "", damaged => 1 })->store();
489
    $availability = $item->get_availability();
490
    is( $availability->{available}, C4::Context->preference('AllowHoldsOnDamagedItems'), "Good availability for damaged item" );
491
    is( $availability->{availability_description}[0], "damaged", "Availability description is 'damaged'" );
492
493
    $item->set({ damaged => 0, withdrawn => 1 })->store();
494
    $availability = $item->get_availability();
495
    is( $availability->{available}, 0, "Item is not available" );
496
    is( $availability->{availability_description}[0], "withdrawn", "Availability description is 'withdrawn'" );
497
498
    $item->set({ withdrawn => 0, itemlost => 1 })->store();
499
    $availability = $item->get_availability();
500
    is( $availability->{available}, 0, "Item is not available" );
501
    is( $availability->{availability_description}[0], "itemlost", "Availability description is 'itemlost'" );
502
503
    $item->set({ itemlost => 0, restricted => 1 })->store();
504
    $availability = $item->get_availability();
505
    is( $availability->{available}, 0, "Item is not available" );
506
    is( $availability->{availability_description}[0], "restricted", "Availability description is 'restricted'" );
507
508
    $item->set({ restricted => 0, notforloan => 1 })->store();
509
    $availability = $item->get_availability();
510
    is( $availability->{available}, 0, "Item is not available" );
511
    is( $availability->{availability_description}[0], "notforloan", "Availability description is 'notforloan'" );
512
513
    $item->set({ notforloan => 0, itype => $itemtype->{itemtype} })->store();
514
    $availability = $item->get_availability();
515
    is( $availability->{available}, 0, "Item is not available" );
516
    is( $availability->{availability_description}[0], "notforloan", "Availability description is 'notforloan' (itemtype)" );
517
518
    $item->set({ itype => undef, barcode => "test" })->store();
519
    my $reserve = Koha::Hold->new(
520
        {
521
            biblionumber   => $item->biblionumber,
522
            itemnumber     => $item->itemnumber,
523
            waitingdate    => '2000-01-01',
524
            borrowernumber => $borrower->{borrowernumber},
525
            branchcode     => $item->homebranch,
526
            suspend        => 0,
527
        }
528
    )->store();
529
    $availability = $item->get_availability();
530
    is( $availability->{available}, 0, "Item is not available" );
531
    is( $availability->{availability_description}[0], "reserved", "Availability description is 'reserved'" );
532
    CancelReserve({ reserve_id => $reserve->reserve_id });
533
534
    $availability = $item->get_availability();
535
    is( $availability->{available}, 1, "Item is available" );
536
537
    my $issue = AddIssue($borrower, $item->barcode, undef, 1);
538
    $item = Koha::Items->find($item->itemnumber); # refresh item
539
    $availability = $item->get_availability();
540
    is( $availability->{available}, 0, "Item is not available" );
541
    is( $availability->{availability_description}[0], "onloan", "Availability description is 'onloan'" );
542
    is( $availability->{expected_available}, $issue->date_due, "Expected to be available '".$issue->date_due."'");
543
464
    $schema->storage->txn_rollback;
544
    $schema->storage->txn_rollback;
465
};
545
};
466
546
Lines 468-474 subtest 'C4::Biblio::EmbedItemsInMarcBiblio' => sub { Link Here
468
    plan tests => 7;
548
    plan tests => 7;
469
549
470
    $schema->storage->txn_begin();
550
    $schema->storage->txn_begin();
471
472
    my $builder = t::lib::TestBuilder->new;
551
    my $builder = t::lib::TestBuilder->new;
473
    my $library1 = $builder->build({
552
    my $library1 = $builder->build({
474
        source => 'Branch',
553
        source => 'Branch',
(-)a/t/db_dependent/api/v1/availability.t (-1 / +195 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
# Copyright KohaSuomi 2016
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use Test::More tests => 76;
23
use Test::Mojo;
24
use t::lib::TestBuilder;
25
26
use Mojo::JSON;
27
28
use C4::Auth;
29
use C4::Circulation;
30
use C4::Context;
31
32
use Koha::Database;
33
use Koha::Items;
34
use Koha::Patron;
35
36
my $builder = t::lib::TestBuilder->new();
37
38
my $dbh = C4::Context->dbh;
39
$dbh->{AutoCommit} = 0;
40
$dbh->{RaiseError} = 1;
41
42
$ENV{REMOTE_ADDR} = '127.0.0.1';
43
my $t = Test::Mojo->new('Koha::REST::V1');
44
45
my @USERENV = (1,'test','MASTERTEST','Test','Test','t','Test',0,);
46
my $BRANCH_IDX = 5;
47
C4::Context->_new_userenv ('DUMMY_SESSION_ID');
48
C4::Context->set_userenv ( @USERENV );
49
50
my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
51
my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
52
53
my $borrower = $builder->build({ source => 'Borrower' });
54
my $biblio = $builder->build({ source => 'Biblio' });
55
my $biblio2 = $builder->build({ source => 'Biblio' });
56
my $biblionumber = $biblio->{biblionumber};
57
my $biblionumber2 = $biblio2->{biblionumber};
58
59
# $item = available, $item2 = unavailable
60
my $items;
61
$items->{available} = build_item($biblionumber);
62
$items->{notforloan} = build_item($biblionumber2, { notforloan => 1 });
63
$items->{damaged} = build_item($biblionumber2, { damaged => 1 });
64
$items->{withdrawn} = build_item($biblionumber2, { withdrawn => 1 });
65
$items->{onloan}  = build_item($biblionumber2, { onloan => undef });
66
$items->{itemlost} = build_item($biblionumber2, { itemlost => 1 });
67
$items->{reserved} = build_item($biblionumber2);
68
my $reserve = Koha::Hold->new(
69
        {
70
            biblionumber   => $items->{reserved}->{biblionumber},
71
            itemnumber     => $items->{reserved}->{itemnumber},
72
            waitingdate    => '2000-01-01',
73
            borrowernumber => $borrower->{borrowernumber},
74
            branchcode     => $items->{reserved}->{homebranch},
75
            suspend        => 0,
76
        }
77
    )->store();
78
79
my $itemnumber = $items->{available}->{itemnumber};
80
81
$t->get_ok("/api/v1/availability/items?itemnumber=-500382")
82
  ->status_is(404);
83
84
$t->get_ok("/api/v1/availability/items?itemnumber=-500382+-500383")
85
  ->status_is(404);
86
87
$t->get_ok("/api/v1/availability/items?biblionumber=-500382")
88
  ->status_is(404);
89
90
$t->get_ok("/api/v1/availability/items?biblionumber=-500382+-500383")
91
  ->status_is(404);
92
93
# available item
94
$t->get_ok("/api/v1/availability/items?itemnumber=$itemnumber")
95
  ->status_is(200)
96
  ->json_is('/0/itemnumber', $itemnumber)
97
  ->json_is('/0/biblionumber', $biblionumber)
98
  ->json_is('/0/available', Mojo::JSON->true)
99
  ->json_is('/0/availability_description', [])
100
  ->json_is('/0/hold_queue_length', 0);
101
$t->get_ok("/api/v1/availability/items?biblionumber=$biblionumber")
102
  ->status_is(200)
103
  ->json_is('/0/itemnumber', $itemnumber)
104
  ->json_is('/0/biblionumber', $biblionumber)
105
  ->json_is('/0/available', Mojo::JSON->true)
106
  ->json_is('/0/availability_description', [])
107
  ->json_is('/0/hold_queue_length', 0);
108
109
# notforloan item
110
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{notforloan}->{itemnumber})
111
  ->status_is(200)
112
  ->json_is('/0/itemnumber', $items->{notforloan}->{itemnumber})
113
  ->json_is('/0/biblionumber', $biblionumber2)
114
  ->json_is('/0/available', Mojo::JSON->false)
115
  ->json_is('/0/availability_description/0', "notforloan")
116
  ->json_is('/0/hold_queue_length', 0);
117
118
# damaged item
119
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{damaged}->{itemnumber})
120
  ->status_is(200)
121
  ->json_is('/0/itemnumber', $items->{damaged}->{itemnumber})
122
  ->json_is('/0/biblionumber', $biblionumber2)
123
  ->json_is('/0/available', C4::Context->preference('AllowHoldsOnDamagedItems') ? Mojo::JSON->true : Mojo::JSON->false)
124
  ->json_is('/0/availability_description/0', "damaged")
125
  ->json_is('/0/hold_queue_length', 0);
126
127
# withdrawn item
128
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{withdrawn}->{itemnumber})
129
  ->status_is(200)
130
  ->json_is('/0/itemnumber', $items->{withdrawn}->{itemnumber})
131
  ->json_is('/0/biblionumber', $biblionumber2)
132
  ->json_is('/0/available', Mojo::JSON->false)
133
  ->json_is('/0/availability_description/0', "withdrawn")
134
  ->json_is('/0/hold_queue_length', 0);
135
136
# lost item
137
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{itemlost}->{itemnumber})
138
  ->status_is(200)
139
  ->json_is('/0/itemnumber', $items->{itemlost}->{itemnumber})
140
  ->json_is('/0/biblionumber', $biblionumber2)
141
  ->json_is('/0/available', Mojo::JSON->false)
142
  ->json_is('/0/availability_description/0', "itemlost")
143
  ->json_is('/0/hold_queue_length', 0);
144
145
my $issue = AddIssue($borrower, $items->{onloan}->{barcode}, undef, 1);
146
147
# issued item
148
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{onloan}->{itemnumber})
149
  ->status_is(200)
150
  ->json_is('/0/itemnumber', $items->{onloan}->{itemnumber})
151
  ->json_is('/0/biblionumber', $biblionumber2)
152
  ->json_is('/0/available', Mojo::JSON->false)
153
  ->json_is('/0/availability_description/0', "onloan")
154
  ->json_is('/0/expected_available', $issue->date_due)
155
  ->json_is('/0/hold_queue_length', 0);
156
157
# reserved item
158
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{reserved}->{itemnumber})
159
  ->status_is(200)
160
  ->json_is('/0/itemnumber', $items->{reserved}->{itemnumber})
161
  ->json_is('/0/biblionumber', $biblionumber2)
162
  ->json_is('/0/available', Mojo::JSON->false)
163
  ->json_is('/0/availability_description/0', "reserved")
164
  ->json_is('/0/hold_queue_length', 1);
165
166
# multiple in one request
167
$t->get_ok("/api/v1/availability/items?itemnumber=".$items->{notforloan}->{itemnumber}."+$itemnumber+-500382")
168
  ->status_is(200)
169
  ->json_is('/0/itemnumber', $items->{notforloan}->{itemnumber})
170
  ->json_is('/0/biblionumber', $biblionumber2)
171
  ->json_is('/0/available', Mojo::JSON->false)
172
  ->json_is('/0/availability_description/0', "notforloan")
173
  ->json_is('/1/itemnumber', $itemnumber)
174
  ->json_is('/1/biblionumber', $biblionumber)
175
  ->json_is('/1/available', Mojo::JSON->true)
176
  ->json_is('/1/availability_description', [])
177
  ->json_is('/1/hold_queue_length', 0);
178
179
sub build_item {
180
    my ($biblionumber, $field) = @_;
181
182
    return $builder->build({
183
        source => 'Item',
184
        value => {
185
            biblionumber => $biblionumber,
186
            notforloan => $field->{notforloan} || 0,
187
            damaged => $field->{damaged} || 0,
188
            withdrawn => $field->{withdrawn} || 0,
189
            itemlost => $field->{itemlost} || 0,
190
            restricted => $field->{restricted} || undef,
191
            onloan => $field->{onloan} || undef,
192
            itype => $field->{itype} || undef,
193
        }
194
    });
195
}

Return to bug 16826