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

(-)a/Koha/Availability.pm (+216 lines)
Line 0 Link Here
1
package Koha::Availability;
2
3
# Copyright Koha-Suomi Oy 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::Exceptions;
23
24
=head1 NAME
25
26
Koha::Availability - Koha Availability object class
27
28
=head1 SYNOPSIS
29
30
Class for storing availability information.
31
32
=head1 DESCRIPTION
33
34
A class to contain availability information in an uniform way.
35
36
Koha::Availability has no actual availability calculation logic, but simply
37
methods to get and set availability information into the object. To get actual
38
availability responses for items/biblios, use e.g. Koha::Availability::Hold.
39
40
Koha::Availability can represent four levels of availability statuses:
41
1. available
42
2. available, with an additional note
43
3. available, but requires confirmation
44
4. unavailable
45
46
Additional notes, reasons for a need to confirm and reasons for unavailabilities
47
are kept in a HASHref, where each value in my proposal is a Koha::Exceptions::*.
48
This allows us to easily store any additional data directly into the reason. For
49
example, if we want to check biblio availability for hold and find out it is not
50
available, the HASHref for unavailabilities has a Koha::Exceptions::Patron::Debt
51
that contains parameters "current_outstanding" and "max_outstanding" which lets
52
us pick up the information easily later on without making new queries.
53
54
With such design, Koha::Availability will be used as a parent for different types
55
of availabilities, like hold and checkout availability. This allows each type of
56
availability to perform uniformly; the ways to find out availability will be the
57
same and the problems with availability are represented the same way.
58
59
Example of inheritance described above:
60
61
       Koha::Availability::Hold          Koha::Availability::Checkout
62
                  |                                   |
63
                   \_________________________________/
64
                                   |
65
                          Koha::Availability
66
67
=head2 Class Methods
68
69
=cut
70
71
=head3 new
72
73
Creates a new Koha::Availability object.
74
75
=cut
76
77
sub new {
78
    my ($class, $params) = @_;
79
80
    my $self = {
81
        available                       => 1,     # boolean value yes / no
82
        confirmations                   => {},    # needs confirmation reasons
83
        notes                           => {},    # availability notes
84
        unavailabilities                => {},    # unavailability reasons
85
        expected_available              => undef, # expected availability date
86
    };
87
88
    bless $self, $class;
89
90
    return $self;
91
}
92
93
sub AUTOLOAD {
94
    my ($self, $params) = @_;
95
96
    my $method = our $AUTOLOAD;
97
    $method =~ s/.*://;
98
99
    # Accessor for class parameters
100
    if (exists $self->{$method}) {
101
        unless (defined $params) {
102
            return $self->{$method};
103
        } else {
104
            $self->{$method} = $params;
105
            return $self;
106
        }
107
    } elsif ($self->can($method)) {
108
        $self->$method($params);
109
    } else {
110
        Koha::Exceptions::Object::MethodNotFound->throw(
111
            "No method $method for " . ref($self)
112
        );
113
    }
114
}
115
116
=head3 confirm
117
118
Get: $availability->confirm
119
    Returns count of reasons that require confirmation.
120
    To get each reason, use accessor $availability->confirmations.
121
122
Set: $availability->confirm(Koha::Exceptions::Item::Damaged->new)
123
    Maintains the availability status as available, and adds the given reason
124
    into $availability->confirmations.
125
126
=cut
127
128
sub confirm {
129
    my ($self, $status) = @_;
130
131
    if (!$status) {
132
        my $keys = keys %{$self->{confirmations}};
133
        return $keys ? $keys : 0;
134
    } else {
135
        if (!keys %{$self->{unavailabilities}}) {
136
            $self->{available} = 1;
137
        }
138
        my $key = ref($status);
139
        $self->{confirmations}->{$key} = $status;
140
    }
141
}
142
143
=head3 note
144
145
Get: $availability->note
146
    Returns count of additional notes.
147
    To get each reason, use accessor $availability->notes.
148
149
Set: $availability->note(Koha::Exceptions::Item::Lost->new)
150
    If no unavailability reasons are stored, sets availability true, and adds
151
    given object as additional availability note. Otherwise does nothing.
152
153
=cut
154
155
sub note {
156
    my ($self, $status) = @_;
157
158
    if (!$status) {
159
        my $keys = keys %{$self->{notes}};
160
        return $keys ? $keys : 0;
161
    } else {
162
        if (!keys %{$self->{notes}}) {
163
            $self->{available} = 1;
164
        }
165
        my $key = ref($status);
166
        $self->{notes}->{$key} = $status;
167
    }
168
}
169
170
=head3 reset
171
172
$availability->reset
173
174
Resets availability status to available and cleans the object from any existing
175
notes, confirmations and unavailabilities.
176
177
=cut
178
179
sub reset {
180
    my ($self) = @_;
181
182
    $self->{'available'} = 1;
183
    $self->{'confirmations'} = {};
184
    $self->{'notes'} = {};
185
    $self->{'unavailabilities'} = {};
186
187
    return $self;
188
}
189
190
=head3 unavailable
191
192
Accessor for unavailability.
193
194
Get: $availability->unavailable
195
    Returns count of reasons that make availability false.
