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

(-)a/Koha/Calendar.pm (+38 lines)
Lines 383-388 sub hours_between { Link Here
383
    return $duration;
383
    return $duration;
384
}
384
}
385
385
386
sub has_business_days_between {
387
    my ( $self, $start_dt, $end_dt ) = @_;
388
389
    # Clone dates to avoid modifying originals
390
    my $current_date = $start_dt->clone->set_time_zone('floating');
391
    my $end_date     = $end_dt->clone->set_time_zone('floating');
392
393
    # Ensure start is before end
394
    if ( $current_date->compare($end_date) >= 0 ) {
395
        return 0;    # Same date or start after end
396
    }
397
398
    # Check each day between start and end (exclusive)
399
    $current_date->add( days => 1 );
400
    while ( $current_date->compare($end_date) < 0 ) {
401
        return 1 unless $self->is_holiday($current_date);
402
        $current_date->add( days => 1 );
403
    }
404
405
    return 0;    # No business days found
406
}
407
386
sub set_daysmode {
408
sub set_daysmode {
387
    my ( $self, $mode ) = @_;
409
    my ( $self, $mode ) = @_;
388
410
Lines 506-511 relative order of the parameters. Link Here
506
528
507
Note: This routine assumes neither the passed start_dt nor end_dt can be a closed day
529
Note: This routine assumes neither the passed start_dt nor end_dt can be a closed day
508
530
531
=head2 has_business_days_between
532
533
$boolean = $calendar->has_business_days_between($start_dt, $end_dt);
534
535
Passed two DateTime objects, returns 1 if there are any business days (non-holidays)
536
between the start and end dates (exclusive), 0 otherwise.
537
538
This method is useful for determining if business days were missed between two dates,
539
such as when checking if server downtime caused business days to be skipped.
540
541
Examples:
542
- Monday to Wednesday with Tuesday as business day: returns 1
543
- Monday to Tuesday (consecutive days): returns 0
544
- Friday to Sunday with Saturday as holiday: returns 0
545
- Same date: returns 0
546
509
=head2 next_open_days
547
=head2 next_open_days
510
548
511
$datetime = $calendar->next_open_days($duedate_dt, $to_add)
549
$datetime = $calendar->next_open_days($duedate_dt, $to_add)
(-)a/t/db_dependent/Koha/Calendar.t (-1 / +138 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2025 Koha Development team
4
#
5
# This file is part of Koha
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::More tests => 3;
23
use Test::Exception;
24
use Test::NoWarnings;
25
26
use Koha::Database;
27
use Koha::DateUtils qw( dt_from_string );
28
use t::lib::TestBuilder;
29
30
BEGIN {
31
    use_ok('Koha::Calendar');
32
}
33
34
my $schema  = Koha::Database->schema;
35
my $builder = t::lib::TestBuilder->new;
36
37
subtest 'has_business_days_between' => sub {
38
39
    plan tests => 6;
40
41
    $schema->storage->txn_begin;
42
43
    my $library    = $builder->build_object( { class => 'Koha::Libraries' } );
44
    my $branchcode = $library->branchcode;
45
46
    # Create test dates
47
    my $monday    = dt_from_string('2024-01-01');    # Monday
48
    my $tuesday   = dt_from_string('2024-01-02');    # Tuesday
49
    my $wednesday = dt_from_string('2024-01-03');    # Wednesday
50
    my $thursday  = dt_from_string('2024-01-04');    # Thursday
51
    my $friday    = dt_from_string('2024-01-05');    # Friday
52
    my $saturday  = dt_from_string('2024-01-06');    # Saturday
53
    my $sunday    = dt_from_string('2024-01-07');    # Sunday
54
55
    # Make Wednesday a holiday
56
    my $wednesday_holiday = $builder->build(
57
        {
58
            source => 'SpecialHoliday',
59
            value  => {
60
                branchcode  => $branchcode,
61
                day         => $wednesday->day,
62
                month       => $wednesday->month,
63
                year        => $wednesday->year,
64
                title       => 'Wednesday Holiday',
65
                isexception => 0
66
            },
67
        }
68
    );
69
70
    # Make Saturday and Sunday holidays (weekend)
71
    my $saturday_holiday = $builder->build(
72
        {
73
            source => 'SpecialHoliday',
74
            value  => {
75
                branchcode  => $branchcode,
76
                day         => $saturday->day,
77
                month       => $saturday->month,
78
                year        => $saturday->year,
79
                title       => 'Saturday Holiday',
80
                isexception => 0
81
            },
82
        }
83
    );
84
85
    my $sunday_holiday = $builder->build(
86
        {
87
            source => 'SpecialHoliday',
88
            value  => {
89
                branchcode  => $branchcode,
90
                day         => $sunday->day,
91
                month       => $sunday->month,
92
                year        => $sunday->year,
93
                title       => 'Sunday Holiday',
94
                isexception => 0
95
            },
96
        }
97
    );
98
99
    my $calendar = Koha::Calendar->new( branchcode => $branchcode );
100
101
    # Test 1: Business day between two business days
102
    is(
103
        $calendar->has_business_days_between( $monday, $wednesday ), 1,
104
        'Should find business day (Tuesday) between Monday and Wednesday'
105
    );
106
107
    # Test 2: No business days between consecutive business days
108
    is(
109
        $calendar->has_business_days_between( $monday, $tuesday ), 0,
110
        'Should find no business days between consecutive days'
111
    );
112
113
    # Test 3: Holiday between two business days
114
    is(
115
        $calendar->has_business_days_between( $tuesday, $thursday ), 0,
116
        'Should find no business days when only holiday (Wednesday) is between'
117
    );
118
119
    # Test 4: Multiple days with business days
120
    is(
121
        $calendar->has_business_days_between( $monday, $friday ), 1,
122
        'Should find business days between Monday and Friday'
123
    );
124
125
    # Test 5: Only holidays between dates
126
    is(
127
        $calendar->has_business_days_between( $friday, $sunday ), 0,
128
        'Should find no business days between Friday and Sunday (Saturday is holiday)'
129
    );
130
131
    # Test 6: Same date
132
    is(
133
        $calendar->has_business_days_between( $monday, $monday ), 0,
134
        'Should find no business days between same date'
135
    );
136
137
    $schema->storage->txn_rollback;
138
};

Return to bug 40636