Bug 42310: (QA follow-up) Add closed_dates_in_range to Koha::Calendar
Introduces a public Koha::Calendar->closed_dates_in_range($from_dt, $to_dt) method that returns an arrayref of ISO date strings representing every closed day in the inclusive range, honouring weekly, annual repeating, single and exception (open-override) closures. This replaces callers that were reaching into Koha::Calendar private state (_holidays, weekly_closed_days, day_month_closed_days) to reconstruct the same logic. A follow-up under Bug 42206 converts the REST controller; further callers can be migrated incrementally. Test plan: 1. prove t/db_dependent/Koha/Calendar.t 2. Verify the new 'closed_dates_in_range' subtest passes Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io> Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
5875ce4c75
commit
7a8a220842
|
|
@ -484,6 +484,38 @@ sub delete_exception {
|
|||
return $self;
|
||||
}
|
||||
|
||||
sub closed_dates_in_range {
|
||||
my ( $self, $from_dt, $to_dt ) = @_;
|
||||
|
||||
croak 'Missing from_dt in closed_dates_in_range' unless $from_dt;
|
||||
croak 'Missing to_dt in closed_dates_in_range' unless $to_dt;
|
||||
|
||||
my $holidays = $self->_holidays;
|
||||
|
||||
my @closed;
|
||||
my $current = $from_dt->clone;
|
||||
while ( $current <= $to_dt ) {
|
||||
my $ymd = $current->ymd('');
|
||||
|
||||
# Exception (open override) wins over any other closure rule.
|
||||
if ( defined $holidays->{$ymd} && $holidays->{$ymd} == 0 ) {
|
||||
$current->add( days => 1 );
|
||||
next;
|
||||
}
|
||||
|
||||
if ( ( defined $holidays->{$ymd} && $holidays->{$ymd} == 1 )
|
||||
|| $self->{weekly_closed_days}->[ $current->day_of_week % 7 ]
|
||||
|| $self->{day_month_closed_days}->{ $current->month }->{ $current->day } )
|
||||
{
|
||||
push @closed, $current->ymd;
|
||||
}
|
||||
|
||||
$current->add( days => 1 );
|
||||
}
|
||||
|
||||
return \@closed;
|
||||
}
|
||||
|
||||
sub copy_to {
|
||||
my ( $self, $target_branchcode ) = @_;
|
||||
croak "No target_branchcode" unless $target_branchcode;
|
||||
|
|
@ -771,6 +803,17 @@ list of specified dates
|
|||
|
||||
$calendar->delete_exception({ date => '2026-12-25' });
|
||||
|
||||
=head3 closed_dates_in_range
|
||||
|
||||
my $dates = $calendar->closed_dates_in_range($from_dt, $to_dt);
|
||||
|
||||
Returns an arrayref of ISO date strings (YYYY-MM-DD) representing every
|
||||
closed day between C<$from_dt> and C<$to_dt> (inclusive), taking
|
||||
weekly, annual-repeating, single and exception (open override)
|
||||
closures into account. Exceptions win: a date listed as an exception
|
||||
is never returned even if a weekly or repeating rule would otherwise
|
||||
close it.
|
||||
|
||||
=head3 copy_to
|
||||
|
||||
$calendar->copy_to($target_branchcode);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
use Modern::Perl;
|
||||
|
||||
use Test::More tests => 5;
|
||||
use Test::More tests => 6;
|
||||
use Test::Exception;
|
||||
use Test::NoWarnings;
|
||||
|
||||
|
|
@ -229,6 +229,49 @@ subtest 'CRUD methods' => sub {
|
|||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'closed_dates_in_range' => sub {
|
||||
|
||||
plan tests => 5;
|
||||
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
||||
my $branchcode = $library->branchcode;
|
||||
|
||||
# Sunday closed every week, 25 December every year, 2026-06-15 single,
|
||||
# 2026-12-25 open exception (overrides the repeating rule).
|
||||
$builder->build_object(
|
||||
{ class => 'Koha::Calendar::WeeklyClosures', value => { library_id => $branchcode, weekday => 0 } } );
|
||||
$builder->build_object(
|
||||
{
|
||||
class => 'Koha::Calendar::RepeatingClosures',
|
||||
value => { library_id => $branchcode, day => 25, month => 12 }
|
||||
}
|
||||
);
|
||||
$builder->build_object(
|
||||
{ class => 'Koha::Calendar::SingleClosures', value => { library_id => $branchcode, date => '2026-06-15' } } );
|
||||
$builder->build_object(
|
||||
{ class => 'Koha::Calendar::Exceptions', value => { library_id => $branchcode, date => '2026-12-25' } } );
|
||||
|
||||
my $calendar = Koha::Calendar->new( branchcode => $branchcode );
|
||||
|
||||
my $closed = $calendar->closed_dates_in_range( dt_from_string('2026-06-14'), dt_from_string('2026-06-16') );
|
||||
is_deeply( $closed, [ '2026-06-14', '2026-06-15' ], 'Sunday and single closure returned' );
|
||||
|
||||
$closed = $calendar->closed_dates_in_range( dt_from_string('2026-12-24'), dt_from_string('2026-12-26') );
|
||||
is_deeply( $closed, [], 'Exception suppresses repeating closure on 2026-12-25' );
|
||||
|
||||
$closed = $calendar->closed_dates_in_range( dt_from_string('2027-06-15'), dt_from_string('2027-06-15') );
|
||||
is_deeply( $closed, [], 'Open Tuesday not returned' );
|
||||
|
||||
$closed = $calendar->closed_dates_in_range( dt_from_string('2027-12-25'), dt_from_string('2027-12-25') );
|
||||
is_deeply( $closed, ['2027-12-25'], 'Repeating closure returned in a year with no exception' );
|
||||
|
||||
throws_ok { $calendar->closed_dates_in_range() } qr/Missing from_dt/, 'croaks without from_dt';
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'delete_*_closure clears _holidays cache' => sub {
|
||||
|
||||
plan tests => 4;
|
||||
|
|
|
|||
Loading…
Reference in New Issue