Bug 30055: (follow-up) Increase popup window size
[srvgit] / Koha / Calendar.pm
index 0d600a6..5ffebb4 100644 (file)
@@ -2,9 +2,8 @@ package Koha::Calendar;
 
 use Modern::Perl;
 
-use Carp;
+use Carp qw( croak );
 use DateTime;
-use DateTime::Set;
 use DateTime::Duration;
 use C4::Context;
 use Koha::Caches;
@@ -51,93 +50,51 @@ sub _init {
     return;
 }
 
-sub exception_holidays {
-    my ( $self ) = @_;
+sub _holidays {
+    my ($self) = @_;
 
-    my $cache  = Koha::Caches->get_instance();
-    my $cached = $cache->get_from_cache('exception_holidays');
-    return $cached if $cached;
+    my $key      = $self->{branchcode} . "_holidays";
+    my $cache    = Koha::Caches->get_instance();
+    my $holidays = $cache->get_from_cache($key);
 
-    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'
-    );
-    $exception_holidays_sth->execute( $branch );
-    my $dates = [];
-    while ( my ( $day, $month, $year ) = $exception_holidays_sth->fetchrow ) {
-        push @{$dates},
-          DateTime->new(
-            day       => $day,
-            month     => $month,
-            year      => $year,
-            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};
-}
-
-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:
+    # $holidays looks like:
     # {
-    #   CPL =>  [
-    #        [0] 20131122,
-    #         ...
-    #    ],
-    #   ...
+    #    20131122 => 1, # single_holiday
+    #    20131123 => 0, # exception_holiday
+    #    ...
     # }
 
-    unless ($single_holidays) {
+    # Populate the cache if necessary
+    unless ($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($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 ;
-    }
-    my $holidays  = ( $single_holidays->{$branchcode} );
-    for my $hols  (@$holidays ) {
-            return 1 if ( $date == $hols )   #match ymds;
+        $holidays = {};
+
+        # Add holidays for each branch
+        my $holidays_sth = $dbh->prepare(
+'SELECT day, month, year, MAX(isexception) FROM special_holidays WHERE branchcode = ? GROUP BY day, month, year'
+        );
+        $holidays_sth->execute($self->{branchcode});
+
+        while ( my ( $day, $month, $year, $exception ) =
+            $holidays_sth->fetchrow )
+        {
+            my $datestring =
+                sprintf( "%04d", $year )
+              . sprintf( "%02d", $month )
+              . sprintf( "%02d", $day );
+
+            $holidays->{$datestring} = $exception ? 0 : 1;
+        }
+        $cache->set_in_cache( $key, $holidays, { expiry => 76800 } );
     }
-    return 0;
+    return $holidays // {};
 }
 
-sub addDate {
+sub addDuration {
     my ( $self, $startdate, $add_duration, $unit ) = @_;
 
 
-    Koha::Exceptions::MissingParameter->throw("Missing mandatory option for Koha:Calendar->addDate: days_mode")
+    Koha::Exceptions::MissingParameter->throw("Missing mandatory option for Koha:Calendar->addDuration: days_mode")
         unless exists $self->{days_mode};
 
     # Default to days duration (legacy support I guess)
@@ -246,11 +203,18 @@ sub get_push_amt {
         unless exists $self->{days_mode};
 
     my $dow = $base_date->day_of_week;
+    # Representation fix
+    # DateTime object dow (1-7) where Monday is 1
+    # Arrays are 0-based where 0 = Sunday, not 7.
+    if ( $dow == 7 ) {
+        $dow = 0;
+    }
+
     return (
         # We're using Dayweek useDaysMode option
         $self->{days_mode} eq 'Dayweek' &&
         # It's not a permanently closed day
-        !$self->{weekly_closed_days}->[$dow] == 1
+        !$self->{weekly_closed_days}->[$dow]
     ) ? 7 : 1;
 }
 
@@ -260,16 +224,13 @@ sub is_holiday {
     my $localdt = $dt->clone();
     my $day   = $localdt->day;
     my $month = $localdt->month;
+    my $ymd   = $localdt->ymd('');
 
     #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) ) {
-        # exceptions are not holidays
-        return 0;
-    }
+    return $self->_holidays->{$ymd} if defined($self->_holidays->{$ymd});
 
     my $dow = $localdt->day_of_week;
     # Representation fix
@@ -287,11 +248,6 @@ sub is_holiday {
         return 1;
     }
 
-    my $ymd   = $localdt->ymd('')  ;
-    if ($self->single_holidays(  $ymd  ) == 1 ) {
-        return 1;
-    }
-
     # damn have to go to work after all
     return 0;
 }
@@ -436,7 +392,7 @@ Koha::Calendar - Object containing a branches calendar
   # are we open
   $open = $c->is_holiday($dt);
   # when will item be due if loan period = $dur (a DateTime::Duration object)
-  $duedate = $c->addDate($dt,$dur,'days');
+  $duedate = $c->addDuration($dt,$dur,'days');
 
 
 =head1 DESCRIPTION
@@ -452,9 +408,9 @@ my $calendar = Koha::Calendar->new( branchcode => 'MAIN' );
 The option branchcode is required
 
 
-=head2 addDate
+=head2 addDuration
 
-    my $dt = $calendar->addDate($date, $dur, $unit)
+    my $dt = $calendar->addDuration($date, $dur, $unit)
 
 C<$date> is a DateTime object representing the starting date of the interval.
 
@@ -498,14 +454,6 @@ C<$unit> is a string value 'days' or 'hours' toflag granularity of duration
 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);
@@ -551,6 +499,15 @@ representing the previous open day after subtracting the number of passed
 days. It is intended for use to calculate the due date when useDaysMode
 syspref is set to either 'Datedue', 'Calendar' or 'Dayweek'.
 
+=head2 days_forward
+
+$datetime = $calendar->days_forward($start_dt, $to_add)
+
+Passed a Datetime and number of days, returns another Datetime representing
+the next open day after adding the passed number of days. It is intended for
+use to calculate the due date when useDaysMode syspref is set to either
+'Datedue', 'Calendar' or 'Dayweek'.
+
 =head2 set_daysmode
 
 For testing only allows the calling script to change days mode