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 => 30,
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:00');
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->enable_waiting_holds_only(1)->store;
104 Koha::CurbsidePickup->new($params)->store;
106 'Koha::Exceptions::CurbsidePickup::NoWaitingHolds',
107 'Cannot create pickup for a patron without waiting hold if flag is set';
109 $policy->enable_waiting_holds_only(0)->store;
110 my $cp = Koha::CurbsidePickup->new($params)->store;
111 is( $cp->status, 'to-be-staged' );
112 is( $patron->curbside_pickups->count, 1, 'Koha::Patron->curbside_pickups' );
115 Koha::CurbsidePickup->new($params)->store
117 'Koha::Exceptions::CurbsidePickup::TooManyPickups',
118 'Cannot create 2 pickups for the same patron';
124 $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
125 $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
127 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
129 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
130 'Cannot create a pickup on a day without opening slots defined';
132 # Day ok but datetime not ok
133 $schedule_dt = $next_monday->set_hour(19)->set_minute(00)->set_second(00);
135 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
137 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
138 'Cannot create a pickup on a time without opening slots defined';
140 # Day ok, datetime inside the opening slot, but wrong (15:15 for instance)
141 $schedule_dt = $next_monday->set_hour(15)->set_minute(15)->set_second(00);
143 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
145 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
146 'Cannot create a pickup on a time that is not matching the start of an interval';
149 Koha::Caches->get_instance->flush_all;
150 C4::Calendar->new( branchcode => $library->branchcode )->insert_week_day_holiday(
153 description => 'Mondays',
155 my $calendar = Koha::Calendar->new( branchcode => $library->branchcode );
157 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
159 'Koha::Exceptions::CurbsidePickup::LibraryIsClosed',
160 'Cannot create a pickup on a holiday';
162 C4::Context->dbh->do(q{DELETE FROM repeatable_holidays});
163 Koha::Caches->get_instance->flush_all;
166 subtest 'workflow' => sub {
170 Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
173 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
175 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
176 my $cp = Koha::CurbsidePickup->new(
178 branchcode => $library->branchcode,
179 borrowernumber => $patron->borrowernumber,
180 scheduled_pickup_datetime => $schedule_dt,
181 notes => 'just a note'
184 is( $cp->status, 'to-be-staged' );
185 is( $pickups->filter_by_to_be_staged->count, 1 );
188 is( $cp->status, 'staged-and-ready' );
189 is( $pickups->filter_by_staged_and_ready->count, 1 );
191 $cp->mark_as_unstaged;
192 is( $cp->status, 'to-be-staged' );
196 $cp->mark_patron_has_arrived;
197 is( $cp->status, 'patron-is-outside' );
198 is( $pickups->filter_by_patron_outside->count, 1 );
200 $cp->mark_as_delivered;
201 is( $cp->status, 'delivered' );
202 is( $pickups->filter_by_delivered->count, 1 );
204 is( $pickups->filter_by_scheduled_today->count, 1 );
205 $cp->scheduled_pickup_datetime($today->clone->subtract(days => 1))->store;
206 is( $pickups->filter_by_scheduled_today->count, 0 );
211 subtest 'mark_as_delivered' => sub {
214 my $item = $builder->build_sample_item({ library => $library->branchcode });
215 my $reserve_id = C4::Reserves::AddReserve(
217 branchcode => $library->branchcode,
218 borrowernumber => $patron->borrowernumber,
219 biblionumber => $item->biblionumber,
221 itemnumber => $item->itemnumber,
224 my $hold = Koha::Holds->find($reserve_id);
228 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
230 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
231 my $cp = Koha::CurbsidePickup->new(
233 branchcode => $library->branchcode,
234 borrowernumber => $patron->borrowernumber,
235 scheduled_pickup_datetime => $schedule_dt,
236 notes => 'just a note'
240 $cp->mark_as_delivered;
241 $cp->discard_changes;
242 is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
244 is( $hold->get_from_storage, undef, 'Hold has been filled' );
245 my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
246 is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
251 subtest 'notify_new_pickup' => sub {
255 $builder->build_sample_item( { library => $library->branchcode } );
256 my $reserve_id = C4::Reserves::AddReserve(
258 branchcode => $library->branchcode,
259 borrowernumber => $patron->borrowernumber,
260 biblionumber => $item->biblionumber,
262 itemnumber => $item->itemnumber,
265 my $hold = Koha::Holds->find($reserve_id);
269 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
271 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
272 my $cp = Koha::CurbsidePickup->new(
274 branchcode => $library->branchcode,
275 borrowernumber => $patron->borrowernumber,
276 scheduled_pickup_datetime => $schedule_dt,
277 notes => 'just a note'
281 $patron->set( { email => 'test@example.org' } )->store;
282 my $dbh = C4::Context->dbh;
283 $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
284 undef, $patron->borrowernumber, 4
286 my $borrower_message_preference_id =
287 $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
289 q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
290 undef, $borrower_message_preference_id, 'email'
293 $cp->notify_new_pickup;
295 my $messages = C4::Letters::GetQueuedMessages(
296 { borrowernumber => $patron->borrowernumber } );
298 $messages->[0]->{subject},
299 sprintf ("You have scheduled a curbside pickup for %s", $library->branchname),
300 "Notice correctly generated"
302 my $biblio_title = $item->biblio->title;
303 like( $messages->[0]->{content},
304 qr{$biblio_title}, "Content contains the list of waiting holds" );
307 $schema->storage->txn_rollback;