196
    To get all reasons, use accessor $availability->unavailabilities.
197
198
Set: $availability->unavailable(Koha::Exceptions::Item::Withdrawn->new)
199
    Sets availability status as "unavailable" and stores the given reason.
200
201
=cut
202
203
sub unavailable {
204
    my ($self, $status) = @_;
205
206
    if (!$status) {
207
        my $keys = keys %{$self->{unavailabilities}};
208
        return $keys ? $keys : 0;
209
    } else {
210
        $self->{available} = 0;
211
        my $key = ref($status);
212
        $self->{unavailabilities}->{$key} = $status;
213
    }
214
}
215
216
1;
(-)a/t/Koha/Availability.t (-1 / +102 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright Koha-Suomi Oy 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 => 2;
22
use t::lib::TestBuilder;
23
24
use Koha::Exceptions;
25
26
use_ok('Koha::Availability');
27
28
my $exception;
29
30
subtest 'Instantiate new Koha::Availability -object' => sub {
31
    plan tests => 6;
32
33
    my $availability = Koha::Availability->new;
34
    is(ref($availability), 'Koha::Availability', 'Object instantiated successfully.');
35
36
    subtest 'Check Koha::Availability -object default values' => \&check_default_values;
37
    subtest 'Add additional notes' => sub {
38
        plan tests => 3;
39
40
        $availability = Koha::Availability->new;
41
        $exception = 'Koha::Exceptions::Exception';
42
        $availability->note($exception->new( error => 'Test note' ));
43
        is($availability->note, 1, 'Added a test note with additional data.');
44
        is(ref($availability->notes->{$exception}), $exception, 'The object contains this test note.');
45
        is($availability->notes->{$exception}->error, 'Test note', 'The note contains our additional data.');
46
    };
47
48
    subtest 'Set availability to be confirmed by a librarian' => sub {
49
        plan tests => 5;
50
51
        $availability = Koha::Availability->new;
52
        $exception = 'Koha::Exceptions::Exception';
53
        $availability->confirm($exception->new( error => 'Needs to be confirmed' ));
54
        is($availability->confirm, 1, 'Added a new exception to be confirmed by librarian, with some additional data.');
55
        my $confirmations = $availability->confirmations;
56
        is(ref($confirmations->{$exception}), $exception, 'The object contains this exception.');
57
        is($confirmations->{$exception}->error, 'Needs to be confirmed', 'Additional data is also stored.');
58
        is($availability->available, 1, 'Although we have something to be confirmed, availability is still true.');
59
        $availability->confirm(Koha::Exceptions::MissingParameter->new( error => 'Just a test.' ));
60
        is($availability->confirm, 2, 'Added another exception. $availability->confirm returns the correct count.');
61
    };
62
63
    subtest 'Set availability to unavailable' => sub {
64
        plan tests => 6;
65
66
        $availability = Koha::Availability->new;
67
        $exception = 'Koha::Exceptions::Exception';
68
        $availability->unavailable($exception->new( error => 'Not available' ));
69
        is($availability->unavailable, 1, 'Added a new exception with some additional data and made the availability false.');
70
        my $unavailabilities = $availability->unavailabilities;
71
        is(ref($unavailabilities->{$exception}), $exception, 'The object contains this exception.');
72
        is($unavailabilities->{$exception}->error, 'Not available', 'Additional data is also stored.');
73
        is($availability->unavailable, 1, 'Availability is unavailable.');
74
        is($availability->available, 0, 'Not available.');
75
        $availability->unavailable(Koha::Exceptions::MissingParameter->new( error => 'Just a test.' ));
76
        is($availability->unavailable, 2, 'Added another exception. $availability->confirm returns the correct count.');
77
    };
78
79
    subtest 'Reset Koha::Availability -object' => sub {
80
        plan tests => 3;
81
82
        $availability = Koha::Availability->new;
83
        $exception = 'Koha::Exceptions::Exception';
84
        $availability->unavailable($exception->new( error => 'Not available' ));
85
        ok(!$availability->available, 'Set Availability-object as unavailable.');
86
        ok($availability->reset, 'Object reset');
87
        ok($availability->available, 'Availability is now true.');
88
    };
89
};
90
91
sub check_default_values {
92
    plan tests => 5;
93
94
    my $availability = Koha::Availability->new;
95
    is($availability->available, 1, 'Koha::Availability -object is available.');
96
    is(keys %{$availability->unavailabilities}, 0, 'There are no unavailabilities.');
97
    is(keys %{$availability->confirmations}, 0, 'Nothing needs to be confirmed.');
98
    is(keys %{$availability->notes}, 0, 'There are no additional notes.');
99
    is($availability->expected_available, undef, 'There is no expectation of future availability');
100
}
101
102
1;

Return to bug 17712