View | Details | Raw Unified | Return to bug 8486
Collapse All | Expand All

(-)a/Koha/Calendar.pm (-17 / +70 lines)
Lines 79-84 sub _init { Link Here
79
    }
79
    }
80
    $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
80
    $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
81
    $self->{days_mode} = C4::Context->preference('useDaysMode');
81
    $self->{days_mode} = C4::Context->preference('useDaysMode');
82
    $self->{test} = 0;
82
    return;
83
    return;
83
}
84
}
84
85
Lines 100-106 sub addDate { Link Here
100
        my $dt = $base_date + $add_duration;
101
        my $dt = $base_date + $add_duration;
101
        while ( $self->is_holiday($dt) ) {
102
        while ( $self->is_holiday($dt) ) {
102
103
103
            # TODOP if hours set to 10 am
104
            $dt->add_duration($day_dur);
104
            $dt->add_duration($day_dur);
105
            if ( $unit eq 'hours' ) {
105
            if ( $unit eq 'hours' ) {
106
                $dt->set_hour($return_by_hour);    # Staffs specific
106
                $dt->set_hour($return_by_hour);    # Staffs specific
Lines 169-193 sub days_between { Link Here
169
    my $start_dt = shift;
169
    my $start_dt = shift;
170
    my $end_dt   = shift;
170
    my $end_dt   = shift;
171
171
172
    my $datestart_temp = $start_dt->clone();
173
    my $dateend_temp = $end_dt->clone();
174
172
175
    # start and end should not be closed days
173
    # start and end should not be closed days
176
    $datestart_temp->truncate( to => 'day' );
174
    my $days = $start_dt->delta_days($end_dt)->delta_days;
177
    $dateend_temp->truncate( to => 'day' );
175
    for (my $dt = $start_dt->clone();
178
    my $duration = $dateend_temp - $datestart_temp;
176
        $dt <= $end_dt;
179
    while ( DateTime->compare( $datestart_temp, $dateend_temp ) == -1 ) {
177
        $dt->add(days => 1)
180
        $datestart_temp->add( days => 1 );
178
    ) {
181
        if ( $self->is_holiday($datestart_temp) ) {
179
        if ($self->is_holiday($dt)) {
182
            $duration->subtract( days => 1 );
180
            $days--;
183
        }
181
        }
184
    }
182
    }
185
    return $duration;
183
    return DateTime::Duration->new( days => $days );
186
184
187
}
185
}
188
186
189
sub hours_between {
187
sub hours_between {
190
    my ($self, $start_dt, $end_dt) = @_;
188
    my ($self, $start_date, $end_date) = @_;
189
    my $start_dt = $start_date->clone();
190
    my $end_dt = $end_date->clone();
191
    my $duration = $end_dt->delta_ms($start_dt);
191
    my $duration = $end_dt->delta_ms($start_dt);
192
    $start_dt->truncate( to => 'day' );
192
    $start_dt->truncate( to => 'day' );
193
    $end_dt->truncate( to => 'day' );
193
    $end_dt->truncate( to => 'day' );
Lines 195-206 sub hours_between { Link Here
195
    # However for hourly loans the logic should be expanded to
195
    # However for hourly loans the logic should be expanded to
196
    # take into account open/close times then it would be a duration
196
    # take into account open/close times then it would be a duration
197
    # of library open hours
197
    # of library open hours
198
    while ( DateTime->compare( $start_dt, $end_dt ) == -1 ) {
198
    my $skipped_days = 0;
199
        $start_dt->add( days => 1 );
199
    for (my $dt = $start_dt->clone();
200
        if ( $self->is_holiday($start_dt) ) {
200
        $dt <= $end_dt;
201
            $duration->subtract( hours => 24 );
201
        $dt->add(days => 1)
202
    ) {
203
        if ($self->is_holiday($dt)) {
204
            ++$skipped_days;
202
        }
205
        }
203
    }
206
    }
207
    if ($skipped_days) {
208
        $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days));
209
    }
210
204
    return $duration;
211
    return $duration;
205
212
206
}
213
}
Lines 221-226 sub _mockinit { Link Here
221
    push @{$dates}, $special;
228
    push @{$dates}, $special;
222
    $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
229
    $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
223
    $self->{days_mode} = 'Calendar';
230
    $self->{days_mode} = 'Calendar';
231
    $self->{test} = 1;
232
    return;
233
}
234
235
sub set_daysmode {
236
    my ( $self, $mode ) = @_;
237
238
    # if not testing this is a no op
239
    if ( $self->{test} ) {
240
        $self->{days_mode} = $mode;
241
    }
242
243
    return;
244
}
245
246
sub clear_weekly_closed_days {
247
    my $self = shift;
248
    $self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ];    # Sunday only
249
    return;
250
}
251
252
sub add_holiday {
253
    my $self = shift;
254
    my $new_dt = shift;
255
    my @dt = $self->{exception_holidays}->as_list;
256
    push @dt, $new_dt;
257
    $self->{exception_holidays} =
258
      DateTime::Set->from_datetimes( dates => \@dt );
259
224
    return;
260
    return;
225
}
261
}
226
262
Lines 287-293 passed at DateTime object returns 1 if it is a closed day Link Here
287
$duration = $calendar->days_between($start_dt, $end_dt);
323
$duration = $calendar->days_between($start_dt, $end_dt);
288
324
289
Passed two dates returns a DateTime::Duration object measuring the length between them
325
Passed two dates returns a DateTime::Duration object measuring the length between them
290
ignoring closed days
326
ignoring closed days. Always returns a positive number irrespective of the
327
relative order of the parameters
328
329
=head2 set_daysmode
330
331
For testing only allows the calling script to change days mode
332
333
=head2 clear_weekly_closed_days
334
335
In test mode changes the testing set of closed days to a new set with
336
no closed days. TODO passing an array of closed days to this would
337
allow testing of more configurations
338
339
=head2 add_holiday
340
341
Passed a datetime object this will add it to the calendar's list of
342
closed days. This is for testing so that we can alter the Calenfar object's
343
list of specified dates
291
344
292
=head1 DIAGNOSTICS
345
=head1 DIAGNOSTICS
293
346
(-)a/t/Calendar.t (-8 / +73 lines)
Lines 1-14 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/env perl
2
#
3
# This Koha test module is a stub!  
4
# Add more tests here!!!
5
2
6
use strict;
3
use strict;
7
use warnings;
4
use warnings;
8
5
use DateTime;
9
use Test::More tests => 1;
6
use Test::More tests => 14;
7
use Koha::DateUtils;
10
8
11
BEGIN {
9
BEGIN {
12
        use_ok('C4::Calendar');
10
    use_ok('Koha::Calendar');
11
12
    # This was the only test C4 had
13
    # Remove when no longer used
14
    use_ok('C4::Calendar');
13
}
15
}
14
16
15
- 
17
my $cal = Koha::Calendar->new( TEST_MODE => 1 );
18
19
isa_ok( $cal, 'Koha::Calendar' );
20
21
my $test_dt = DateTime->new(    # Monday
22
    year      => 2012,
23
    month     => 7,
24
    day       => 23,
25
    hour      => 11,
26
    minute    => 53,
27
    time_zone => 'Europe/London',
28
);
29
30
my $later_dt = DateTime->new(    # Monday
31
    year      => 2012,
32
    month     => 9,
33
    day       => 17,
34
    hour      => 17,
35
    minute    => 30,
36
    time_zone => 'Europe/London',
37
);
38
39
my $daycount = $cal->days_between( $test_dt, $later_dt );
40
cmp_ok( $daycount->in_units('days'),
41
    '==', 48, 'days_between calculates correctly' );
42
43
my $ret = $cal->addDate( $test_dt, 1, 'days' );
44
45
cmp_ok( $ret->ymd(), 'eq', '2012-07-24', 'Simple Single Day Add (Calendar)`' );
46
47
$ret = $cal->addDate( $test_dt, 7, 'days' );
48
cmp_ok( $ret->ymd(), 'eq', '2012-07-31', 'Add 7 days Calendar mode' );
49
$cal->set_daysmode('Datedue');
50
$ret = $cal->addDate( $test_dt, 7, 'days' );
51
cmp_ok( $ret->ymd(), 'eq', '2012-07-30', 'Add 7 days Datedue mode' );
52
$cal->set_daysmode('Days');
53
$ret = $cal->addDate( $test_dt, 7, 'days' );
54
cmp_ok( $ret->ymd(), 'eq', '2012-07-30', 'Add 7 days Days mode' );
55
$cal->set_daysmode('Calendar');
56
57
# example tests for bug report
58
$cal->clear_weekly_closed_days();
59
60
$daycount = $cal->days_between( dt_from_string('2012-01-10'),
61
    dt_from_string("2012-05-05") )->in_units('days');
62
cmp_ok( $daycount, '==', 116, 'test larger intervals' );
63
$daycount = $cal->days_between( dt_from_string("2012-01-01"),
64
    dt_from_string("2012-05-05") )->in_units('days');
65
cmp_ok( $daycount, '==', 125, 'test positive intervals' );
66
my $daycount2 = $cal->days_between( dt_from_string("2012-05-05"),
67
    dt_from_string("2012-01-01") )->in_units('days');
68
cmp_ok( $daycount2, '==', $daycount, 'test parameter order not relevant' );
69
$daycount = $cal->days_between( dt_from_string("2012-07-01"),
70
    dt_from_string("2012-07-15") )->in_units('days');
71
cmp_ok( $daycount, '==', 14, 'days_between calculates correctly' );
72
$cal->add_holiday( dt_from_string('2012-07-06') );
73
$daycount = $cal->days_between( dt_from_string("2012-07-01"),
74
    dt_from_string("2012-07-15") )->in_units('days');
75
cmp_ok( $daycount, '==', 13, 'holiday correctly recognized' );
76
77
$cal->add_holiday( dt_from_string('2012-07-07') );
78
$daycount = $cal->days_between( dt_from_string("2012-07-01"),
79
    dt_from_string("2012-07-15") )->in_units('days');
80
cmp_ok( $daycount, '==', 12, 'multiple holidays correctly recognized' );

Return to bug 8486