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

(-)a/Koha/CurbsidePickup.pm (-10 / +163 lines)
Lines 2-19 package Koha::CurbsidePickup; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
Lines 23-31 use Koha::Database; Link Here
23
23
24
use base qw(Koha::Object);
24
use base qw(Koha::Object);
25
25
26
use C4::Circulation qw( CanBookBeIssued AddIssue );
27
use Koha::DateUtils qw( dt_from_string );
26
use Koha::Patron;
28
use Koha::Patron;
27
use Koha::Library;
29
use Koha::Library;
28
use Koha::CurbsidePickupIssues;
30
use Koha::CurbsidePickupIssues;
31
use Koha::Exceptions::CurbsidePickup;
29
32
30
=head1 NAME
33
=head1 NAME
31
34
Lines 35-40 Koha::CurbsidePickup - Koha Curbside Pickup Object class Link Here
35
38
36
=head2 Class methods
39
=head2 Class methods
37
40
41
=cut
42
43
=head3 new
44
45
=cut
46
47
sub new {
48
    my ( $self, $params ) = @_;
49
50
    my $existing_curbside_pickups = Koha::CurbsidePickups->search(
51
        {
52
            branchcode                => $params->{branchcode},
53
            borrowernumber            => $params->{borrowernumber},
54
            delivered_datetime        => undef,
55
            scheduled_pickup_datetime => { '>' => \'DATE(NOW())' },
56
        }
57
    );
58
    Koha::Exceptions::CurbsidePickup::TooManyPickups->throw(
59
        branchcode     => $params->{branchcode},
60
        borrowernumber => $params->{borrowernumber}
61
    ) if $existing_curbside_pickups->count;
62
63
    my $policy =
64
      Koha::CurbsidePickupPolicies->find( { branchcode => $params->{branchcode} } );
65
    my $is_valid =
66
      $policy->is_valid_pickup_datetime( $params->{scheduled_pickup_datetime} );
67
    unless ($is_valid) {
68
        my $error = @{ $is_valid->messages }[0]->message;
69
        Koha::Exceptions::CurbsidePickup::NoMatchingSlots->throw
70
          if $error eq 'no_matching_slots';
71
        Koha::Exceptions::CurbsidePickup::NoMorePickupsAvailable->throw
72
          if $error eq 'no_more_available';
73
        Koha::Exceptions->throw(
74
            "Error message must raise the appropriate exception");
75
    }
76
77
    return $self->SUPER::new($params);
78
}
79
38
=head3 checkouts
80
=head3 checkouts
39
81
40
Return the checkouts linked to this pickup
82
Return the checkouts linked to this pickup
Lines 91-96 sub library { Link Here
91
    return Koha::Library->_new_from_dbic( $rs );
133
    return Koha::Library->_new_from_dbic( $rs );
92
}
134
}
93
135
136
=head3 mark_as_staged
137
138
Mark the pickup as staged
139
140
=cut
141
142
sub mark_as_staged {
143
    my ( $self ) = @_;
144
    my $staged_by = C4::Context->userenv ? C4::Context->userenv->{number} : undef;
145
    $self->set(
146
        {
147
            staged_datetime  => dt_from_string(),
148
            staged_by        => $staged_by,
149
            arrival_datetime => undef,
150
        }
151
    )->store;
152
}
153
154
=head3 mark_as_unstaged
155
156
Mark the pickup as unstaged
157
158
=cut
159
160
sub mark_as_unstaged {
161
    my ( $self ) = @_;
162
163
    $self->set(
164
        {
165
            staged_datetime  => undef,
166
            staged_by        => undef,
167
            arrival_datetime => undef,
168
        }
169
    )->store;
170
}
171
172
=head3 mark_patron_has_arrived
173
174
Set the arrival time of the patron
175
176
=cut
177
178
sub mark_patron_has_arrived {
179
    my ( $self ) = @_;
180
    $self->set(
181
        {
182
            arrival_datetime => dt_from_string(),
183
        }
184
    )->store;
185
}
186
187
=head3 mark_as_delivered
188
189
Mark the pickup as delivered. The waiting holds will be filled.
190
191
=cut
192
193
sub mark_as_delivered {
194
    my ( $self ) = @_;
195
    my $patron          = $self->patron;
196
    my $holds           = $patron->holds;
197
    my $branchcode = C4::Context->userenv ? C4::Context->userenv->{branch} : undef;
198
    foreach my $hold ( $holds->as_list ) {
199
        if ( $hold->found eq 'W' && $branchcode && $hold->branchcode eq $branchcode ) {
200
            my ( $issuingimpossible, $needsconfirmation ) =
201
              C4::Circulation::CanBookBeIssued( $patron, $hold->item->barcode );
202
203
            unless ( keys %$issuingimpossible ) {
204
                my $issue =
205
                  C4::Circulation::AddIssue( $patron->unblessed, $hold->item->barcode );
206
                if ($issue) {
207
                    Koha::CurbsidePickupIssue->new(
208
                        {
209
                            curbside_pickup_id => $self->id,
210
                            issue_id           => $issue->id,
211
                            reserve_id         => $hold->id,
212
                        }
213
                    )->store();
214
                }
215
                else {
216
                    Koha::Exceptions->throw(sprintf("Cannot checkout hold %s for patron %s: %s", $patron->id, $hold->id, join(", ", keys %$issuingimpossible)));
217
                }
218
            }
219
        }
220
    }
221
222
    my $delivered_by = C4::Context->userenv ? C4::Context->userenv->{number} : undef;
223
    $self->arrival_datetime(dt_from_string) unless $self->arrival_datetime;
224
    $self->set(
225
        {
226
            delivered_datetime => dt_from_string(),
227
            delivered_by       => $delivered_by,
228
        }
229
    )->store;
230
}
231
232
=head3 status
233
234
Return the status of the pickup, can be 'to-be-staged', 'staged-and-ready', 'patron-is-outside' or 'delivered'.
235
236
=cut
237
238
sub status {
239
    my ($self) = @_;
240
    return
241
        !defined $self->staged_datetime    ? 'to-be-staged'
242
      : !defined $self->arrival_datetime   ? 'staged-and-ready'
243
      : !defined $self->delivered_datetime ? 'patron-is-outside'
244
      :                                      'delivered';
245
}
246
94
=head2 Internal methods
247
=head2 Internal methods
95
248
96
=head3 _type
249
=head3 _type
(-)a/Koha/CurbsidePickupIssue.pm (-10 / +10 lines)
Lines 2-19 package Koha::CurbsidePickupIssue; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
(-)a/Koha/CurbsidePickupIssues.pm (-11 / +15 lines)
Lines 2-19 package Koha::CurbsidePickupIssues; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
Lines 35-41 Koha::CurbsidePickupIssues - Koha Curbside Pickup Issues Object set class Link Here
35
35
36
=cut
36
=cut
37
37
38
=head3 type
38
=head3 _type
39
39
40
=cut
40
=cut
41
41
Lines 43-48 sub _type { Link Here
43
    return 'CurbsidePickupIssue';
43
    return 'CurbsidePickupIssue';
44
}
44
}
45
45
46
=head3 object_class
47
48
=cut
49
46
sub object_class {
50
sub object_class {
47
    return 'Koha::CurbsidePickupIssue';
51
    return 'Koha::CurbsidePickupIssue';
48
}
52
}
(-)a/Koha/CurbsidePickupOpeningSlot.pm (-10 / +12 lines)
Lines 2-19 package Koha::CurbsidePickupOpeningSlot; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
Lines 31-36 CurbsidePickupOpeningSlot - Koha Curbside Pickup Slot Object class Link Here
31
31
32
=head2 Class methods
32
=head2 Class methods
33
33
34
=cut
35
34
=head2 Internal methods
36
=head2 Internal methods
35
37
36
=head3 _type
38
=head3 _type
(-)a/Koha/CurbsidePickupOpeningSlots.pm (-11 / +15 lines)
Lines 2-19 package Koha::CurbsidePickupOpeningSlots; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
Lines 35-41 Koha::CurbsidePickupOpeningSlots - Koha Curbside Pickup Opening Slots Object set Link Here
35
35
36
=cut
36
=cut
37
37
38
=head3 type
38
=head3 _type
39
39
40
=cut
40
=cut
41
41
Lines 43-48 sub _type { Link Here
43
    return 'CurbsidePickupOpeningSlot';
43
    return 'CurbsidePickupOpeningSlot';
44
}
44
}
45
45
46
=head3 object_class
47
48
=cut
49
46
sub object_class {
50
sub object_class {
47
    return 'Koha::CurbsidePickupOpeningSlot';
51
    return 'Koha::CurbsidePickupOpeningSlot';
48
}
52
}
(-)a/Koha/CurbsidePickupPolicies.pm (-11 / +15 lines)
Lines 2-19 package Koha::CurbsidePickupPolicies; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
Lines 35-41 Koha::CurbsidePickupPolicies - Koha Curbside Pickup Policies Object set class Link Here
35
35
36
=cut
36
=cut
37
37
38
=head3 type
38
=head3 _type
39
39
40
=cut
40
=cut
41
41
Lines 43-48 sub _type { Link Here
43
    return 'CurbsidePickupPolicy';
43
    return 'CurbsidePickupPolicy';
44
}
44
}
45
45
46
=head3 object_class
47
48
=cut
49
46
sub object_class {
50
sub object_class {
47
    return 'Koha::CurbsidePickupPolicy';
51
    return 'Koha::CurbsidePickupPolicy';
48
}
52
}
(-)a/Koha/CurbsidePickupPolicy.pm (-12 / +61 lines)
Lines 2-28 package Koha::CurbsidePickupPolicy; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Carp;
21
22
use Koha::Database;
20
use Koha::Database;
23
use Koha::Library;
21
use Koha::Library;
24
use Koha::CurbsidePickupOpeningSlots;
22
use Koha::CurbsidePickupOpeningSlots;
25
23
24
use Koha::Result::Boolean;
25
use Koha::Exceptions::CurbsidePickup;
26
26
use base qw(Koha::Object);
27
use base qw(Koha::Object);
27
28
28
=head1 NAME
29
=head1 NAME
Lines 72-77 sub add_opening_slot { Link Here
72
    )->store;
