Bug 24545: Fix license statements
[srvgit] / Koha / Calendar.pm
index 298cdb2..dfc358d 100644 (file)
@@ -7,8 +7,8 @@ use DateTime;
 use DateTime::Set;
 use DateTime::Duration;
 use C4::Context;
 use DateTime::Set;
 use DateTime::Duration;
 use C4::Context;
+use Koha::Caches;
 use Carp;
 use Carp;
-use Readonly;
 
 sub new {
     my ( $classname, %options ) = @_;
 
 sub new {
     my ( $classname, %options ) = @_;
@@ -18,10 +18,6 @@ sub new {
         my $o = lc $o_name;
         $self->{$o} = $options{$o_name};
     }
         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';
     }
     if ( !defined $self->{branchcode} ) {
         croak 'No branchcode argument passed to Koha::Calendar->new';
     }
@@ -33,130 +29,256 @@ sub _init {
     my $self       = shift;
     my $branch     = $self->{branchcode};
     my $dbh        = C4::Context->dbh();
     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 ];
     $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;
     }
         $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} = {};
     $self->{day_month_closed_days} = {};
-    while ( my $tuple = $repeat_sth->fetchrow_hashref ) {
-        $self->{day_month_closed_days}->{ $tuple->{day} }->{ $tuple->{month} } =
+    while ( my $tuple = $day_month_closed_days_sth->fetchrow_hashref ) {
+        $self->{day_month_closed_days}->{ $tuple->{month} }->{ $tuple->{day} } =
           1;
     }
           1;
     }
-    my $special = $dbh->prepare(
-'SELECT day, month, year, title, description FROM special_holidays WHERE ( branchcode = ? ) AND (isexception = ?)'
+
+    $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'
     );
     );
-    $special->execute( $branch, 1 );
+    $exception_holidays_sth->execute( $branch );
     my $dates = [];
     my $dates = [];
