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;
27 use Koha::DateUtils qw( dt_from_string );
29 use t::lib::TestBuilder;
33 my $schema = Koha::Database->new->schema;
34 $schema->storage->txn_begin;
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(
41 class => 'Koha::Patrons',
42 value => { branchcode => $library->branchcode }
45 t::lib::Mocks::mock_userenv( { patron => $logged_in_patron } );
46 my $patron = $builder->build_object(
48 class => 'Koha::Patrons',
49 value => { branchcode => $library->branchcode }
53 my $policy = Koha::CurbsidePickupPolicy->new(
55 branchcode => $library->branchcode,
57 enable_waiting_holds_only => 0,
58 pickup_interval => 30,
59 patrons_per_interval => 2,
60 patron_scheduled_pickup => 1
63 my $policy_disabled = Koha::CurbsidePickupPolicy->new(
65 branchcode => $library_disabled->branchcode,
67 enable_waiting_holds_only => 0,
68 pickup_interval => 30,
69 patrons_per_interval => 2,
70 patron_scheduled_pickup => 1
74 # Open Mondays from 12 to 18
75 $policy->add_opening_slot('1-12:00-18:00');
77 my $today = dt_from_string;
79 subtest 'Create a pickup' => sub {
82 # Day and datetime are ok
84 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
86 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
89 branchcode => $library->branchcode,
90 borrowernumber => $patron->borrowernumber,
91 scheduled_pickup_datetime => $schedule_dt,
92 notes => 'just a note'
96 Koha::CurbsidePickup->new({%$params, branchcode => $library_disabled->branchcode})->store;
98 'Koha::Exceptions::CurbsidePickup::NotEnabled',
99 'Cannot create pickup if the policy does not allow it';
101 $policy->enable_waiting_holds_only(1)->store;
103 Koha::CurbsidePickup->new($params)->store;
105 'Koha::Exceptions::CurbsidePickup::NoWaitingHolds',
106 'Cannot create pickup for a patron without waiting hold if flag is set';
108 $policy->enable_waiting_holds_only(0)->store;
109 my $cp = Koha::CurbsidePickup->new($params)->store;
110 is( $cp->status, 'to-be-staged' );
111 is( $patron->curbside_pickups->count, 1, 'Koha::Patron->curbside_pickups' );
114 Koha::CurbsidePickup->new($params)->store
116 'Koha::Exceptions::CurbsidePickup::TooManyPickups',
117 'Cannot create 2 pickups for the same patron';
123 $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
124 $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
126 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
128 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
129 'Cannot create a pickup on a day without opening slots defined';
131 # Day ok but datetime not ok
132 $schedule_dt = $next_monday->set_hour(19)->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 time without opening slots defined';
139 # Day ok, datetime inside the opening slot, but wrong (15:15 for instance)
140 $schedule_dt = $next_monday->set_hour(15)->set_minute(15)->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 that is not matching the start of an interval';
149 subtest 'workflow' => sub {
153 Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
156 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
158 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
159 my $cp = Koha::CurbsidePickup->new(
161 branchcode => $library->branchcode,
162 borrowernumber => $patron->borrowernumber,
163 scheduled_pickup_datetime => $schedule_dt,
164 notes => 'just a note'
167 is( $cp->status, 'to-be-staged' );
168 is( $pickups->filter_by_to_be_staged->count, 1 );
171 is( $cp->status, 'staged-and-ready' );
172 is( $pickups->filter_by_staged_and_ready->count, 1 );
174 $cp->mark_as_unstaged;
175 is( $cp->status, 'to-be-staged' );
179 $cp->mark_patron_has_arrived;
180 is( $cp->status, 'patron-is-outside' );
181 is( $pickups->filter_by_patron_outside->count, 1 );
183 $cp->mark_as_delivered;
184 is( $cp->status, 'delivered' );
185 is( $pickups->filter_by_delivered->count, 1 );
190 subtest 'mark_as_delivered' => sub {
193 my $item = $builder->build_sample_item({ library => $library->branchcode });
194 my $reserve_id = C4::Reserves::AddReserve(
196 branchcode => $library->branchcode,
197 borrowernumber => $patron->borrowernumber,
198 biblionumber => $item->biblionumber,
200 itemnumber => $item->itemnumber,
203 my $hold = Koha::Holds->find($reserve_id);
207 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
209 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
210 my $cp = Koha::CurbsidePickup->new(
212 branchcode => $library->branchcode,
213 borrowernumber => $patron->borrowernumber,
214 scheduled_pickup_datetime => $schedule_dt,
215 notes => 'just a note'
219 $cp->mark_as_delivered;
220 $cp->discard_changes;
221 is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
223 is( $hold->get_from_storage, undef, 'Hold has been filled' );
224 my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
225 is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
230 subtest 'notify_new_pickup' => sub {
234 $builder->build_sample_item( { library => $library->branchcode } );
235 my $reserve_id = C4::Reserves::AddReserve(
237 branchcode => $library->branchcode,
238 borrowernumber => $patron->borrowernumber,
239 biblionumber => $item->biblionumber,
241 itemnumber => $item->itemnumber,
244 my $hold = Koha::Holds->find($reserve_id);
248 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
250 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
251 my $cp = Koha::CurbsidePickup->new(
253 branchcode => $library->branchcode,
254 borrowernumber => $patron->borrowernumber,
255 scheduled_pickup_datetime => $schedule_dt,
256 notes => 'just a note'
260 $patron->set( { email => 'test@example.org' } )->store;
261 my $dbh = C4::Context->dbh;
262 $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
263 undef, $patron->borrowernumber, 4
265 my $borrower_message_preference_id =
266 $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
268 q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
269 undef, $borrower_message_preference_id, 'email'
272 $cp->notify_new_pickup;
274 my $messages = C4::Letters::GetQueuedMessages(
275 { borrowernumber => $patron->borrowernumber } );
277 $messages->[0]->{subject},
278 sprintf ("You have schedule a curbside pickup for %s.", $library->branchname),
279 "Notice correctly generated"
281 my $biblio_title = $item->biblio->title;
282 like( $messages->[0]->{content},
283 qr{$biblio_title}, "Content contains the list of waiting holds" );
286 $schema->storage->txn_rollback;