use DateTime::Set;
use DateTime::Duration;
use C4::Context;
+use Koha::Caches;
use Carp;
-use Readonly;
sub new {
my ( $classname, %options ) = @_;
my $o = lc $o_name;
$self->{$o} = $options{$o_name};
}
- if ( exists $options{TEST_MODE} ) {
- $self->_mockinit();
- return $self;
- }
if ( !defined $self->{branchcode} ) {
croak 'No branchcode argument passed to Koha::Calendar->new';
}
);
$weekly_closed_days_sth->execute( $branch );
$self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ];
- Readonly::Scalar my $sunday => 7;
while ( my $tuple = $weekly_closed_days_sth->fetchrow_hashref ) {
$self->{weekly_closed_days}->[ $tuple->{weekday} ] = 1;
}
1;
}
+ $self->{days_mode} = C4::Context->preference('useDaysMode');
+ $self->{test} = 0;
+ return;
+}
+
+sub exception_holidays {
+ my ( $self ) = @_;
+
+ my $cache = Koha::Caches->get_instance();
+ my $cached = $cache->get_from_cache('exception_holidays');
+ return $cached if $cached;
+
+ my $dbh = C4::Context->dbh;
+ my $branch = $self->{branchcode};
my $exception_holidays_sth = $dbh->prepare(
'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 1'
);
day => $day,
month => $month,
year => $year,
- time_zone => C4::Context->tz()
+ time_zone => "floating",
)->truncate( to => 'day' );
}
$self->{exception_holidays} =
DateTime::Set->from_datetimes( dates => $dates );
+ $cache->set_in_cache( 'exception_holidays', $self->{exception_holidays} );
+ return $self->{exception_holidays};
+}
- my $single_holidays_sth = $dbh->prepare(
+sub single_holidays {
+ my ( $self, $date ) = @_;
+ my $branchcode = $self->{branchcode};
+ my $cache = Koha::Caches->get_instance();
+ my $single_holidays = $cache->get_from_cache('single_holidays');
+
+ # $single_holidays looks like:
+ # {
+ # CPL => [
+ # [0] 20131122,
+ # ...
+ # ],
+ # ...
+ # }
+
+ unless ($single_holidays) {
+ my $dbh = C4::Context->dbh;
+ $single_holidays = {};
+
+ # push holidays for each branch
+ my $branches_sth =
+ $dbh->prepare('SELECT distinct(branchcode) FROM special_holidays');
+ $branches_sth->execute();
+ while ( my $br = $branches_sth->fetchrow ) {
+ my $single_holidays_sth = $dbh->prepare(
'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 0'
- );
- $single_holidays_sth->execute( $branch );
- $dates = [];
- while ( my ( $day, $month, $year ) = $single_holidays_sth->fetchrow ) {
- push @{$dates},
- DateTime->new(
- day => $day,
- month => $month,
- year => $year,
- time_zone => C4::Context->tz()
- )->truncate( to => 'day' );
+ );
+ $single_holidays_sth->execute($br);
+
+ my @ymd_arr;
+ while ( my ( $day, $month, $year ) =
+ $single_holidays_sth->fetchrow )
+ {
+ my $dt = DateTime->new(
+ day => $day,
+ month => $month,
+ year => $year,
+ time_zone => 'floating',
+ )->truncate( to => 'day' );
+ push @ymd_arr, $dt->ymd('');
+ }
+ $single_holidays->{$br} = \@ymd_arr;
+ } # br
+ $cache->set_in_cache( 'single_holidays', $single_holidays,
+ { expiry => 76800 } ) #24 hrs ;
}
- $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
- $self->{days_mode} = C4::Context->preference('useDaysMode');
- $self->{test} = 0;
- return;
+ my $holidays = ( $single_holidays->{$branchcode} );
+ for my $hols (@$holidays ) {
+ return 1 if ( $date == $hols ) #match ymds;
+ }
+ return 0;
}
sub addDate {
if ( $unit eq 'hours' ) {
# Fixed for legacy support. Should be set as a branch parameter
- Readonly::Scalar my $return_by_hour => 10;
+ my $return_by_hour = 10;
$dt = $self->addHours($startdate, $add_duration, $return_by_hour);
} else {
my ( $self, $startdate, $days_duration ) = @_;
my $base_date = $startdate->clone();
+ $self->{days_mode} ||= q{};
+
if ( $self->{days_mode} eq 'Calendar' ) {
# use the calendar to skip all days the library is closed
# when adding
# Datedue, then use the calendar to push
# the date to the next open day if holiday
if ( $self->is_holiday($base_date) ) {
+
if ( $days_duration->is_negative() ) {
$base_date = $self->prev_open_day($base_date);
} else {
sub is_holiday {
my ( $self, $dt ) = @_;
+
my $localdt = $dt->clone();
my $day = $localdt->day;
my $month = $localdt->month;
+ #Change timezone to "floating" before doing any calculations or comparisons
+ $localdt->set_time_zone("floating");
$localdt->truncate( to => 'day' );
- if ( $self->{exception_holidays}->contains($localdt) ) {
+
+ if ( $self->exception_holidays->contains($localdt) ) {
# exceptions are not holidays
return 0;
}
my $dow = $localdt->day_of_week;
# Representation fix
- # TODO: Shouldn't we shift the rest of the $dow also?
+ # DateTime object dow (1-7) where Monday is 1
+ # Arrays are 0-based where 0 = Sunday, not 7.
if ( $dow == 7 ) {
$dow = 0;
}
return 1;
}
- if ( $self->{single_holidays}->contains($localdt) ) {
+ my $ymd = $localdt->ymd('') ;
+ if ($self->single_holidays( $ymd ) == 1 ) {
return 1;
}
my $start_dt = shift;
my $end_dt = shift;
+ if ( $start_dt->compare($end_dt) > 0 ) {
+ # swap dates
+ my $int_dt = $end_dt;
+ $end_dt = $start_dt;
+ $start_dt = $int_dt;
+ }
+
# start and end should not be closed days
my $days = $start_dt->delta_days($end_dt)->delta_days;
}
-sub _mockinit {
- my $self = shift;
- $self->{weekly_closed_days} = [ 1, 0, 0, 0, 0, 0, 0 ]; # Sunday only
- $self->{day_month_closed_days} = { 6 => { 16 => 1, } };
- my $dates = [];
- $self->{exception_holidays} =
- DateTime::Set->from_datetimes( dates => $dates );
- my $special = DateTime->new(
- year => 2011,
- month => 6,
- day => 1,
- time_zone => 'Europe/London',
- );
- push @{$dates}, $special;
- $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
-
- # if not defined, days_mode defaults to 'Calendar'
- if ( !defined($self->{days_mode}) ) {
- $self->{days_mode} = 'Calendar';
- }
-
- $self->{test} = 1;
- return;
-}
-
sub set_daysmode {
my ( $self, $mode ) = @_;
return;
}
-sub add_holiday {
- my $self = shift;
- my $new_dt = shift;
- my @dt = $self->{single_holidays}->as_list;
- push @dt, $new_dt;
- $self->{single_holidays} =
- DateTime::Set->from_datetimes( dates => \@dt );
-
- return;
-}
-
1;
__END__
Koha::Calendar - Object containing a branches calendar
-=head1 VERSION
-
-This documentation refers to Koha::Calendar version 0.0.1
-
=head1 SYNOPSIS
use Koha::Calendar
parameter will be removed when issuingrules properly cope with that
+=head2 single_holidays
+
+my $rc = $self->single_holidays( $ymd );
+
+Passed a $date in Ymd (yyyymmdd) format - returns 1 if date is a single_holiday, or 0 if not.
+
+
=head2 is_holiday
$yesno = $calendar->is_holiday($dt);