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 );
187 is( $pickups->filter_by_scheduled_today->count, 1 );
188 $cp->scheduled_pickup_datetime($today->clone->subtract(days => 1))->store;
189 is( $pickups->filter_by_scheduled_today->count, 0 );
194 subtest 'mark_as_delivered' => sub {
197 my $item = $builder->build_sample_item({ library => $library->branchcode });
198 my $reserve_id = C4::Reserves::AddReserve(
200 branchcode => $library->branchcode,
201 borrowernumber => $patron->borrowernumber,
202 biblionumber => $item->biblionumber,
204 itemnumber => $item->itemnumber,
207 my $hold = Koha::Holds->find($reserve_id);
211 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
213 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
214 my $cp = Koha::CurbsidePickup->new(
216 branchcode => $library->branchcode,
217 borrowernumber => $patron->borrowernumber,
218 scheduled_pickup_datetime => $schedule_dt,
219 notes => 'just a note'
223 $cp->mark_as_delivered;
224 $cp->discard_changes;
225 is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
227 is( $hold->get_from_storage, undef, 'Hold has been filled' );
228 my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
229 is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
234 subtest 'notify_new_pickup' => sub {
238 $builder->build_sample_item( { library => $library->branchcode } );
239 my $reserve_id = C4::Reserves::AddReserve(
241 branchcode => $library->branchcode,
242 borrowernumber => $patron->borrowernumber,
243 biblionumber => $item->biblionumber,
245 itemnumber => $item->itemnumber,
248 my $hold = Koha::Holds->find($reserve_id);
252 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
254 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
255 my $cp = Koha::CurbsidePickup->new(
257 branchcode => $library->branchcode,
258 borrowernumber => $patron->borrowernumber,
259 scheduled_pickup_datetime => $schedule_dt,
260 notes => 'just a note'
264 $patron->set( { email => 'test@example.org' } )->store;
265 my $dbh = C4::Context->dbh;
266 $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
267 undef, $patron->borrowernumber, 4
269 my $borrower_message_preference_id =
270 $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
272 q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
273 undef, $borrower_message_preference_id, 'email'
276 $cp->notify_new_pickup;
278 my $messages = C4::Letters::GetQueuedMessages(
279 { borrowernumber => $patron->borrowernumber } );
281 $messages->[0]->{subject},
282 sprintf ("You have schedule a curbside pickup for %s.", $library->branchname),
283 "Notice correctly generated"
285 my $biblio_title = $item->biblio->title;
286 like( $messages->[0]->{content},
287 qr{$biblio_title}, "Content contains the list of waiting holds" );
290 $schema->storage->txn_rollback;