3 # This file is part of Koha
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.
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.
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>.
20 use Test::More tests => 4;
24 use Koha::CurbsidePickups;
25 use Koha::CurbsidePickupPolicies;
28 use Koha::DateUtils qw( dt_from_string );
30 use t::lib::TestBuilder;
34 my $schema = Koha::Database->new->schema;
35 $schema->storage->txn_begin;
37 my $builder = t::lib::TestBuilder->new;
38 my $library = $builder->build_object( { class => 'Koha::Libraries' } );
39 my $library_disabled = $builder->build_object( { class => 'Koha::Libraries' } );
40 my $logged_in_patron = $builder->build_object(
42 class => 'Koha::Patrons',
43 value => { branchcode => $library->branchcode }
46 t::lib::Mocks::mock_userenv( { patron => $logged_in_patron } );
47 my $patron = $builder->build_object(
49 class => 'Koha::Patrons',
50 value => { branchcode => $library->branchcode }
54 my $policy = Koha::CurbsidePickupPolicy->new(
56 branchcode => $library->branchcode,
58 enable_waiting_holds_only => 0,
59 pickup_interval => 15,
60 patrons_per_interval => 2,
61 patron_scheduled_pickup => 1
64 my $policy_disabled = Koha::CurbsidePickupPolicy->new(
66 branchcode => $library_disabled->branchcode,
68 enable_waiting_holds_only => 0,
69 pickup_interval => 30,
70 patrons_per_interval => 2,
71 patron_scheduled_pickup => 1
75 # Open Mondays from 12 to 18
76 $policy->add_opening_slot('1-12:00-18:45');
78 my $today = dt_from_string;
80 subtest 'Create a pickup' => sub {
83 # Day and datetime are ok
85 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
87 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
90 branchcode => $library->branchcode,
91 borrowernumber => $patron->borrowernumber,
92 scheduled_pickup_datetime => $schedule_dt,
93 notes => 'just a note'
97 Koha::CurbsidePickup->new({%$params, branchcode => $library_disabled->branchcode})->store;
99 'Koha::Exceptions::CurbsidePickup::NotEnabled',
100 'Cannot create pickup if the policy does not allow it';
102 $policy->enabled(1)->store;
104 $policy->enable_waiting_holds_only(1)->store;
106 Koha::CurbsidePickup->new($params)->store;
108 'Koha::Exceptions::CurbsidePickup::NoWaitingHolds',
109 'Cannot create pickup for a patron without waiting hold if flag is set';
111 $policy->enable_waiting_holds_only(0)->store;
112 my $cp = Koha::CurbsidePickup->new($params)->store;
113 is( $cp->status, 'to-be-staged' );
114 is( $patron->curbside_pickups->count, 1, 'Koha::Patron->curbside_pickups' );
117 Koha::CurbsidePickup->new($params)->store
119 'Koha::Exceptions::CurbsidePickup::TooManyPickups',
120 'Cannot create 2 pickups for the same patron';
124 $schedule_dt = $next_monday->set_hour(18)->set_minute(15)->set_second(00);
125 $cp = Koha::CurbsidePickup->new( { %$params, scheduled_pickup_datetime => $schedule_dt } )->store;
131 $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
132 $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
134 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
136 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
137 'Cannot create a pickup on a day without opening slots defined';
139 # Day ok but datetime not ok
140 $schedule_dt = $next_monday->set_hour(19)->set_minute(00)->set_second(00);
142 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
144 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
145 'Cannot create a pickup on a time without opening slots defined';
147 # Day ok, datetime inside the opening slot, but wrong (15:07 for instance)
148 $schedule_dt = $next_monday->set_hour(15)->set_minute(7)->set_second(0);
150 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
152 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
153 'Cannot create a pickup on a time that is not matching the start of an interval';
156 Koha::Caches->get_instance->flush_all;
157 C4::Calendar->new( branchcode => $library->branchcode )->insert_week_day_holiday(
160 description => 'Mondays',
162 my $calendar = Koha::Calendar->new( branchcode => $library->branchcode );
164 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
166 'Koha::Exceptions::CurbsidePickup::LibraryIsClosed',
167 'Cannot create a pickup on a holiday';
169 C4::Context->dbh->do(q{DELETE FROM repeatable_holidays});
170 Koha::Caches->get_instance->flush_all;
173 subtest 'workflow' => sub {
177 Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
180 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
182 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
183 my $cp = Koha::CurbsidePickup->new(
185 branchcode => $library->branchcode,
186 borrowernumber => $patron->borrowernumber,
187 scheduled_pickup_datetime => $schedule_dt,
188 notes => 'just a note'
191 is( $cp->status, 'to-be-staged' );
192 is( $pickups->filter_by_to_be_staged->count, 1 );
195 is( $cp->status, 'staged-and-ready' );
196 is( $pickups->filter_by_staged_and_ready->count, 1 );
198 $cp->mark_as_unstaged;
199 is( $cp->status, 'to-be-staged' );
203 $cp->mark_patron_has_arrived;
204 is( $cp->status, 'patron-is-outside' );
205 is( $pickups->filter_by_patron_outside->count, 1 );
207 $cp->mark_as_delivered;
208 is( $cp->status, 'delivered' );
209 is( $pickups->filter_by_delivered->count, 1 );
211 is( $pickups->filter_by_scheduled_today->count, 1 );
212 $cp->scheduled_pickup_datetime($today->clone->subtract(days => 1))->store;
213 is( $pickups->filter_by_scheduled_today->count, 0 );
218 subtest 'mark_as_delivered' => sub {
221 my $item = $builder->build_sample_item({ library => $library->branchcode });
222 my $reserve_id = C4::Reserves::AddReserve(
224 branchcode => $library->branchcode,
225 borrowernumber => $patron->borrowernumber,
226 biblionumber => $item->biblionumber,
228 itemnumber => $item->itemnumber,
231 my $hold = Koha::Holds->find($reserve_id);
235 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
237 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
238 my $cp = Koha::CurbsidePickup->new(
240 branchcode => $library->branchcode,
241 borrowernumber => $patron->borrowernumber,
242 scheduled_pickup_datetime => $schedule_dt,
243 notes => 'just a note'
247 $cp->mark_as_delivered;
248 $cp->discard_changes;
249 is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
251 is( $hold->get_from_storage, undef, 'Hold has been filled' );
252 my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
253 is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
258 subtest 'notify_new_pickup' => sub {
262 $builder->build_sample_item( { library => $library->branchcode } );
263 my $reserve_id = C4::Reserves::AddReserve(
265 branchcode => $library->branchcode,
266 borrowernumber => $patron->borrowernumber,
267 biblionumber => $item->biblionumber,
269 itemnumber => $item->itemnumber,
272 my $hold = Koha::Holds->find($reserve_id);
276 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
278 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
279 my $cp = Koha::CurbsidePickup->new(
281 branchcode => $library->branchcode,
282 borrowernumber => $patron->borrowernumber,
283 scheduled_pickup_datetime => $schedule_dt,
284 notes => 'just a note'
288 $patron->set( { email => 'test@example.org' } )->store;
289 my $dbh = C4::Context->dbh;
290 $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
291 undef, $patron->borrowernumber, 4
293 my $borrower_message_preference_id =
294 $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
296 q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
297 undef, $borrower_message_preference_id, 'email'
300 $cp->notify_new_pickup;
302 my $messages = C4::Letters::GetQueuedMessages(
303 { borrowernumber => $patron->borrowernumber } );
305 $messages->[0]->{subject},
306 sprintf ("You have scheduled a curbside pickup for %s", $library->branchname),
307 "Notice correctly generated"
309 my $biblio_title = $item->biblio->title;
310 like( $messages->[0]->{content},
311 qr{$biblio_title}, "Content contains the list of waiting holds" );
314 $schema->storage->txn_rollback;