-    while ( my ( $day, $month, $year, $title, $description ) =
-        $special->fetchrow ) {
+    while ( my ( $day, $month, $year ) = $exception_holidays_sth->fetchrow ) {
         push @{$dates},
           DateTime->new(
             day       => $day,
             month     => $month,
             year      => $year,
         push @{$dates},
           DateTime->new(
             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 );
           )->truncate( to => 'day' );
     }
     $self->{exception_holidays} =
       DateTime::Set->from_datetimes( dates => $dates );
-    $special->execute( $branch, 1 );
-    $dates = [];
-    while ( my ( $day, $month, $year, $title, $description ) =
-        $special->fetchrow ) {
-        push @{$dates},
-          DateTime->new(
-            day       => $day,
-            month     => $month,
-            year      => $year,
-            time_zone => C4::Context->tz()
-          )->truncate( to => 'day' );
+    $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:
+    # {
+    #   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($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 {
     my ( $self, $startdate, $add_duration, $unit ) = @_;
 }
 
 sub addDate {
     my ( $self, $startdate, $add_duration, $unit ) = @_;
-    my $base_date = $startdate->clone();
+
+    # Default to days duration (legacy support I guess)
     if ( ref $add_duration ne 'DateTime::Duration' ) {
         $add_duration = DateTime::Duration->new( days => $add_duration );
     }
     if ( ref $add_duration ne 'DateTime::Duration' ) {
         $add_duration = DateTime::Duration->new( days => $add_duration );
     }
-    $unit ||= q{};    # default days ?
-    my $days_mode = $self->{days_mode};
-    Readonly::Scalar my $return_by_hour => 10;
-    my $day_dur = DateTime::Duration->new( days => 1 );
-    if ( $add_duration->is_negative() ) {
-        $day_dur = DateTime::Duration->new( days => -1 );
+
+    $unit ||= 'days'; # default days ?
+    my $dt;
+    if ( $unit eq 'hours' ) {
+        # Fixed for legacy support. Should be set as a branch parameter
+        my $return_by_hour = 10;
+
+        $dt = $self->addHours($startdate, $add_duration, $return_by_hour);
+    } else {
+        # days
+        $dt = $self->addDays($startdate, $add_duration);
     }
     }
-    if ( $days_mode eq 'Datedue' ) {
+    return $dt;
+}
+
+sub addHours {
+    my ( $self, $startdate, $hours_duration, $return_by_hour ) = @_;
+    my $base_date = $startdate->clone();
 
 
-        my $dt = $base_date + $add_duration;
-        while ( $self->is_holiday($dt) ) {
+    $base_date->add_duration($hours_duration);
 
 
-            $dt->add_duration($day_dur);
-            if ( $unit eq 'hours' ) {
-                $dt->set_hour($return_by_hour);    # Staffs specific
-            }
+    # If we are using the calendar behave for now as if Datedue
+    # was the chosen option (current intended behaviour)
+
+    if ( $self->{days_mode} ne 'Days' &&
+          $self->is_holiday($base_date) ) {
+
+        if ( $hours_duration->is_negative() ) {
+            $base_date = $self->prev_open_days($base_date, 1);
+        } else {
+            $base_date = $self->next_open_days($base_date, 1);
         }
         }
-        return $dt;
-    } elsif ( $days_mode eq 'Calendar' ) {
-        if ( $unit eq 'hours' ) {
-            $base_date->add_duration($add_duration);
-            while ( $self->is_holiday($base_date) ) {
-                $base_date->add_duration($day_dur);
 
 
-            }
+        $base_date->set_hour($return_by_hour);
 
 
+    }
+
+    return $base_date;
+}
+
+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
+        my $days = abs $days_duration->in_units('days');
+
+        if ( $days_duration->is_negative() ) {
+            while ($days) {
+                $base_date = $self->prev_open_days($base_date, 1);
+                --$days;
+            }
         } else {
         } else {
-            my $days = abs $add_duration->in_units('days');
             while ($days) {
             while ($days) {
-                $base_date->add_duration($day_dur);
-                if ( $self->is_holiday($base_date) ) {
-                    next;
-                } else {
-                    --$days;
-                }
+                $base_date = $self->next_open_days($base_date, 1);
+                --$days;
             }
         }
             }
         }
-        if ( $unit eq 'hours' ) {
-            my $dt = $base_date->clone()->subtract( days => 1 );
-            if ( $self->is_holiday($dt) ) {
-                $base_date->set_hour($return_by_hour);    # Staffs specific
+
+    } else { # Days, Datedue or Dayweek
+        # use straight days, then use calendar to push
+        # the date to the next open day as appropriate
+        # if Datedue or Dayweek
+        $base_date->add_duration($days_duration);
+
+        if ( $self->{days_mode} eq 'Datedue' ||
+            $self->{days_mode} eq 'Dayweek') {
+            # Datedue or Dayweek, then use the calendar to push
+            # the date to the next open day if holiday
+            if ( $self->is_holiday($base_date) ) {
+                my $dow = $base_date->day_of_week;
+                my $days = $days_duration->in_units('days');
+                # Is it a period based on weeks
+                my $push_amt = $days % 7 == 0 ?
+                    $self->get_push_amt($base_date) : 1;
+                if ( $days_duration->is_negative() ) {
+                    $base_date = $self->prev_open_days($base_date, $push_amt);
+                } else {
+                    $base_date = $self->next_open_days($base_date, $push_amt);
+                }
             }
         }
             }
         }
-        return $base_date;
-    } else {    # Days
-        return $base_date + $add_duration;
     }
     }
+
+    return $base_date;
+}
+
+sub get_push_amt {
+    my ( $self, $base_date) = @_;
+
+    my $dow = $base_date->day_of_week;
+    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
+    ) ? 7 : 1;
 }
 
 sub is_holiday {
     my ( $self, $dt ) = @_;
 }
 
 sub is_holiday {
     my ( $self, $dt ) = @_;
-    my $dow = $dt->day_of_week;
+
+    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) ) {
+        # exceptions are not holidays
+        return 0;
+    }
+
+    my $dow = $localdt->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;
     }
     if ( $dow == 7 ) {
         $dow = 0;
     }
+
     if ( $self->{weekly_closed_days}->[$dow] == 1 ) {
         return 1;
     }
     if ( $self->{weekly_closed_days}->[$dow] == 1 ) {
         return 1;
     }
-    $dt->truncate( to => 'day' );
-    my $day   = $dt->day;
-    my $month = $dt->month;
+
     if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) {
         return 1;
     }
     if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) {
         return 1;
     }
-    if ( $self->{exception_holidays}->contains($dt) ) {
-        return 1;
-    }
-    if ( $self->{single_holidays}->contains($dt) ) {
+
+    my $ymd   = $localdt->ymd('')  ;
+    if ($self->single_holidays(  $ymd  ) == 1 ) {
         return 1;
     }
 
         return 1;
     }
 
