Bug 18936: Convert issuingrules fields to circulation_rules
[koha.git] / t / db_dependent / Circulation / CalcDateDue.t
blobb154c1fd5ef3420404dc51e43df0ecaed123c25a
1 #!/usr/bin/perl
3 use Modern::Perl;
5 use Test::More tests => 17;
6 use Test::MockModule;
7 use DBI;
8 use DateTime;
9 use t::lib::Mocks;
10 use t::lib::TestBuilder;
11 use C4::Calendar;
13 use Koha::CirculationRules;
15 use_ok('C4::Circulation');
17 my $schema = Koha::Database->new->schema;
18 $schema->storage->txn_begin;
19 my $builder = t::lib::TestBuilder->new;
21 my $categorycode = 'B';
22 my $itemtype = 'MX';
23 my $branchcode = 'FPL';
24 my $issuelength = 10;
25 my $renewalperiod = 5;
26 my $lengthunit = 'days';
28 Koha::CirculationRules->search()->delete();
29 Koha::CirculationRules->set_rules(
31 categorycode => $categorycode,
32 itemtype => $itemtype,
33 branchcode => $branchcode,
34 rules => {
35 issuelength => $issuelength,
36 renewalperiod => $renewalperiod,
37 lengthunit => $lengthunit,
42 #Set syspref ReturnBeforeExpiry = 1 and useDaysMode = 'Days'
43 t::lib::Mocks::mock_preference('ReturnBeforeExpiry', 1);
44 t::lib::Mocks::mock_preference('useDaysMode', 'Days');
46 my $cache = Koha::Caches->get_instance();
47 $cache->clear_from_cache('single_holidays');
49 my $dateexpiry = '2013-01-01';
51 my $borrower = {categorycode => 'B', dateexpiry => $dateexpiry};
52 my $start_date = DateTime->new({year => 2013, month => 2, day => 9});
53 my $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
54 is($date, $dateexpiry . 'T23:59:00', 'date expiry');
55 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
58 #Set syspref ReturnBeforeExpiry = 1 and useDaysMode != 'Days'
59 t::lib::Mocks::mock_preference('ReturnBeforeExpiry', 1);
60 t::lib::Mocks::mock_preference('useDaysMode', 'noDays');
62 $borrower = {categorycode => 'B', dateexpiry => $dateexpiry};
63 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
64 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
65 is($date, $dateexpiry . 'T23:59:00', 'date expiry with useDaysMode to noDays');
67 # Let's add a special holiday on 2013-01-01. With ReturnBeforeExpiry and
68 # useDaysMode different from 'Days', return should forward the dateexpiry.
69 my $calendar = C4::Calendar->new(branchcode => $branchcode);
70 $calendar->insert_single_holiday(
71 day => 1,
72 month => 1,
73 year => 2013,
74 title =>'holidayTest',
75 description => 'holidayDesc'
77 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
78 is($date, '2012-12-31T23:59:00', 'date expiry should be 2013-01-01 -1 day');
79 $calendar->insert_single_holiday(
80 day => 31,
81 month => 12,
82 year => 2012,
83 title =>'holidayTest',
84 description => 'holidayDesc'
86 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
87 is($date, '2012-12-30T23:59:00', 'date expiry should be 2013-01-01 -2 day');
90 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
93 #Set syspref ReturnBeforeExpiry = 0 and useDaysMode = 'Days'
94 t::lib::Mocks::mock_preference('ReturnBeforeExpiry', 0);
95 t::lib::Mocks::mock_preference('useDaysMode', 'Days');
97 $borrower = {categorycode => 'B', dateexpiry => $dateexpiry};
98 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
99 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
100 is($date, '2013-02-' . (9 + $issuelength) . 'T23:59:00', "date expiry ( 9 + $issuelength )");
102 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
103 is($date, '2013-02-' . (9 + $renewalperiod) . 'T23:59:00', "date expiry ( 9 + $renewalperiod )");
106 # Now we want to test the Dayweek useDaysMode option
107 # For this we need a loan period that is a mutiple of 7 days
108 # But, since we currently don't have that, let's test it does the
109 # right thing in that case, it should act as though useDaysMode is set to
110 # Datedue
111 #Set syspref ReturnBeforeExpiry = 0 and useDaysMode = 'Dayweek'
112 t::lib::Mocks::mock_preference('ReturnBeforeExpiry', 0);
113 t::lib::Mocks::mock_preference('useDaysMode', 'Dayweek');
115 # No closed day interfering, so we should get the regular due date
116 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
117 is($date, '2013-02-' . (9 + $issuelength) . 'T23:59:00', "useDaysMode = Dayweek, no closed days, issue date expiry ( start + $issuelength )");
119 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
120 is($date, '2013-02-' . (9 + $renewalperiod) . 'T23:59:00', "useDaysMode = Dayweek, no closed days, renewal date expiry ( start + $renewalperiod )");
122 # Now let's add a closed day on the expected renewal date, it should
123 # roll forward as per Datedue (i.e. one day at a time)
124 # For issues...
125 $calendar->insert_single_holiday(
126 day => 9 + $issuelength,
127 month => 2,
128 year => 2013,
129 title =>'DayweekTest1',
130 description => 'DayweekTest1'
132 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower );
133 is($date, '2013-02-' . (9 + $issuelength + 1) . 'T23:59:00', "useDaysMode = Dayweek, closed on due date, 10 day loan (should not trigger 7 day roll forward), issue date expiry ( start + $issuelength + 1 )");
134 # Remove the holiday we just created
135 $calendar->delete_holiday(
136 day => 9 + $issuelength,
137 month => 2,
138 year => 2013
141 # ...and for renewals...
142 $calendar->insert_single_holiday(
143 day => 9 + $renewalperiod,
144 month => 2,
145 year => 2013,
146 title =>'DayweekTest2',
147 description => 'DayweekTest2'
149 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $borrower, 1 );
150 is($date, '2013-02-' . (9 + $renewalperiod + 1) . 'T23:59:00', "useDaysMode = Dayweek, closed on due date, 5 day renewal (should not trigger 7 day roll forward), renewal date expiry ( start + $renewalperiod + 1 )");
151 # Remove the holiday we just created
152 $calendar->delete_holiday(
153 day => 9 + $renewalperiod,
154 month => 2,
155 year => 2013,
158 # Now we test it does the right thing if the loan and renewal periods
159 # are a multiple of 7 days
160 my $dayweek_categorycode = 'C';
161 my $dayweek_itemtype = 'MX';
162 my $dayweek_branchcode = 'FPL';
163 my $dayweek_issuelength = 14;
164 my $dayweek_renewalperiod = 7;
165 my $dayweek_lengthunit = 'days';
167 Koha::Database->schema->resultset('Issuingrule')->create({
168 categorycode => $dayweek_categorycode,
169 itemtype => $dayweek_itemtype,
170 branchcode => $dayweek_branchcode,
171 issuelength => $dayweek_issuelength,
172 renewalperiod => $dayweek_renewalperiod,
173 lengthunit => $dayweek_lengthunit,
175 my $dayweek_borrower = {categorycode => 'C', dateexpiry => $dateexpiry};
177 # For issues...
178 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
179 $calendar->insert_single_holiday(
180 day => 9 + $dayweek_issuelength,
181 month => 2,
182 year => 2013,
183 title =>'DayweekTest3',
184 description => 'DayweekTest3'
186 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $dayweek_borrower );
187 my $issue_should_add = $dayweek_issuelength + 7;
188 my $dayweek_issue_expected = $start_date->add( days => $issue_should_add );
189 is($date, $dayweek_issue_expected->strftime('%F') . 'T23:59:00', "useDaysMode = Dayweek, closed on due date, 14 day loan (should trigger 7 day roll forward), issue date expiry ( start + $issue_should_add )");
190 # Remove the holiday we just created
191 $calendar->delete_holiday(
192 day => 9 + $dayweek_issuelength,
193 month => 2,
194 year => 2013,
197 # ...and for renewals...
198 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
199 $calendar->insert_single_holiday(
200 day => 9 + $dayweek_renewalperiod,
201 month => 2,
202 year => 2013,
203 title => 'DayweekTest4',
204 description => 'DayweekTest4'
206 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $dayweek_borrower, 1 );
207 my $renewal_should_add = $dayweek_renewalperiod + 7;
208 my $dayweek_renewal_expected = $start_date->add( days => $renewal_should_add );
209 is($date, $dayweek_renewal_expected->strftime('%F') . 'T23:59:00', "useDaysMode = Dayweek, closed on due date, 7 day renewal (should trigger 7 day roll forward), renewal date expiry ( start + $renewal_should_add )");
210 # Remove the holiday we just created
211 $calendar->delete_holiday(
212 day => 9 + $dayweek_renewalperiod,
213 month => 2,
214 year => 2013,
217 # Now test it continues to roll forward by 7 days until it finds
218 # an open day, so we create a 3 week period of closed Saturdays
219 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
220 my $expected_rolled_date = DateTime->new({year => 2013, month => 3, day => 9});
221 my $holiday = $start_date->clone();
222 $holiday->add(days => 7);
223 $calendar->insert_single_holiday(
224 day => $holiday->day,
225 month => $holiday->month,
226 year => 2013,
227 title =>'DayweekTest5',
228 description => 'DayweekTest5'
230 $holiday->add(days => 7);
231 $calendar->insert_single_holiday(
232 day => $holiday->day,
233 month => $holiday->month,
234 year => 2013,
235 title =>'DayweekTest6',
236 description => 'DayweekTest6'
238 $holiday->add(days => 7);
239 $calendar->insert_single_holiday(
240 day => $holiday->day,
241 month => $holiday->month,
242 year => 2013,
243 title =>'DayweekTest7',
244 description => 'DayweekTest7'
246 # For issues...
247 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $dayweek_borrower );
248 $dayweek_issue_expected = $start_date->add( days => $issue_should_add );
249 is($date, $expected_rolled_date->strftime('%F') . 'T23:59:00', "useDaysMode = Dayweek, closed on due date and two subequent due dates, 14 day loan (should trigger 2 x 7 day roll forward), issue date expiry ( start + 28 )");
250 # ...and for renewals...
251 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
252 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $dayweek_borrower, 1 );
253 $dayweek_issue_expected = $start_date->add( days => $renewal_should_add );
254 is($date, $expected_rolled_date->strftime('%F') . 'T23:59:00', "useDaysMode = Dayweek, closed on due date and three subsequent due dates, 7 day renewal (should trigger 3 x 7 day roll forward), issue date expiry ( start + 28 )");
255 # Remove the holidays we just created
256 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
257 my $del_holiday = $start_date->clone();
258 $del_holiday->add(days => 7);
259 $calendar->delete_holiday(
260 day => $del_holiday->day,
261 month => $del_holiday->month,
262 year => 2013
264 $del_holiday->add(days => 7);
265 $calendar->delete_holiday(
266 day => $del_holiday->day,
267 month => $del_holiday->month,
268 year => 2013
270 $del_holiday->add(days => 7);
271 $calendar->delete_holiday(
272 day => $del_holiday->day,
273 month => $del_holiday->month,
274 year => 2013
277 # Now test that useDaysMode "Dayweek" doesn't try to roll forward onto
278 # a permanently closed day and instead rolls forward just one day
279 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
280 # Our tests are concerned with Saturdays, so let's close on Saturdays
281 $calendar->insert_week_day_holiday(
282 weekday => 6,
283 title => "Saturday closure",
284 description => "Closed on Saturdays"
286 # For issues...
287 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $dayweek_borrower );
288 $dayweek_issue_expected = $start_date->add( days => $dayweek_issuelength + 1 );
289 is($date, $dayweek_issue_expected->strftime('%F') . 'T23:59:00', "useDaysMode = Dayweek, due on Saturday, closed on Saturdays, 14 day loan (should trigger 1 day roll forward), issue date expiry ( start + 15 )");
290 # ...and for renewals...
291 $start_date = DateTime->new({year => 2013, month => 2, day => 9});
292 $date = C4::Circulation::CalcDateDue( $start_date, $itemtype, $branchcode, $dayweek_borrower, 1 );
293 $dayweek_renewal_expected = $start_date->add( days => $dayweek_renewalperiod + 1 );
294 is($date, $dayweek_renewal_expected->strftime('%F') . 'T23:59:00', "useDaysMode = Dayweek, due on Saturday, closed on Saturdays, 7 day renewal (should trigger 1 day roll forward), issue date expiry ( start + 8 )");
295 # Remove the holiday we just created
296 $calendar->delete_holiday(
297 weekday => 6
301 $cache->clear_from_cache('single_holidays');
302 $schema->storage->txn_rollback;