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' );
113 Koha::CurbsidePickup->new($params)->store
115 'Koha::Exceptions::CurbsidePickup::TooManyPickups',
116 'Cannot create 2 pickups for the same patron';
122 $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
123 $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
125 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
127 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
128 'Cannot create a pickup on a day without opening slots defined';
130 # Day ok but datetime not ok
131 $schedule_dt = $next_monday->set_hour(19)->set_minute(00)->set_second(00);
133 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
135 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
136 'Cannot create a pickup on a time without opening slots defined';
138 # Day ok, datetime inside the opening slot, but wrong (15:15 for instance)
139 $schedule_dt = $next_monday->set_hour(15)->set_minute(15)->set_second(00);
141 Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
143 'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
144 'Cannot create a pickup on a time that is not matching the start of an interval';
148 subtest 'workflow' => sub {
152 Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
155 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
157 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
158 my $cp = Koha::CurbsidePickup->new(
160 branchcode => $library->branchcode,
161 borrowernumber => $patron->borrowernumber,
162 scheduled_pickup_datetime => $schedule_dt,
163 notes => 'just a note'
166 is( $cp->status, 'to-be-staged' );
167 is( $pickups->filter_by_to_be_staged->count, 1 );
170 is( $cp->status, 'staged-and-ready' );
171 is( $pickups->filter_by_staged_and_ready->count, 1 );
173 $cp->mark_as_unstaged;
174 is( $cp->status, 'to-be-staged' );
178 $cp->mark_patron_has_arrived;
179 is( $cp->status, 'patron-is-outside' );
180 is( $pickups->filter_by_patron_outside->count, 1 );
182 $cp->mark_as_delivered;
183 is( $cp->status, 'delivered' );
184 is( $pickups->filter_by_delivered->count, 1 );
189 subtest 'mark_as_delivered' => sub {
192 my $item = $builder->build_sample_item({ library => $library->branchcode });
193 my $reserve_id = C4::Reserves::AddReserve(
195 branchcode => $library->branchcode,
196 borrowernumber => $patron->borrowernumber,
197 biblionumber => $item->biblionumber,
199 itemnumber => $item->itemnumber,
202 my $hold = Koha::Holds->find($reserve_id);
206 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
208 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
209 my $cp = Koha::CurbsidePickup->new(
211 branchcode => $library->branchcode,
212 borrowernumber => $patron->borrowernumber,
213 scheduled_pickup_datetime => $schedule_dt,
214 notes => 'just a note'
218 $cp->mark_as_delivered;
219 $cp->discard_changes;
220 is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
222 is( $hold->get_from_storage, undef, 'Hold has been filled' );
223 my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
224 is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
229 subtest 'notify_new_pickup' => sub {
233 $builder->build_sample_item( { library => $library->branchcode } );
234 my $reserve_id = C4::Reserves::AddReserve(
236 branchcode => $library->branchcode,
237 borrowernumber => $patron->borrowernumber,
238 biblionumber => $item->biblionumber,
240 itemnumber => $item->itemnumber,
243 my $hold = Koha::Holds->find($reserve_id);
247 $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
249 $next_monday->set_hour(15)->set_minute(00)->set_second(00);
250 my $cp = Koha::CurbsidePickup->new(
252 branchcode => $library->branchcode,
253 borrowernumber => $patron->borrowernumber,
254 scheduled_pickup_datetime => $schedule_dt,
255 notes => 'just a note'
259 $patron->set( { email => 'test@example.org' } )->store;
260 my $dbh = C4::Context->dbh;
261 $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
262 undef, $patron->borrowernumber, 4
264 my $borrower_message_preference_id =
265 $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
267 q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
268 undef, $borrower_message_preference_id, 'email'
271 $cp->notify_new_pickup;
273 my $messages = C4::Letters::GetQueuedMessages(
274 { borrowernumber => $patron->borrowernumber } );
276 $messages->[0]->{subject},
277 sprintf ("You have schedule a curbside pickup for %s.", $library->branchname),
278 "Notice correctly generated"
280 my $biblio_title = $item->biblio->title;
281 like( $messages->[0]->{content},
282 qr{$biblio_title}, "Content contains the list of waiting holds" );
285 $schema->storage->txn_rollback;