@@ -164,72 +286,99 @@ sub is_holiday {
     return 0;
 }
 
     return 0;
 }
 
+sub next_open_days {
+    my ( $self, $dt, $to_add ) = @_;
+    my $base_date = $dt->clone();
+
+    $base_date->add(days => $to_add);
+    while ($self->is_holiday($base_date)) {
+        my $add_next = $self->get_push_amt($base_date);
+        $base_date->add(days => $add_next);
+    }
+    return $base_date;
+}
+
+sub prev_open_days {
+    my ( $self, $dt, $to_sub ) = @_;
+    my $base_date = $dt->clone();
+
+    # It feels logical to be passed a positive number, though we're
+    # subtracting, so do the right thing
+    $to_sub = $to_sub > 0 ? 0 - $to_sub : $to_sub;
+
+    $base_date->add(days => $to_sub);
+
+    while ($self->is_holiday($base_date)) {
+        my $sub_next = $self->get_push_amt($base_date);
+        # Ensure we're subtracting when we need to be
+        $sub_next = $sub_next > 0 ? 0 - $sub_next : $sub_next;
+        $base_date->add(days => $sub_next);
+    }
+
+    return $base_date;
+}
+
+sub days_forward {
+    my $self     = shift;
+    my $start_dt = shift;
+    my $num_days = shift;
+
+    return $start_dt unless $num_days > 0;
+
+    my $base_dt = $start_dt->clone();
+
+    while ($num_days--) {
+        $base_dt = $self->next_open_days($base_dt, 1);
+    }
+
+    return $base_dt;
+}
+
 sub days_between {
     my $self     = shift;
     my $start_dt = shift;
     my $end_dt   = shift;
 
 sub days_between {
     my $self     = shift;
     my $start_dt = shift;
     my $end_dt   = shift;
 
+    # Change time zone for date math and swap if needed
+    $start_dt = $start_dt->clone->set_time_zone('floating');
+    $end_dt = $end_dt->clone->set_time_zone('floating');
+    if( $start_dt->compare($end_dt) > 0 ) {
+        ( $start_dt, $end_dt ) = ( $end_dt, $start_dt );
+    }
 
     # start and end should not be closed days
 
     # start and end should not be closed days
-    my $days = $start_dt->delta_days($end_dt)->delta_days;
-    for (my $dt = $start_dt->clone();
-        $dt <= $end_dt;
-        $dt->add(days => 1)
-    ) {
-        if ($self->is_holiday($dt)) {
-            $days--;
-        }
+    my $delta_days = $start_dt->delta_days($end_dt)->delta_days;
+    while( $start_dt->compare($end_dt) < 1 ) {
+        $delta_days-- if $self->is_holiday($start_dt);
+        $start_dt->add( days => 1 );
     }
     }
-    return DateTime::Duration->new( days => $days );
-
+    return DateTime::Duration->new( days => $delta_days );
 }
 
 sub hours_between {
     my ($self, $start_date, $end_date) = @_;
 }
 
 sub hours_between {
     my ($self, $start_date, $end_date) = @_;
-    my $start_dt = $start_date->clone();
-    my $end_dt = $end_date->clone();
+    my $start_dt = $start_date->clone()->set_time_zone('floating');
+    my $end_dt = $end_date->clone()->set_time_zone('floating');
+
     my $duration = $end_dt->delta_ms($start_dt);
     $start_dt->truncate( to => 'day' );
     $end_dt->truncate( to => 'day' );
     my $duration = $end_dt->delta_ms($start_dt);
     $start_dt->truncate( to => 'day' );
     $end_dt->truncate( to => 'day' );
+
     # NB this is a kludge in that it assumes all days are 24 hours
     # However for hourly loans the logic should be expanded to
     # take into account open/close times then it would be a duration
     # of library open hours
     my $skipped_days = 0;
     # NB this is a kludge in that it assumes all days are 24 hours
     # However for hourly loans the logic should be expanded to
     # take into account open/close times then it would be a duration
     # of library open hours
     my $skipped_days = 0;
-    for (my $dt = $start_dt->clone();
-        $dt <= $end_dt;
-        $dt->add(days => 1)
-    ) {
-        if ($self->is_holiday($dt)) {
-            ++$skipped_days;
-        }
+    while( $start_dt->compare($end_dt) < 1 ) {
+        $skipped_days++ if $self->is_holiday($start_dt);
+        $start_dt->add( days => 1 );
     }
     }
+
     if ($skipped_days) {
         $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days));
     }
 
     return $duration;
     if ($skipped_days) {
         $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days));
     }
 
     return $duration;