73
    )->store;
73
}
74
}
74
75
76
=head3 is_valid_pickup_datetime
77
78
=cut
79
80
sub is_valid_pickup_datetime {
81
    my ( $self, $datetime ) = @_;
82
83
    my $opening_slots =
84
      $self->opening_slots->search( { day => $datetime->dow % 7 } );
85
    my $matching_slot;
86
    while ( my $opening_slot = $opening_slots->next ) {
87
        my $start = $datetime->clone->set_hour( $opening_slot->start_hour )
88
          ->set_minute( $opening_slot->start_minute );
89
        my $end = $datetime->clone->set_hour( $opening_slot->end_hour )
90
          ->set_minute( $opening_slot->start_minute );
91
        my $keep_going = 1;
92
        my $slot_start = $start->clone;
93
        my $slot_end = $slot_start->clone->add(minutes => $self->pickup_interval);
94
        while ($slot_end <= $end) {
95
            if ( $slot_start == $datetime ) {
96
                $matching_slot = $slot_start;
97
                last;
98
            }
99
            $slot_start->add( minutes => $self->pickup_interval);
100
            $slot_end->add( minutes => $self->pickup_interval);
101
        }
102
    }
103
104
    return Koha::Result::Boolean->new(0)
105
      ->add_message( { message => 'no_matching_slots' } )
106
      unless $matching_slot;
107
108
    my $dtf  = Koha::Database->new->schema->storage->datetime_parser;
109
    # Check too many users for this slot
110
    my $existing_pickups = Koha::CurbsidePickups->search(
111
        {
112
            branchcode                => $self->branchcode,
113
            scheduled_pickup_datetime => $dtf->format_datetime($matching_slot),
114
        }
115
    );
116
117
    return Koha::Result::Boolean->new(0)
118
      ->add_message( { message => 'no_more_available' } )
119
      if $existing_pickups->count >= $self->patrons_per_interval;
120
121
    return 1;
122
}
123
75
=head2 Internal methods
124
=head2 Internal methods
76
125
77
=head3 _type
126
=head3 _type
(-)a/Koha/CurbsidePickups.pm (-11 / +66 lines)
Lines 2-19 package Koha::CurbsidePickups; Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
5
# Koha is free software; you can redistribute it and/or modify it
6
# terms of the GNU General Public License as published by the Free Software
6
# under the terms of the GNU General Public License as published by
7
# Foundation; either version 3 of the License, or (at your option) any later
7
# the Free Software Foundation; either version 3 of the License, or
8
# version.
8
# (at your option) any later version.
9
#
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
10
# Koha is distributed in the hope that it will be useful, but
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
13
#
14
#
14
# You should have received a copy of the GNU General Public License along
15
# You should have received a copy of the GNU General Public License
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
Lines 35-41 Koha::CurbsidePickups - Koha Curbside Pickup Object set class Link Here
35
35
36
=cut
36
=cut
37
37
38
=head3 type
38
=head3 filter_by_to_be_staged
39
40
Filter by pickups that have not been staged yet
41
42
=cut
43
44
sub filter_by_to_be_staged {
45
    my ($self) = @_;
46
    return $self->search( { staged_datetime => undef } );
47
}
48
49
=head3 filter_by_staged_and_ready
50
51
Filter by pickups that have been staged and are ready
52
53
=cut
54
55
sub filter_by_staged_and_ready {
56
    my ($self) = @_;
57
    return $self->search(
58
        { staged_datetime => { -not => undef }, arrival_datetime => undef } );
59
}
60
61
=head3 filter_by_patron_outside
62
63
Filter by pickups with patrons waiting outside
64
65
=cut
66
67
sub filter_by_patron_outside {
68
    my ($self) = @_;
69
    return $self->search(
70
        { arrival_datetime => { -not => undef }, delivered_datetime => undef }
71
    );
72
}
73
74
=head3 filter_by_delivered
75
76
Filter by pickups that have been delivered already
77
78
=cut
79
80
sub filter_by_delivered {
81
    my ($self) = @_;
82
    return $self->search( { delivered_datetime => { -not => undef } } );
83
}
84
85
=head2 Internal Methods
86
87
=cut
88
89
=head3 _type
39
90
40
=cut
91
=cut
41
92
Lines 43-48 sub _type { Link Here
43
    return 'CurbsidePickup';
94
    return 'CurbsidePickup';
44
}
95
}
45
96
97
=head3 object_class
98
99
=cut
100
46
sub object_class {
101
sub object_class {
47
    return 'Koha::CurbsidePickup';
102
    return 'Koha::CurbsidePickup';
48
}
103
}
(-)a/Koha/Exceptions/CurbsidePickup.pm (+46 lines)
Line 0 Link Here
1
package Koha::Exceptions::CurbsidePickup;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Koha::Exception;
21
22
use Exception::Class (
23
24
    'Koha::Exceptions::CurbsidePickup' => {
25
        isa => 'Koha::Exception',
26
    },
27
    'Koha::Exceptions::CurbsidePickup::NotEnabled' => {
28
        isa         => 'Koha::Exceptions::CurbsidePickup',
29
        description => 'Curbside pickups are not enable for this library',
30
    },
31
    'Koha::Exceptions::CurbsidePickup::TooManyPickups' => {
32
        isa         => 'Koha::Exceptions::CurbsidePickup',
33
        description => 'Patron already has a scheduled pickup for this library',
34
        fields      => [ 'branchcode', 'borrowernumber' ],
35
    },
36
    'Koha::Exceptions::CurbsidePickup::NoMatchingSlots' => {
37
        isa         => 'Koha::Exceptions::CurbsidePickup',
38
        description => 'Cannot create a pickup with this pickup datetime',
39
    },
40
    'Koha::Exceptions::CurbsidePickup::NoMorePickupsAvailable' => {
41
        isa         => 'Koha::Exceptions::CurbsidePickup',
42
        description => 'No more pickups available for this slot',
43
    },
44
);
45
46
1;
(-)a/t/db_dependent/Koha/CurbsidePickups.t (-1 / +236 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 3;
21
use Test::Exception;
22
23
use Koha::City;
24
use Koha::CurbsidePickups;
25
use Koha::CurbsidePickupPolicies;
26
use Koha::Database;
27
use Koha::DateUtils qw( dt_from_string );
28
29
use t::lib::TestBuilder;
30
use t::lib::Dates;
31
use t::lib::Mocks;
32
33
my $schema = Koha::Database->new->schema;
34
$schema->storage->txn_begin;
35
36
my $builder          = t::lib::TestBuilder->new;
37
my $library          = $builder->build_object( { class => 'Koha::Libraries' } );
38
my $library_disabled = $builder->build_object( { class => 'Koha::Libraries' } );
39
my $logged_in_patron = $builder->build_object(
40
    {
41
        class => 'Koha::Patrons',
42
        value => { branchcode => $library->branchcode }
43
    }
44
);
45
t::lib::Mocks::mock_userenv( { patron => $logged_in_patron } );
46
my $patron = $builder->build_object(
47
    {
48
        class => 'Koha::Patrons',
49
        value => { branchcode => $library->branchcode }
50
    }
51
);
52
53
my $policy = Koha::CurbsidePickupPolicy->new(
54
    {
55
        branchcode              => $library->branchcode,
56
        enabled                 => 1,
57
        pickup_interval         => 30,
58
        patrons_per_interval    => 2,
59
        patron_scheduled_pickup => 1
60
    }
61
)->store;
62
my $policy_disabled = Koha::CurbsidePickupPolicy->new(
63
    {
64
        branchcode              => $library_disabled->branchcode,
65
        enabled                 => 0,
66
        pickup_interval         => 30,
67
        patrons_per_interval    => 2,
68
        patron_scheduled_pickup => 1
69
    }
70
)->store;
71
72
# Open Mondays from 12 to 18
73
$policy->add_opening_slot('1-12:00-18:00');
74
75
my $today = dt_from_string;
76
77
subtest 'Create a pickup' => sub {
78
    plan tests => 5;
79
80
    # Day and datetime are ok
81
    my $next_monday =
82
      $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
83
    my $schedule_dt =
84
      $next_monday->set_hour(15)->set_minute(00)->set_second(00);
85
    my $cp = Koha::CurbsidePickup->new(
86
        {
87
            branchcode                => $library->branchcode,
88
            borrowernumber            => $patron->borrowernumber,
89
            scheduled_pickup_datetime => $schedule_dt,
90
            notes                     => 'just a note'
91
        }
92
    )->store;
93
    is( $cp->status, 'to-be-staged' );
94
95
    throws_ok {
96
        Koha::CurbsidePickup->new(
97
            {
98
                branchcode                => $library->branchcode,
99
                borrowernumber            => $patron->borrowernumber,
100
                scheduled_pickup_datetime => $schedule_dt,
101
                notes                     => 'just a note'
102
            }
103
          )->store
104
    }
105
    'Koha::Exceptions::CurbsidePickup::TooManyPickups',
106
      'Cannot create 2 pickups for the same patron';
107
108
    $cp->delete;
109
110
    # Day is not ok
111
    my $next_tuesday =
112
      $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
113
    $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
114
    throws_ok {
115
        Koha::CurbsidePickup->new(
116
            {
117
                branchcode                => $library->branchcode,
118
                borrowernumber            => $patron->borrowernumber,
119
                scheduled_pickup_datetime => $schedule_dt,
120
                notes                     => 'just a note'
121
            }
122
          )->store
123
    }
124
    'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
125
      'Cannot create a pickup on a day without opening slots defined';
126
127
    # Day ok but datetime not ok
128
    $schedule_dt = $next_monday->set_hour(19)->set_minute(00)->set_second(00);
129
    throws_ok {
130
        Koha::CurbsidePickup->new(
131
            {
132
                branchcode                => $library->branchcode,
133
                borrowernumber            => $patron->borrowernumber,
134
                scheduled_pickup_datetime => $schedule_dt,
135
                notes                     => 'just a note'
136
            }
137
          )->store
138
    }
139
    'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
140
      'Cannot create a pickup on a time without opening slots defined';
141
142
    # Day ok, datetime inside the opening slot, but wrong (15:15 for instance)
143
    $schedule_dt = $next_monday->set_hour(15)->set_minute(15)->set_second(00);
144
    throws_ok {
145
        Koha::CurbsidePickup->new(
146
            {
147
                branchcode                => $library->branchcode,
148
                borrowernumber            => $patron->borrowernumber,
149
                scheduled_pickup_datetime => $schedule_dt,
150
                notes                     => 'just a note'
151
            }
152
          )->store
153
    }
154
    'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
155
'Cannot create a pickup on a time that is not matching the start of an interval';
156
157
};
158
159
subtest 'workflow' => sub {
160
    plan tests => 9;
161
162
    my $pickups =
163
      Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
164
165
    my $next_monday =
166
      $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
167
    my $schedule_dt =
168
      $next_monday->set_hour(15)->set_minute(00)->set_second(00);
169
    my $cp = Koha::CurbsidePickup->new(
170
        {
171
            branchcode                => $library->branchcode,
172
            borrowernumber            => $patron->borrowernumber,
173
            scheduled_pickup_datetime => $schedule_dt,
174
            notes                     => 'just a note'
175
        }
176
    )->store;
177
    is( $cp->status, 'to-be-staged' );
178
    is( $pickups->filter_by_to_be_staged->count, 1 );
179
180
    $cp->mark_as_staged;
181
    is( $cp->status, 'staged-and-ready' );
182
    is( $pickups->filter_by_staged_and_ready->count, 1 );
183
184
    $cp->mark_as_unstaged;
185
    is( $cp->status, 'to-be-staged' );
186
187
    $cp->mark_as_staged;
188
189
    $cp->mark_patron_has_arrived;
190
    is( $cp->status, 'patron-is-outside' );
191
    is( $pickups->filter_by_patron_outside->count, 1 );
192
193
    $cp->mark_as_delivered;
194
    is( $cp->status, 'delivered' );
195
    is( $pickups->filter_by_delivered->count, 1 );
196
};
197
198
subtest 'mark_as_delivered' => sub {
199
    plan tests => 3;
200
201
    my $item = $builder->build_sample_item({ library => $library->branchcode });
202
    my $reserve_id = C4::Reserves::AddReserve(
203
        {
204
            branchcode     => $library->branchcode,
205
            borrowernumber => $patron->borrowernumber,
206
            biblionumber   => $item->biblionumber,
207
            priority       => 1,
208
            itemnumber     => $item->itemnumber,
209
        }
210
    );
211
    my $hold = Koha::Holds->find($reserve_id);
212
    $hold->set_waiting;
213
214
    my $next_monday =
215
      $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
216
    my $schedule_dt =
217
      $next_monday->set_hour(15)->set_minute(00)->set_second(00);
218
    my $cp = Koha::CurbsidePickup->new(
219
        {
220
            branchcode                => $library->branchcode,
221
            borrowernumber            => $patron->borrowernumber,
222
            scheduled_pickup_datetime => $schedule_dt,
223
            notes                     => 'just a note'
224
        }
225
    )->store;
226
227
    $cp->mark_as_delivered;
228
    $cp->discard_changes;
229
    is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
230
231
    is( $hold->get_from_storage, undef, 'Hold has been filled' );
232
    my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
233
    is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' )
234
};
235
236
$schema->storage->txn_rollback;

Return to bug 30650