Bug 11650: multiplicated authorities after link_bibs_to_authorities.pl
[koha_fer] / Koha / Calendar.pm
index 3986038..276c7ce 100644 (file)
@@ -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';
     }
@@ -33,28 +29,51 @@ sub _init {
     my $self       = shift;
     my $branch     = $self->{branchcode};
     my $dbh        = C4::Context->dbh();
-    my $repeat_sth = $dbh->prepare(
-'SELECT * from repeatable_holidays WHERE branchcode = ? AND ISNULL(weekday) = ?'
+    my $weekly_closed_days_sth = $dbh->prepare(
+'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL'
     );
-    $repeat_sth->execute( $branch, 0 );
+    $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 = $repeat_sth->fetchrow_hashref ) {
+    while ( my $tuple = $weekly_closed_days_sth->fetchrow_hashref ) {
         $self->{weekly_closed_days}->[ $tuple->{weekday} ] = 1;
     }
-    $repeat_sth->execute( $branch, 1 );
+    my $day_month_closed_days_sth = $dbh->prepare(
+'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL'
+    );
+    $day_month_closed_days_sth->execute( $branch );
     $self->{day_month_closed_days} = {};
-    while ( my $tuple = $repeat_sth->fetchrow_hashref ) {
+    while ( my $tuple = $day_month_closed_days_sth->fetchrow_hashref ) {
         $self->{day_month_closed_days}->{ $tuple->{month} }->{ $tuple->{day} } =
           1;
     }
 
-    my $special = $dbh->prepare(
-'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = ?'
+    $self->{days_mode}       = C4::Context->preference('useDaysMode');
+    $self->{test}            = 0;
+    return;
+}
+
+
+# FIXME: use of package-level variables for caching the holiday
+# lists breaks persistance engines.  As of 2013-12-10, the RM
+# is allowing this with the expectation that prior to release of
+# 3.16, bug 8089 will be fixed and we can switch the caching over
+# to Koha::Cache.
+our ( $exception_holidays, $single_holidays );
+sub exception_holidays {
+    my ( $self ) = @_;
+    my $dbh = C4::Context->dbh;
+    my $branch = $self->{branchcode};
+    if ( $exception_holidays ) {
+        $self->{exception_holidays} = $exception_holidays;
+        return $exception_holidays;
+    }
+    my $exception_holidays_sth = $dbh->prepare(
+'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 1'
     );
-    $special->execute( $branch, 1 );
+    $exception_holidays_sth->execute( $branch );
     my $dates = [];
-    while ( my ( $day, $month, $year ) = $special->fetchrow ) {
+    while ( my ( $day, $month, $year ) = $exception_holidays_sth->fetchrow ) {
         push @{$dates},
           DateTime->new(
             day       => $day,
@@ -65,10 +84,24 @@ sub _init {
     }
     $self->{exception_holidays} =
       DateTime::Set->from_datetimes( dates => $dates );
+    $exception_holidays = $self->{exception_holidays};
+    return $exception_holidays;
+}
 
-    $special->execute( $branch, 0 );
-    $dates = [];
-    while ( my ( $day, $month, $year ) = $special->fetchrow ) {
+sub single_holidays {
+    my ( $self ) = @_;
+    my $dbh = C4::Context->dbh;
+    my $branch = $self->{branchcode};
+    if ( $single_holidays ) {
+        $self->{single_holidays} = $single_holidays;
+        return $single_holidays;
+    }
+    my $single_holidays_sth = $dbh->prepare(
+'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 0'
+    );
+    $single_holidays_sth->execute( $branch );
+    my $dates = [];
+    while ( my ( $day, $month, $year ) = $single_holidays_sth->fetchrow ) {
         push @{$dates},
           DateTime->new(
             day       => $day,
@@ -78,11 +111,9 @@ sub _init {
           )->truncate( to => 'day' );
     }
     $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
-    $self->{days_mode}       = C4::Context->preference('useDaysMode');
-    $self->{test}            = 0;
-    return;
+    $single_holidays = $self->{single_holidays};
+    return $single_holidays;
 }
-
 sub addDate {
     my ( $self, $startdate, $add_duration, $unit ) = @_;
 
@@ -177,23 +208,32 @@ 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) ) {
+        # 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?
     if ( $dow == 7 ) {
         $dow = 0;
     }
+
     if ( $self->{weekly_closed_days}->[$dow] == 1 ) {
         return 1;
     }
-    $localdt->truncate( to => 'day' );
-    my $day   = $localdt->day;
-    my $month = $localdt->month;
+
     if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) {
         return 1;
     }
-    if ( $self->{exception_holidays}->contains($localdt) ) {
-        return 1;
-    }
-    if ( $self->{single_holidays}->contains($localdt) ) {
+
+    if ( $self->single_holidays->contains($localdt) ) {
         return 1;
     }
 
@@ -232,6 +272,13 @@ sub days_between {
     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;
@@ -275,31 +322,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 ) = @_;
 
@@ -320,10 +342,11 @@ sub clear_weekly_closed_days {
 sub add_holiday {
     my $self = shift;
     my $new_dt = shift;
-    my @dt = $self->{exception_holidays}->as_list;
+    my @dt = $self->single_holidays->as_list;
     push @dt, $new_dt;
-    $self->{exception_holidays} =
+    $self->{single_holidays} =
       DateTime::Set->from_datetimes( dates => \@dt );
+    $single_holidays = $self->{single_holidays};
 
     return;
 }