Bug 16088: Introduce Koha::Cache::Memory::Lite to cache the language
[koha.git] / Koha / Calendar.pm
index 6a12530..1321621 100644 (file)
@@ -7,8 +7,8 @@ use DateTime;
 use DateTime::Set;
 use DateTime::Duration;
 use C4::Context;
+use Koha::Cache;
 use Carp;
-use Readonly;
 
 sub new {
     my ( $classname, %options ) = @_;
@@ -18,10 +18,6 @@ sub new {
         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';
     }
@@ -38,7 +34,6 @@ sub _init {
     );
     $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;
     }
@@ -52,6 +47,20 @@ sub _init {
           1;
     }
 
+    $self->{days_mode}       = C4::Context->preference('useDaysMode');
+    $self->{test}            = 0;
+    return;
+}
+
+sub exception_holidays {
+    my ( $self ) = @_;
+
+    my $cache  = Koha::Cache->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'
     );
@@ -68,25 +77,61 @@ sub _init {
     }
     $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::Cache->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 => C4::Context->tz()
+                )->truncate( to => 'day' );
+                push @ymd_arr, $dt->ymd('');
+            }
+            $single_holidays->{$br} = \@ymd_arr;
+        }    # br
+        $cache->set_in_cache( 'single_holidays', $single_holidays,
+            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 {
@@ -102,7 +147,7 @@ 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 {
@@ -142,6 +187,8 @@ sub addDays {
     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
@@ -168,6 +215,7 @@ sub addDays {
             # 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 {
@@ -182,20 +230,23 @@ sub addDays {
 
 sub is_holiday {
     my ( $self, $dt ) = @_;
+
     my $localdt = $dt->clone();
     my $day   = $localdt->day;
     my $month = $localdt->month;
 
     $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;
     }
@@ -208,7 +259,8 @@ sub is_holiday {
         return 1;
     }
 
-    if ( $self->{single_holidays}->contains($localdt) ) {
+    my $ymd   = $localdt->ymd('')  ;
+    if ($self->single_holidays(  $ymd  ) == 1 ) {
         return 1;
     }
 
@@ -297,31 +349,6 @@ sub hours_between {
 
 }
 
-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 ) = @_;
 
@@ -339,17 +366,6 @@ sub clear_weekly_closed_days {
     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__
 
@@ -357,10 +373,6 @@ __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
@@ -426,6 +438,13 @@ Currently unit is only used to invoke Staffs return Monday at 10 am rule this
 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);