-
-}
-
-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 );
-    $self->{days_mode} = 'Calendar';
-    $self->{test} = 1;
-    return;
 }
 
 sub set_daysmode {
 }
 
 sub set_daysmode {
@@ -249,17 +398,6 @@ sub clear_weekly_closed_days {
     return;
 }
 
     return;
 }
 
-sub add_holiday {
-    my $self = shift;
-    my $new_dt = shift;
-    my @dt = $self->{exception_holidays}->as_list;
-    push @dt, $new_dt;
-    $self->{exception_holidays} =
-      DateTime::Set->from_datetimes( dates => \@dt );
-
-    return;
-}
-
 1;
 __END__
 
 1;
 __END__
 
@@ -267,15 +405,11 @@ __END__
 
 Koha::Calendar - Object containing a branches calendar
 
 
 Koha::Calendar - Object containing a branches calendar
 
-=head1 VERSION
-
-This documentation refers to Koha::Calendar version 0.0.1
-
 =head1 SYNOPSIS
 
 =head1 SYNOPSIS
 
-  use Koha::Calendat
+  use Koha::Calendar
 
 
-  my $c = Koha::Calender->new( branchcode => 'MAIN' );
+  my $c = Koha::Calendar->new( branchcode => 'MAIN' );
   my $dt = DateTime->now();
 
   # are we open
   my $dt = DateTime->now();
 
   # are we open
@@ -311,11 +445,51 @@ 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
 
 
 parameter will be removed when issuingrules properly cope with that
 
 
+=head2 addHours
+
+    my $dt = $calendar->addHours($date, $dur, $return_by_hour )
+
+C<$date> is a DateTime object representing the starting date of the interval.
+
+C<$offset> is a DateTime::Duration to add to it
+
+C<$return_by_hour> is an integer value representing the opening hour for the branch
+
+=head2 get_push_amt
+
+    my $amt = $calendar->get_push_amt($date)
+
+C<$date> is a DateTime object representing a closed return date
+
+Using the days_mode syspref value and the nature of the closed return
+date, return how many days we should jump forward to find another return date
+
+=head2 addDays
+
+    my $dt = $calendar->addDays($date, $dur)
+
+C<$date> is a DateTime object representing the starting date of the interval.
+
+C<$offset> is a DateTime::Duration to add to it
+
+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);
 
 =head2 is_holiday
 
 $yesno = $calendar->is_holiday($dt);
 
-passed at DateTime object returns 1 if it is a closed day
+passed a DateTime object returns 1 if it is a closed day
 0 if not according to the calendar
 
 =head2 days_between
 0 if not according to the calendar
 
 =head2 days_between
@@ -324,7 +498,37 @@ $duration = $calendar->days_between($start_dt, $end_dt);
 
 Passed two dates returns a DateTime::Duration object measuring the length between them
 ignoring closed days. Always returns a positive number irrespective of the
 
 Passed two dates returns a DateTime::Duration object measuring the length between them
 ignoring closed days. Always returns a positive number irrespective of the
-relative order of the parameters
+relative order of the parameters.
+
+Note: This routine assumes neither the passed start_dt nor end_dt can be a closed day
+
+=head2 hours_between
+
+$duration = $calendar->hours_between($start_dt, $end_dt);
+
+Passed two dates returns a DateTime::Duration object measuring the length between them
+ignoring closed days. Always returns a positive number irrespective of the
+relative order of the parameters.
+
+Note: This routine assumes neither the passed start_dt nor end_dt can be a closed day
+
+=head2 next_open_days
+
+$datetime = $calendar->next_open_days($duedate_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 prev_open_days
+
+$datetime = $calendar->prev_open_days($duedate_dt, $to_sub)
+
+Passed a Datetime and a number of days, returns another Datetime
+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 set_daysmode
 
 
 =head2 set_daysmode
 
@@ -359,15 +563,15 @@ Colin Campbell colin.campbell@ptfs-europe.com
 
 Copyright (c) 2011 PTFS-Europe Ltd All rights reserved
 
 
 Copyright (c) 2011 PTFS-Europe Ltd All rights reserved
 
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
+Koha is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.
 
 (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+Koha is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
+along with Koha; if not, see <http://www.gnu.org/licenses>.