From 85337bda527555fcc2adfc1f90132e0e41d7d0c2 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Thu, 20 Jun 2013 16:54:32 -0600 Subject: [PATCH] Bug 8133 - hourly loans doesn't know when library closed This adds support for storing library hours in the calendar, and using those hours to compute hourly loan duetimes. A large amount of cleanup was also performed to expunge duplication of code between C4::Calendar and Koha::Calendar. Test plan: 1) Apply patch. 2) Update database. 3) Verify that the calendar administration interface still exists and works as expected. 4) Run t/Calendar.t and t/db_dependent/Calendar.t. Signed-off-by: Chris Cormack --- C4/Calendar.pm | 153 ++++------ C4/Circulation.pm | 2 + Koha/Calendar.pm | 331 +++++++++++---------- .../data/mysql/de-DE/optional/sample_holidays.sql | 10 +- .../data/mysql/en/optional/sample_holidays.sql | 8 +- .../data/mysql/es-ES/optional/sample_holidays.sql | 8 +- .../data/mysql/it-IT/necessari/sample_holidays.sql | 10 +- installer/data/mysql/kohastructure.sql | 70 +++-- .../mysql/nb-NO/2-Valgfritt/sample_holidays.sql | 14 +- .../data/mysql/pl-PL/optional/sample_holidays.sql | 8 +- installer/data/mysql/ru-RU/optional/holidays.sql | 30 +- installer/data/mysql/uk-UA/optional/holidays.sql | 42 +-- installer/data/mysql/updatedatabase.pl | 76 +++++ .../intranet-tmpl/prog/en/includes/tools-menu.inc | 2 +- .../prog/en/modules/tools/calendar.tt | 56 ++-- misc/cronjobs/staticfines.pl | 2 +- t/Calendar.t | 139 +++++++-- t/db_dependent/Calendar.t | 88 +++--- tools/calendar.pl | 105 +++---- 19 files changed, 648 insertions(+), 506 deletions(-) diff --git a/C4/Calendar.pm b/C4/Calendar.pm index dee183d..7131b56 100644 --- a/C4/Calendar.pm +++ b/C4/Calendar.pm @@ -20,7 +20,7 @@ use vars qw($VERSION @EXPORT); use Carp; -use Koha::Database; +use C4::Context; our ( @ISA, @EXPORT ); @@ -66,10 +66,9 @@ sub GetSingleEvents { return C4::Context->dbh->selectall_arrayref( q{ SELECT - CONCAT(LPAD(year, 4, '0'), '-', LPAD(month, 2, '0'), '-', LPAD(day, 2, '0')) as event_date, - 0 as open_hour, 0 as open_minute, IF(isexception, 24, 0) as close_hour, - 0 as close_minute, title, description, IF(isexception, 0, 1) as closed - FROM special_holidays + event_date, open_hour, open_minute, close_hour, close_minute, title, description, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_events WHERE branchcode = ? }, { Slice => {} }, $branchcode ); } @@ -87,11 +86,11 @@ sub GetWeeklyEvents { return C4::Context->dbh->selectall_arrayref( q{ SELECT - weekday, 0 as open_hour, 0 as open_minute, 0 as close_hour, - 0 as close_minute, title, description, 1 as closed - FROM repeatable_holidays + weekday, open_hour, open_minute, close_hour, close_minute, title, description, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_repeats WHERE branchcode = ? AND weekday IS NOT NULL - }, { Slice => {} }, $branchcode ); + }, { Slice => {} }, $branchcode ); } =head2 GetYearlyEvents @@ -107,130 +106,91 @@ sub GetYearlyEvents { return C4::Context->dbh->selectall_arrayref( q{ SELECT - month, day, 0 as open_hour, 0 as open_minute, 0 as close_hour, - 0 as close_minute, title, description, 1 as closed - FROM repeatable_holidays + month, day, open_hour, open_minute, close_hour, close_minute, title, description, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_repeats WHERE branchcode = ? AND weekday IS NULL }, { Slice => {} }, $branchcode ); } =head2 ModSingleEvent - ModSingleEvent( $branchcode, \%info ) + ModSingleEvent( $branchcode, $date, \%info ) -Creates or updates an event for a single date. $info->{date} should be an -ISO-formatted date string, and \%info should also contain the following keys: -open_hour, open_minute, close_hour, close_minute, title and description. +Creates or updates an event for a single date. $date should be an ISO-formatted +date string, and \%info should contain the following keys: open_hour, +open_minute, close_hour, close_minute, title and description. =cut sub ModSingleEvent { - my ( $branchcode, $info ) = @_; - - my ( $year, $month, $day ) = ( $info->{date} =~ /(\d+)-(\d+)-(\d+)/ ); - return unless ( $year && $month && $day ); - - my $dbh = C4::Context->dbh; - my @args = ( ( map { $info->{$_} } qw(title description) ), $info->{close_hour} != 0, $branchcode, $year, $month, $day ); - - # The code below relies on $dbh->do returning 0 when the update affects no rows - my $affected = $dbh->do( q{ - UPDATE special_holidays - SET - title = ?, description = ?, isexception = ? - WHERE branchcode = ? AND year = ? AND month = ? AND day = ? - }, {}, @args ); - - $dbh->do( q{ - INSERT - INTO special_holidays(title, description, isexception, branchcode, year, month, day) - VALUES (?, ?, ?, ?, ?, ?, ?) - }, {}, @args ) unless ( $affected > 0 ); + my ( $branchcode, $date, $info ) = @_; + + C4::Context->dbh->do( q{ + INSERT INTO calendar_events(branchcode, event_date, open_hour, open_minute, close_hour, close_minute, title, description) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE open_hour = ?, open_minute = ?, close_hour = ?, close_minute = ?, title = ?, description = ? + }, {}, $branchcode, $date, ( map { $info->{$_} } qw(open_hour open_minute close_hour close_minute title description) ) x 2 ); } =head2 ModRepeatingEvent - ModRepeatingEvent( $branchcode, \%info ) + ModRepeatingEvent( $branchcode, $weekday, $month, $day, \%info ) -Creates or updates a weekly- or yearly-repeating event. Either $info->{weekday}, -or $info->{month} and $info->{day} should be set, for a weekly or yearly event, -respectively. +Creates or updates a weekly- or yearly-repeating event. Either $weekday, +or $month and $day should be set, for a weekly or yearly event, respectively. =cut -sub _get_compare { - my ( $colname, $value ) = @_; - - return ' AND ' . $colname . ' ' . ( defined( $value ) ? '=' : 'IS' ) . ' ?'; -} - sub ModRepeatingEvent { - my ( $branchcode, $info ) = @_; - - my $dbh = C4::Context->dbh; - my $open = ( $info->{close_hour} != 0 ); - - if ($open) { - $dbh->do( q{ - DELETE FROM repeatable_holidays - WHERE branchcode = ? - } . _get_compare( 'weekday', $info->{weekday} ) . _get_compare( 'month', $info->{month} ) . _get_compare( 'day', $info->{day} ), {}, $branchcode, $info->{weekday}, $info->{month}, $info->{day} ); - } else { - my @args = ( ( map { $info->{$_} } qw(title description) ), $branchcode, $info->{weekday}, $info->{month}, $info->{day} ); - - # The code below relies on $dbh->do returning 0 when the update affects no rows - my $affected = $dbh->do( q{ - UPDATE repeatable_holidays - SET - title = ?, description = ? - WHERE branchcode = ? - } . _get_compare( 'weekday', $info->{weekday} ) . _get_compare( 'month', $info->{month} ) . _get_compare( 'day', $info->{day} ), {}, @args ); - - $dbh->do( q{ - INSERT - INTO repeatable_holidays(title, description, branchcode, weekday, month, day) - VALUES (?, ?, ?, ?, ?, ?) - }, {}, @args ) unless ( $affected > 0 ); - } + my ( $branchcode, $weekday, $month, $day, $info ) = @_; + + C4::Context->dbh->do( q{ + INSERT INTO calendar_repeats(branchcode, weekday, month, day, open_hour, open_minute, close_hour, close_minute, title, description) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE open_hour = ?, open_minute = ?, close_hour = ?, close_minute = ?, title = ?, description = ? + }, {}, $branchcode, $weekday, $month, $day, ( map { $info->{$_} } qw(open_hour open_minute close_hour close_minute title description) ) x 2 ); } =head2 DelSingleEvent - DelSingleEvent( $branchcode, \%info ) + DelSingleEvent( $branchcode, $date, \%info ) -Deletes an event for a single date. $info->{date} should be an ISO-formatted date string. +Deletes an event for a single date. $date should be an ISO-formatted date string. =cut sub DelSingleEvent { - my ( $branchcode, $info ) = @_; - - my ( $year, $month, $day ) = ( $info->{date} =~ /(\d+)-(\d+)-(\d+)/ ); - return unless ( $year && $month && $day ); + my ( $branchcode, $date ) = @_; C4::Context->dbh->do( q{ - DELETE FROM special_holidays - WHERE branchcode = ? AND year = ? AND month = ? AND day = ? - }, {}, $branchcode, $year, $month, $day ); + DELETE FROM calendar_events + WHERE branchcode = ? AND event_date = ? + }, {}, $branchcode, $date ); +} + +sub _get_compare { + my ( $colname, $value ) = @_; + + return ' AND ' . $colname . ' ' . ( defined( $value ) ? '=' : 'IS' ) . ' ?'; } =head2 DelRepeatingEvent - DelRepeatingEvent( $branchcode, \%info ) + DelRepeatingEvent( $branchcode, $weekday, $month, $day ) -Deletes a weekly- or yearly-repeating event. Either $info->{weekday}, or -$info->{month} and $info->{day} should be set, for a weekly or yearly event, -respectively. +Deletes a weekly- or yearly-repeating event. Either $weekday, or $month and +$day should be set, for a weekly or yearly event, respectively. =cut sub DelRepeatingEvent { - my ( $branchcode, $info ) = @_; + my ( $branchcode, $weekday, $month, $day ) = @_; C4::Context->dbh->do( q{ - DELETE FROM repeatable_holidays + DELETE FROM calendar_repeats WHERE branchcode = ? - } . _get_compare( 'weekday', $info->{weekday} ) . _get_compare( 'month', $info->{month} ) . _get_compare( 'day', $info->{day} ), {}, $branchcode, $info->{weekday}, $info->{month}, $info->{day} ); + } . _get_compare( 'weekday', $weekday ) . _get_compare( 'month', $month ) . _get_compare( 'day', $day ), {}, $branchcode, $weekday, $month, $day ); } =head2 CopyAllEvents @@ -245,16 +205,16 @@ sub CopyAllEvents { my ( $from_branchcode, $to_branchcode ) = @_; C4::Context->dbh->do( q{ - INSERT IGNORE INTO special_holidays(branchcode, year, month, day, isexception, title, description) - SELECT ?, year, month, day, isexception, title, description - FROM special_holidays + INSERT IGNORE INTO calendar_events(branchcode, event_date, open_hour, open_minute, close_hour, close_minute, title, description) + SELECT ?, event_date, open_hour, open_minute, close_hour, close_minute, title, description + FROM calendar_events WHERE branchcode = ? }, {}, $to_branchcode, $from_branchcode ); C4::Context->dbh->do( q{ - INSERT IGNORE INTO repeatable_holidays(branchcode, weekday, month, day, title, description) - SELECT ?, weekday, month, day, title, description - FROM repeatable_holidays + INSERT IGNORE INTO calendar_repeats(branchcode, weekday, month, day, open_hour, open_minute, close_hour, close_minute, title, description) + SELECT ?, weekday, month, day, open_hour, open_minute, close_hour, close_minute, title, description + FROM calendar_repeats WHERE branchcode = ? }, {}, $to_branchcode, $from_branchcode ); } @@ -267,6 +227,5 @@ __END__ =head1 AUTHOR Koha Physics Library UNLP -Jesse Weaver =cut diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 48de084..f2edcc3 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -3337,6 +3337,8 @@ sub CalcDateDue { return $datedue; } + + sub CheckValidBarcode{ my ($barcode) = @_; my $dbh = C4::Context->dbh; diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm index 7f4b9a5..77db08a 100644 --- a/Koha/Calendar.pm +++ b/Koha/Calendar.pm @@ -29,91 +29,41 @@ sub _init { my $self = shift; my $branch = $self->{branchcode}; my $dbh = C4::Context->dbh(); - my $weekly_closed_days_sth = $dbh->prepare( -'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL' - ); - $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; - } - 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 = $day_month_closed_days_sth->fetchrow_hashref ) { - $self->{day_month_closed_days}->{ $tuple->{month} }->{ $tuple->{day} } = - 1; + + $self->{weekday_hours} = $dbh->selectall_hashref( q{ + SELECT + weekday, open_hour, open_minute, close_hour, close_minute, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_repeats + WHERE branchcode = ? AND weekday IS NOT NULL + }, 'weekday', { Slice => {} }, $branch ); + + my $day_month_hours = $dbh->selectall_arrayref( q{ + SELECT + month, day, open_hour, open_minute, close_hour, close_minute, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_repeats + WHERE branchcode = ? AND weekday IS NULL + }, { Slice => {} }, $branch ); + + # DBD::Mock doesn't support multi-key selectall_hashref, so we do it ourselves for now + foreach my $day_month ( @$day_month_hours ) { + $self->{day_month_hours}->{ $day_month->{month} }->{ $day_month->{day} } = $day_month; } + $self->{date_hours} = $dbh->selectall_hashref( q{ + SELECT + event_date, open_hour, open_minute, close_hour, close_minute, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_events + WHERE branchcode = ? + }, 'event_date', { Slice => {} }, $branch ); + $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' - ); - $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 => C4::Context->tz() - )->truncate( to => 'day' ); - } - $self->{exception_holidays} = - DateTime::Set->from_datetimes( dates => $dates ); - $exception_holidays = $self->{exception_holidays}; - return $exception_holidays; -} - -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, - month => $month, - year => $year, - time_zone => C4::Context->tz() - )->truncate( to => 'day' ); - } - $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates ); - $single_holidays = $self->{single_holidays}; - return $single_holidays; -} sub addDate { my ( $self, $startdate, $add_duration, $unit ) = @_; @@ -126,10 +76,7 @@ sub addDate { my $dt; if ( $unit eq 'hours' ) { - # Fixed for legacy support. Should be set as a branch parameter - Readonly::Scalar my $return_by_hour => 10; - - $dt = $self->addHours($startdate, $add_duration, $return_by_hour); + $dt = $self->addHours($startdate, $add_duration); } else { # days $dt = $self->addDays($startdate, $add_duration); @@ -139,25 +86,73 @@ sub addDate { } sub addHours { - my ( $self, $startdate, $hours_duration, $return_by_hour ) = @_; + my ( $self, $startdate, $hours_duration ) = @_; my $base_date = $startdate->clone(); - $base_date->add_duration($hours_duration); + if ( $self->{days_mode} eq 'Days' ) { + $base_date->add_duration( $hours_duration ); + return $base_date; + } + my $hours = $self->get_hours_full( $base_date ); + + if ( $hours_duration->is_negative() ) { + if ( $base_date <= $hours->{open_time} ) { + # Library is already closed + $base_date = $self->prev_open_day( $base_date ); + $hours = $self->get_hours_full( $base_date ); + $base_date = $hours->{close_time}->clone; + + if ( $self->{days_mode} eq 'Calendar' ) { + return $base_date; + } + } - # If we are using the calendar behave for now as if Datedue - # was the chosen option (current intended behaviour) + while ( $hours_duration->is_negative ) { + my $day_len = $hours->{open_time} - $base_date; - if ( $self->{days_mode} ne 'Days' && - $self->is_holiday($base_date) ) { + if ( DateTime::Duration->compare( $day_len, $hours_duration, $base_date ) > 0 ) { + if ( $self->{days_mode} eq 'Calendar' ) { + return $hours->{open_time}; + } - if ( $hours_duration->is_negative() ) { - $base_date = $self->prev_open_day($base_date); - } else { - $base_date = $self->next_open_day($base_date); + $hours_duration->subtract( $day_len ); + $base_date = $self->prev_open_day( $base_date ); + $hours = $self->get_hours_full( $base_date ); + $base_date = $hours->{close_time}->clone; + } else { + $base_date->add_duration( $hours_duration ); + return $base_date; + } + } + } else { + if ( $base_date >= $hours->{close_time} ) { + # Library is already closed + $base_date = $self->next_open_day( $base_date ); + $hours = $self->get_hours_full( $base_date ); + $base_date = $hours->{open_time}->clone; + + if ( $self->{days_mode} eq 'Calendar' ) { + return $base_date; + } } - $base_date->set_hour($return_by_hour); + while ( $hours_duration->is_positive ) { + my $day_len = $hours->{close_time} - $base_date; + + if ( DateTime::Duration->compare( $day_len, $hours_duration, $base_date ) < 0 ) { + if ( $self->{days_mode} eq 'Calendar' ) { + return $hours->{close_time}; + } + $hours_duration->subtract( $day_len ); + $base_date = $self->next_open_day( $base_date ); + $hours = $self->get_hours_full( $base_date ); + $base_date = $hours->{open_time}->clone; + } else { + $base_date->add_duration( $hours_duration ); + return $base_date; + } + } } return $base_date; @@ -207,33 +202,25 @@ sub addDays { sub is_holiday { my ( $self, $dt ) = @_; - my $localdt = $dt->clone(); - my $day = $localdt->day; - my $month = $localdt->month; - - $localdt->truncate( to => 'day' ); + my $day = $dt->day; + my $month = $dt->month; - if ( $self->_exception_holidays->contains($localdt) ) { - # exceptions are not holidays + if ( exists $self->{date_hours}->{ $dt->ymd } && !$self->{date_hours}->{ $dt->ymd }->{closed} ) { 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 ) { + if ( ( $self->{day_month_hours}->{$month}->{$day} || {} )->{closed} ) { return 1; } - if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) { + # We use 0 for Sunday, not 7 + my $dow = $dt->day_of_week % 7; + + if ( ( $self->{weekday_hours}->{ $dow } || {} )->{closed} ) { return 1; } - if ( $self->_single_holidays->contains($localdt) ) { + if ( ( $self->{date_hours}->{ $dt->ymd } || {} )->{closed} ) { return 1; } @@ -241,6 +228,60 @@ sub is_holiday { return 0; } +sub get_hours { + my ( $self, $dt ) = @_; + my $day = $dt->day; + my $month = $dt->month; + + if ( exists $self->{date_hours}->{ $dt->ymd } ) { + return $self->{date_hours}->{ $dt->ymd }; + } + + if ( exists $self->{day_month_hours}->{$month}->{$day} ) { + return $self->{day_month_hours}->{$month}->{$day}; + } + + # We use 0 for Sunday, not 7 + my $dow = $dt->day_of_week % 7; + + if ( exists $self->{weekday_hours}->{ $dow } ) { + return $self->{weekday_hours}->{ $dow }; + } + + # Assume open + return { + open_hour => 0, + open_minute => 0, + close_hour => 24, + close_minute => 0, + closed => 0 + }; +} + +sub get_hours_full { + my ( $self, $dt ) = @_; + + my $hours = { %{ $self->get_hours( $dt ) } }; + + $hours->{open_time} = $dt + ->clone->truncate( to => 'day' ) + ->set_hour( $hours->{open_hour} ) + ->set_minute( $hours->{open_minute} ); + + if ( $hours->{close_hour} == 24 ) { + $hours->{close_time} = $dt + ->clone->truncate( to => 'day' ) + ->add( days => 1 ); + } else { + $hours->{close_time} = $dt + ->clone->truncate( to => 'day' ) + ->set_hour( $hours->{close_hour} ) + ->set_minute( $hours->{close_minute} ); + } + + return $hours; +} + sub next_open_day { my ( $self, $dt ) = @_; my $base_date = $dt->clone(); @@ -298,45 +339,39 @@ sub hours_between { my ($self, $start_date, $end_date) = @_; my $start_dt = $start_date->clone(); my $end_dt = $end_date->clone(); - 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; - for (my $dt = $start_dt->clone(); - $dt <= $end_dt; - $dt->add(days => 1) - ) { - if ($self->is_holiday($dt)) { - ++$skipped_days; - } - } - if ($skipped_days) { - $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days)); + + if ( $start_dt->compare($end_dt) > 0 ) { + # swap dates + my $int_dt = $end_dt; + $end_dt = $start_dt; + $start_dt = $int_dt; } - return $duration; + my $start_hours = $self->get_hours_full( $start_dt ); + my $end_hours = $self->get_hours_full( $end_dt ); -} + $start_dt = $start_hours->{open_time} if ( $start_dt < $start_hours->{open_time} ); + $end_dt = $end_hours->{close_time} if ( $end_dt > $end_hours->{close_time} ); + + return $end_dt - $start_dt if ( $start_dt->ymd eq $end_dt->ymd ); -sub set_daysmode { - my ( $self, $mode ) = @_; + my $duration = DateTime::Duration->new; + + $duration->add_duration( $start_hours->{close_time} - $start_dt ) if ( $start_dt < $start_hours->{close_time} ); - # if not testing this is a no op - if ( $self->{test} ) { - $self->{days_mode} = $mode; + for (my $date = $start_dt->clone->truncate( to => 'day' )->add( days => 1 ); + $date->ymd lt $end_dt->ymd; + $date->add(days => 1) + ) { + my $hours = $self->get_hours_full( $date ); + + $duration->add_duration( $hours->{close_time}->delta_ms( $hours->{open_time} ) ); } - return; -} + $duration->add_duration( $end_dt - $end_hours->{open_time} ) if ( $end_dt > $start_hours->{open_time} ); + + return $duration; -sub clear_weekly_closed_days { - my $self = shift; - $self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ]; # Sunday only - return; } 1; @@ -392,14 +427,12 @@ parameter will be removed when issuingrules properly cope with that =head2 addHours - my $dt = $calendar->addHours($date, $dur, $return_by_hour ) + my $dt = $calendar->addHours($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<$return_by_hour> is an integer value representing the opening hour for the branch - =head2 addDays @@ -446,16 +479,6 @@ Passed a Datetime returns another Datetime representing the previous open day. I intended for use to calculate the due date when useDaysMode syspref is set to either 'Datedue' or 'Calendar'. -=head2 set_daysmode - -For testing only allows the calling script to change days mode - -=head2 clear_weekly_closed_days - -In test mode changes the testing set of closed days to a new set with -no closed days. TODO passing an array of closed days to this would -allow testing of more configurations - =head1 DIAGNOSTICS Will croak if not passed a branchcode in new diff --git a/installer/data/mysql/de-DE/optional/sample_holidays.sql b/installer/data/mysql/de-DE/optional/sample_holidays.sql index 124fcad..7f18bf2 100644 --- a/installer/data/mysql/de-DE/optional/sample_holidays.sql +++ b/installer/data/mysql/de-DE/optional/sample_holidays.sql @@ -1,5 +1,5 @@ -INSERT INTO `repeatable_holidays` VALUES -(2,'MPL',0,NULL,NULL,'','Sonntag'), -(3,'MPL',NULL,1,1,'','Neujahr'), -(4,'MPL',NULL,25,12,'','1. Weihnachtsfeiertag'), -(5,'MPL',NULL,25,12,'','2. Weihnachtsfeiertag'); +INSERT INTO `calendar_repeats` VALUES +(2,'MPL',0,NULL,NULL,'','Sonntag',0,0,0,0), +(3,'MPL',NULL,1,1,'','Neujahr',0,0,0,0), +(4,'MPL',NULL,12,25,'','1. Weihnachtsfeiertag',0,0,0,0), +(5,'MPL',NULL,12,25,'','2. Weihnachtsfeiertag',0,0,0,0); diff --git a/installer/data/mysql/en/optional/sample_holidays.sql b/installer/data/mysql/en/optional/sample_holidays.sql index 33b6ff6..866c14f 100644 --- a/installer/data/mysql/en/optional/sample_holidays.sql +++ b/installer/data/mysql/en/optional/sample_holidays.sql @@ -1,4 +1,4 @@ -INSERT INTO `repeatable_holidays` VALUES -(2,'MPL',0,NULL,NULL,'','Sundays'), -(3,'MPL',NULL,1,1,'','New Year\'s Day'), -(4,'MPL',NULL,25,12,'','Christmas'); +INSERT INTO `calendar_repeats` VALUES +(2,'MPL',0,NULL,NULL,'','Sundays',0,0,0,0), +(3,'MPL',NULL,1,1,'','New Year\'s Day',0,0,0,0), +(4,'MPL',NULL,12,25,'','Christmas',0,0,0,0); diff --git a/installer/data/mysql/es-ES/optional/sample_holidays.sql b/installer/data/mysql/es-ES/optional/sample_holidays.sql index e323317..1cf78ec 100644 --- a/installer/data/mysql/es-ES/optional/sample_holidays.sql +++ b/installer/data/mysql/es-ES/optional/sample_holidays.sql @@ -1,4 +1,4 @@ -INSERT INTO `repeatable_holidays` VALUES -(2,'',0,NULL,NULL,'','Sundays'), -(3,'',NULL,1,1,'','New Year\'s Day'), -(4,'',NULL,25,12,'','Christmas'); +INSERT INTO `calendar_repeats` VALUES +(2,'',0,NULL,NULL,'','Sundays',0,0,0,0), +(3,'',NULL,1,1,'','New Year\'s Day',0,0,0,0), +(4,'',NULL,12,25,'','Christmas',0,0,0,0); diff --git a/installer/data/mysql/it-IT/necessari/sample_holidays.sql b/installer/data/mysql/it-IT/necessari/sample_holidays.sql index 67640a9..f1478de 100644 --- a/installer/data/mysql/it-IT/necessari/sample_holidays.sql +++ b/installer/data/mysql/it-IT/necessari/sample_holidays.sql @@ -1,8 +1,8 @@ SET FOREIGN_KEY_CHECKS=0; -INSERT INTO `repeatable_holidays` VALUES -(2,'',0,NULL,NULL,'','Domenica'), -(3,'',NULL,1,1,'','Nuovo anno'), -(4,'',NULL,25,12,'','Natale'); +INSERT INTO `calendar_repeats` VALUES +(2,'',0,NULL,NULL,'','Domenica',0,0,0,0), +(3,'',NULL,1,1,'','Nuovo anno',0,0,0,0), +(4,'',NULL,12,25,'','Natale',0,0,0,0); -SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file +SET FOREIGN_KEY_CHECKS=1; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index aeeba17..6edb078 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -667,6 +667,43 @@ CREATE TABLE `default_circ_rules` ( PRIMARY KEY (`singleton`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `calendar_events` +-- +DROP TABLE IF EXISTS `calendar_events`; +CREATE TABLE `calendar_events` ( + `branchcode` varchar(10) NOT NULL DEFAULT '', + `event_date` date NOT NULL, + `title` varchar(50) NOT NULL DEFAULT '', + `description` text NOT NULL, + `open_hour` smallint(6) NOT NULL, + `open_minute` smallint(6) NOT NULL, + `close_hour` smallint(6) NOT NULL, + `close_minute` smallint(6) NOT NULL, + PRIMARY KEY (`branchcode`,`event_date`), + CONSTRAINT `calendar_events_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `calendar_repeats` +-- +DROP TABLE IF EXISTS `calendar_repeats`; +CREATE TABLE `calendar_repeats` ( + `branchcode` varchar(10) NOT NULL DEFAULT '', + `weekday` smallint(6) DEFAULT NULL, + `month` smallint(6) DEFAULT NULL, + `day` smallint(6) DEFAULT NULL, + `title` varchar(50) NOT NULL DEFAULT '', + `description` text NOT NULL, + `open_hour` smallint(6) NOT NULL, + `open_minute` smallint(6) NOT NULL, + `close_hour` smallint(6) NOT NULL, + `close_minute` smallint(6) NOT NULL, + UNIQUE KEY `branchcode` (`branchcode`,`weekday`), + UNIQUE KEY `branchcode_2` (`branchcode`,`month`,`day`), + CONSTRAINT `calendar_repeats_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Table structure for table `cities` -- @@ -1766,22 +1803,6 @@ CREATE TABLE `printers_profile` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- --- Table structure for table `repeatable_holidays` --- - -DROP TABLE IF EXISTS `repeatable_holidays`; -CREATE TABLE `repeatable_holidays` ( -- information for the days the library is closed - `id` int(11) NOT NULL auto_increment, -- unique identifier assigned by Koha - `branchcode` varchar(10) NOT NULL default '', -- foreign key from the branches table, defines which branch this closing is for - `weekday` smallint(6) default NULL, -- day of the week (0=Sunday, 1=Monday, etc) this closing is repeated on - `day` smallint(6) default NULL, -- day of the month this closing is on - `month` smallint(6) default NULL, -- month this closing is in - `title` varchar(50) NOT NULL default '', -- title of this closing - `description` text NOT NULL, -- description for this closing - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -- Table structure for table `reports_dictionary` -- @@ -1954,23 +1975,6 @@ CREATE TABLE sessions ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- --- Table structure for table `special_holidays` --- - -DROP TABLE IF EXISTS `special_holidays`; -CREATE TABLE `special_holidays` ( -- non repeatable holidays/library closings - `id` int(11) NOT NULL auto_increment, -- unique identifier assigned by Koha - `branchcode` varchar(10) NOT NULL default '', -- foreign key from the branches table, defines which branch this closing is for - `day` smallint(6) NOT NULL default 0, -- day of the month this closing is on - `month` smallint(6) NOT NULL default 0, -- month this closing is in - `year` smallint(6) NOT NULL default 0, -- year this closing is in - `isexception` smallint(1) NOT NULL default 1, -- is this a holiday exception to a repeatable holiday (1 for yes, 0 for no) - `title` varchar(50) NOT NULL default '', -- title for this closing - `description` text NOT NULL, -- description of this closing - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -- Table structure for table `statistics` -- diff --git a/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql b/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql index 7df9e67..d2b5ab7 100644 --- a/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql +++ b/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql @@ -19,10 +19,10 @@ -- with Koha; if not, write to the Free Software Foundation, Inc., -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -INSERT INTO `repeatable_holidays` VALUES -(2,'',0,NULL,NULL,'','Søndager'), -(3,'',NULL,1,1,'','1. nyttårsdag'), -(4,'',NULL,1,5,'','1. mai'), -(5,'',NULL,17,5,'','17. mai'), -(6,'',NULL,25,12,'','1. juledag'), -(7,'',NULL,26,12,'','2. juledag'); +INSERT INTO `calendar_repeats` VALUES +(2,'',0,NULL,NULL,'','Søndager',0,0,0,0), +(3,'',NULL,1,1,'','1. nyttårsdag',0,0,0,0), +(4,'',NULL,5,1,'','1. mai',0,0,0,0), +(5,'',NULL,5,17,'','17. mai',0,0,0,0), +(6,'',NULL,12,25,'','1. juledag',0,0,0,0), +(7,'',NULL,12,26,'','2. juledag',0,0,0,0); diff --git a/installer/data/mysql/pl-PL/optional/sample_holidays.sql b/installer/data/mysql/pl-PL/optional/sample_holidays.sql index bee37b5..6dfd59d 100644 --- a/installer/data/mysql/pl-PL/optional/sample_holidays.sql +++ b/installer/data/mysql/pl-PL/optional/sample_holidays.sql @@ -1,4 +1,4 @@ -INSERT INTO `repeatable_holidays` VALUES -(2,'',0,NULL,NULL,'','Niedziele'), -(3,'',NULL,1,1,'','Nowy Rok'), -(4,'',NULL,25,12,'','Boże Narodzenie'); +INSERT INTO `calendar_repeats` VALUES +(2,'',0,NULL,NULL,'','Niedziele',0,0,0,0), +(3,'',NULL,1,1,'','Nowy Rok',0,0,0,0), +(4,'',NULL,12,25,'','Boże Narodzenie',0,0,0,0); diff --git a/installer/data/mysql/ru-RU/optional/holidays.sql b/installer/data/mysql/ru-RU/optional/holidays.sql index 42f3311..7d8e00b 100644 --- a/installer/data/mysql/ru-RU/optional/holidays.sql +++ b/installer/data/mysql/ru-RU/optional/holidays.sql @@ -1,23 +1,23 @@ -TRUNCATE repeatable_holidays; +TRUNCATE calendar_repeats; -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (2, '',0,NULL,NULL,'','Воскресенья'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',0,NULL,NULL,'','Воскресенья', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (3, '',NULL,1,1,'','Новый год'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',NULL,1,1,'','Новый год', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (4, '',NULL,7,1,'','Рождество'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',NULL,7,1,'','Рождество', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (5, '',NULL,8,3,'','Международный женский день'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',NULL,8,3,'','Международный женский день', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (6, '',NULL,1,5,'','День Труда'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',NULL,1,5,'','День Труда', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (7, '',NULL,2,5,'','День Труда'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',NULL,2,5,'','День Труда', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) -VALUES (8, '',NULL,9,5,'','День Победы'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) +VALUES ('',NULL,9,5,'','День Победы', 0, 0, 0, 0); diff --git a/installer/data/mysql/uk-UA/optional/holidays.sql b/installer/data/mysql/uk-UA/optional/holidays.sql index 55f45be..f6ce5bd 100644 --- a/installer/data/mysql/uk-UA/optional/holidays.sql +++ b/installer/data/mysql/uk-UA/optional/holidays.sql @@ -1,24 +1,24 @@ -TRUNCATE repeatable_holidays; +TRUNCATE calendar_repeats; -INSERT INTO `repeatable_holidays` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`) VALUES -('STL', 0, NULL, NULL,'', 'Неділі'), -('STL', NULL, 1, 1, '', 'Новий рік'), -('STL', NULL, 7, 1, '', 'Різдво'), -('STL', NULL, 8, 3, '', 'Міжнародний жіночий день'), -('STL', NULL, 1, 5, '', 'День Праці'), -('STL', NULL, 2, 5, '', 'День Праці'), -('STL', NULL, 9, 5, '', 'День Перемоги'), -('STL', NULL, 28, 6, '', 'День Конституції'), -('STL', NULL, 24, 8, '', 'День Незалежності'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) VALUES +('STL', 0, NULL, NULL,'', 'Неділі', 0, 0, 0, 0), +('STL', NULL, 1, 1, '', 'Новий рік', 0, 0, 0, 0), +('STL', NULL, 7, 1, '', 'Різдво', 0, 0, 0, 0), +('STL', NULL, 8, 3, '', 'Міжнародний жіночий день', 0, 0, 0, 0), +('STL', NULL, 1, 5, '', 'День Праці', 0, 0, 0, 0), +('STL', NULL, 2, 5, '', 'День Праці', 0, 0, 0, 0), +('STL', NULL, 9, 5, '', 'День Перемоги', 0, 0, 0, 0), +('STL', NULL, 28, 6, '', 'День Конституції', 0, 0, 0, 0), +('STL', NULL, 24, 8, '', 'День Незалежності', 0, 0, 0, 0); -INSERT INTO `repeatable_holidays` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`) VALUES -('LNSL', 0, NULL, NULL,'', 'Неділі'), -('LNSL', NULL, 1, 1, '', 'Новий рік'), -('LNSL', NULL, 7, 1, '', 'Різдво'), -('LNSL', NULL, 8, 3, '', 'Міжнародний жіночий день'), -('LNSL', NULL, 1, 5, '', 'День Праці'), -('LNSL', NULL, 2, 5, '', 'День Праці'), -('LNSL', NULL, 9, 5, '', 'День Перемоги'), -('LNSL', NULL, 28, 6, '', 'День Конституції'), -('LNSL', NULL, 24, 8, '', 'День Незалежності'); +INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) VALUES +('LNSL', 0, NULL, NULL,'', 'Неділі', 0, 0, 0, 0), +('LNSL', NULL, 1, 1, '', 'Новий рік', 0, 0, 0, 0), +('LNSL', NULL, 7, 1, '', 'Різдво', 0, 0, 0, 0), +('LNSL', NULL, 8, 3, '', 'Міжнародний жіночий день', 0, 0, 0, 0), +('LNSL', NULL, 1, 5, '', 'День Праці', 0, 0, 0, 0), +('LNSL', NULL, 2, 5, '', 'День Праці', 0, 0, 0, 0), +('LNSL', NULL, 9, 5, '', 'День Перемоги', 0, 0, 0, 0), +('LNSL', NULL, 28, 6, '', 'День Конституції', 0, 0, 0, 0), +('LNSL', NULL, 24, 8, '', 'День Незалежності', 0, 0, 0, 0); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 9bdc033..e862d94 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -8777,6 +8777,82 @@ if ( CheckVersion($DBversion) ) { INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('StatisticsFields','location|itype|ccode','Define fields (from the items table) used for statistics members',NULL,'Free') }); print "Upgrade to $DBversion done (Bug 12728: Checked syspref StatisticsFields)\n"; + + SetVersion($DBversion); +} + +$DBversion = "3.17.00.XXX"; +if ( CheckVersion($DBversion) ) { + print "Upgrade to $DBversion done (Bug 8133: create tables, migrate data to calendar_*)\n"; + + $dbh->do( q{ + CREATE TABLE `calendar_events` ( + `branchcode` varchar(10) NOT NULL DEFAULT '', + `event_date` date NOT NULL, + `title` varchar(50) NOT NULL DEFAULT '', + `description` text NOT NULL, + `open_hour` smallint(6) NOT NULL, + `open_minute` smallint(6) NOT NULL, + `close_hour` smallint(6) NOT NULL, + `close_minute` smallint(6) NOT NULL, + PRIMARY KEY (`branchcode`,`event_date`), + CONSTRAINT `calendar_events_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + } ); + + $dbh->do( q{ + CREATE TABLE `calendar_repeats` ( + `branchcode` varchar(10) NOT NULL DEFAULT '', + `weekday` smallint(6) DEFAULT NULL, + `month` smallint(6) DEFAULT NULL, + `day` smallint(6) DEFAULT NULL, + `title` varchar(50) NOT NULL DEFAULT '', + `description` text NOT NULL, + `open_hour` smallint(6) NOT NULL, + `open_minute` smallint(6) NOT NULL, + `close_hour` smallint(6) NOT NULL, + `close_minute` smallint(6) NOT NULL, + UNIQUE KEY `branchcode` (`branchcode`,`weekday`), + UNIQUE KEY `branchcode_2` (`branchcode`,`month`,`day`), + CONSTRAINT `calendar_repeats_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + } ); + + $dbh->do( q{ + INSERT INTO + calendar_events(branchcode, event_date, title, description, open_hour, open_minute, close_hour, close_minute) + SELECT + branchcode, CONCAT_WS('-', year, month, day), title, description, 0, 0, 0, 0 + FROM special_holidays + WHERE isexception = 0 + } ); + + $dbh->do( q{ + INSERT INTO + calendar_events(branchcode, event_date, title, description, open_hour, open_minute, close_hour, close_minute) + SELECT + branchcode, CONCAT_WS('-', year, month, day), title, description, 0, 0, 24, 0 + FROM special_holidays + WHERE isexception = 1 + } ); + + $dbh->do( q{ + INSERT INTO + calendar_repeats(branchcode, weekday, month, day, title, description, open_hour, open_minute, close_hour, close_minute) + SELECT + branchcode, weekday, month, day, title, description, 0, 0, 0, 0 + FROM repeatable_holidays + WHERE weekday IS NULL + } ); + + $dbh->do( q{ + DROP TABLE repeatable_holidays; + } ); + + $dbh->do( q{ + DROP TABLE special_holidays; + } ); + SetVersion($DBversion); } diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc index 13dd061..916195c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc @@ -87,7 +87,7 @@
Additional tools
    [% IF ( CAN_user_tools_edit_calendar ) %] -
  • Calendar
  • +
  • Calendar
  • [% END %] [% IF ( CAN_user_tools_manage_csv_profiles ) %]
  • CSV profiles
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt index b952253..4acb1cd 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt @@ -5,7 +5,9 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] -[% INCLUDE 'datatables.inc' %] + +[% INCLUDE 'datatables-strings.inc' %] + - - [% event.title %] - [% event.description %] + + [% event.title %] + [% event.description %] [% IF event.closed %] Closed [% ELSIF event.close_hour == 24 %] Open [% ELSE %] - [% event.open_hour %]:[% event.open_minute > 10 ? event.open_minute : ( '0' _ event.open_minute) %] - + [% event.open_hour %]:[% event.open_minute > 10 ? event.open_minute : ( '0' _ event.open_minute) %] - [% event.close_hour %]:[% event.close_minute > 10 ? event.close_minute : ( '0' _ event.close_minute) %] [% END %] - [% END %] + [% END %] [% END %] @@ -531,20 +535,20 @@ li.hoursentry input { [% FOREACH event IN yearly_events %] [% event.month_day_sort %] - [% event.title %] - [% event.description %] + [% event.title %] + [% event.description %] [% IF event.closed %] Closed [% ELSIF event.close_hour == 24 %] Open [% ELSE %] - [% event.open_hour %]:[% event.open_minute > 10 ? event.open_minute : ( '0' _ event.open_minute) %] - + [% event.open_hour %]:[% event.open_minute > 10 ? event.open_minute : ( '0' _ event.open_minute) %] - [% event.close_hour %]:[% event.close_minute > 10 ? event.close_minute : ( '0' _ event.close_minute) %] [% END %] - [% END %] + [% END %] [% END %] @@ -572,12 +576,12 @@ li.hoursentry input { [% ELSIF event.close_hour == 24 %] Open [% ELSE %] - [% event.open_hour %]:[% event.open_minute > 10 ? event.open_minute : ( '0' _ event.open_minute) %] - + [% event.open_hour %]:[% event.open_minute > 10 ? event.open_minute : ( '0' _ event.open_minute) %] - [% event.close_hour %]:[% event.close_minute > 10 ? event.close_minute : ( '0' _ event.close_minute) %] [% END %] - [% END %] + [% END %] [% END %] diff --git a/misc/cronjobs/staticfines.pl b/misc/cronjobs/staticfines.pl index 2f3d86c..779678d 100755 --- a/misc/cronjobs/staticfines.pl +++ b/misc/cronjobs/staticfines.pl @@ -176,7 +176,7 @@ for ( my $i = 0 ; $i < scalar(@$data) ; $i++ ) { $calendars{$branchcode} = Koha::Calendar->new( branchcode => $branchcode ); } $calendar = $calendars{$branchcode}; - my $isHoliday = $calendar->is_holiday( DateTime->new( + my $isHoliday = $calendar->is_holiday( DateTime->new( year => $tyear, month => $tmonth, day => $tday diff --git a/t/Calendar.t b/t/Calendar.t index 8c30c77..31e036a 100755 --- a/t/Calendar.t +++ b/t/Calendar.t @@ -4,13 +4,15 @@ use strict; use warnings; use DateTime; use DateTime::Duration; -use Test::More tests => 34; +use Test::More tests => 51; use Test::MockModule; use DBD::Mock; use Koha::DateUtils; BEGIN { use_ok('Koha::Calendar'); + use Carp; + $SIG{ __DIE__ } = sub { Carp::confess( @_ ) }; } my $module_context = new Test::MockModule('C4::Context'); @@ -38,38 +40,55 @@ SKIP: { skip "DBD::Mock is too old", 33 unless $DBD::Mock::VERSION >= 1.45; +# Apologies for strange indentation, DBD::Mock is picky my $holidays_session = DBD::Mock::Session->new('holidays_session' => ( { # weekly holidays - statement => "SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL", + statement => q{ + SELECT + weekday, open_hour, open_minute, close_hour, close_minute, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_repeats + WHERE branchcode = ? AND weekday IS NOT NULL + }, results => [ - ['weekday'], - [0], # sundays - [6] # saturdays + ['weekday', 'open_hour', 'open_minute', 'close_hour', 'close_minute', 'closed'], + [0, 0, 0, 0, 0, 1], # sundays + [1,10, 0,19, 0, 0], # mondays + [2,10, 0,19, 0, 0], # tuesdays + [6, 0, 0, 0, 0, 1] # saturdays ] }, { # day and month repeatable holidays - statement => "SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL", + statement => q{ + SELECT + month, day, open_hour, open_minute, close_hour, close_minute, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_repeats + WHERE branchcode = ? AND weekday IS NULL + }, results => [ - [ 'month', 'day' ], - [ 1, 1 ], # new year's day - [12,25] # christmas + [ 'month', 'day', 'open_hour', 'open_minute', 'close_hour', 'close_minute', 'closed' ], + [ 1, 1, 0, 0, 0, 0, 1], # new year's day + [ 6,26,10, 0,15, 0, 0], # wednesdays + [12,25, 0, 0, 0, 0, 1] # christmas ] }, { # exception holidays - statement => "SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 1", - results => [ - [ 'day', 'month', 'year' ], - [ 11, 11, 2012 ] # sunday exception - ] + statement => q{ + SELECT + event_date, open_hour, open_minute, close_hour, close_minute, + (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed + FROM calendar_events + WHERE branchcode = ? }, - { # single holidays - statement => "SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 0", results => [ - [ 'day', 'month', 'year' ], - [ 1, 6, 2011 ], # single holiday - [ 4, 7, 2012 ] + [ 'event_date', 'open_hour', 'open_minute', 'close_hour', 'close_minute', 'closed' ], + [ '2012-11-11', 0, 0,24, 0, 0 ], # sunday exception + [ '2011-06-01', 0, 0, 0, 0, 1 ], # single holiday + [ '2012-07-04', 0, 0, 0, 0, 1 ], + [ '2014-06-26',12, 0,14, 0, 0 ] ] - } + }, )); # Initialize the global $dbh variable @@ -189,6 +208,22 @@ my $day_after_christmas = DateTime->new( minute => 53, ); + my $same_day_dt = DateTime->new( # Monday + year => 2012, + month => 7, + day => 23, + hour => 13, + minute => 53, + ); + + my $after_close_dt = DateTime->new( # Monday + year => 2012, + month => 7, + day => 23, + hour => 22, + minute => 53, + ); + my $later_dt = DateTime->new( # Monday year => 2012, month => 9, @@ -232,13 +267,41 @@ my $day_after_christmas = DateTime->new( is( $cal->addDate($day_after_christmas, -1, 'days')->ymd(), '2012-12-24', 'Negative call to addDate (Datedue)' ); + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -10 ), 'hours' ),'eq', + '2012-07-20T15:53:00', + 'Subtract 10 hours (Datedue)' ); + + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 10 ), 'hours' ),'eq', + '2012-07-24T12:53:00', + 'Add 10 hours (Datedue)' ); + + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -1 ), 'hours' ),'eq', + '2012-07-23T10:53:00', + 'Subtract 1 hours (Datedue)' ); + + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 1 ), 'hours' ),'eq', + '2012-07-23T12:53:00', + 'Add 1 hours (Datedue)' ); + ## Note that the days_between API says closed days are not considered. ## This tests are here as an API test. cmp_ok( $cal->days_between( $test_dt, $later_dt )->in_units('days'), - '==', 40, 'days_between calculates correctly (Days)' ); + '==', 40, 'days_between calculates correctly (Datedue)' ); cmp_ok( $cal->days_between( $later_dt, $test_dt )->in_units('days'), - '==', 40, 'Test parameter order not relevant (Days)' ); + '==', 40, 'Test parameter order not relevant (Datedue)' ); + + cmp_ok( $cal->hours_between( $test_dt, $same_day_dt )->in_units('hours'), + '==', 2, 'hours_between calculates correctly (short period)' ); + + cmp_ok( $cal->hours_between( $test_dt, $after_close_dt )->in_units('hours'), + '==', 7, 'hours_between calculates correctly (after close)' ); + + cmp_ok( $cal->hours_between( $test_dt, $later_dt )->in_units('hours'), + '==', 725, 'hours_between calculates correctly (Datedue)' ); + + cmp_ok( $cal->hours_between( $later_dt, $test_dt )->in_units('hours'), + '==', 725, 'hours_between parameter order not relevant (Datedue)' ); } @@ -274,11 +337,33 @@ my $day_after_christmas = DateTime->new( is( $cal->addDate($day_after_christmas, -1, 'days')->ymd(), '2012-12-24', 'Negative call to addDate (Calendar)' ); + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -10 ), 'hours' ),'eq', + '2012-07-23T10:00:00', + 'Subtract 10 hours (Calendar)' ); + + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 10 ), 'hours' ),'eq', + '2012-07-23T19:00:00', + 'Add 10 hours (Calendar)' ); + + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -1 ), 'hours' ),'eq', + '2012-07-23T10:53:00', + 'Subtract 1 hours (Calendar)' ); + + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 1 ), 'hours' ),'eq', + '2012-07-23T12:53:00', + 'Add 1 hours (Calendar)' ); + cmp_ok( $cal->days_between( $test_dt, $later_dt )->in_units('days'), '==', 40, 'days_between calculates correctly (Calendar)' ); cmp_ok( $cal->days_between( $later_dt, $test_dt )->in_units('days'), '==', 40, 'Test parameter order not relevant (Calendar)' ); + + cmp_ok( $cal->hours_between( $test_dt, $later_dt )->in_units('hours'), + '==', 725, 'hours_between calculates correctly (Calendar)' ); + + cmp_ok( $cal->hours_between( $later_dt, $test_dt )->in_units('hours'), + '==', 725, 'hours_between parameter order not relevant (Calendar)' ); } @@ -311,6 +396,10 @@ my $day_after_christmas = DateTime->new( is( $cal->addDate($day_after_christmas, -1, 'days')->ymd(), '2012-12-25', 'Negative call to addDate (Days)' ); + cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 10 ), 'hours' ),'eq', + '2012-07-23T21:53:00', + 'Add 10 hours (Days)' ); + ## Note that the days_between API says closed days are not considered. ## This tests are here as an API test. cmp_ok( $cal->days_between( $test_dt, $later_dt )->in_units('days'), @@ -319,6 +408,12 @@ my $day_after_christmas = DateTime->new( cmp_ok( $cal->days_between( $later_dt, $test_dt )->in_units('days'), '==', 40, 'Test parameter order not relevant (Days)' ); + cmp_ok( $cal->hours_between( $test_dt, $later_dt )->in_units('hours'), + '==', 725, 'hours_between calculates correctly (Days)' ); + + cmp_ok( $cal->hours_between( $later_dt, $test_dt )->in_units('hours'), + '==', 725, 'hours_between parameter order not relevant (Days)' ); + } } # End SKIP block diff --git a/t/db_dependent/Calendar.t b/t/db_dependent/Calendar.t index 162e09b..a55bb1d 100644 --- a/t/db_dependent/Calendar.t +++ b/t/db_dependent/Calendar.t @@ -1,86 +1,78 @@ use Modern::Perl; -use Test::More tests => 14; +use Test::More tests => 18; use C4::Calendar; -use C4::Context; -my $dbh = C4::Context->dbh; - -# Start transaction -$dbh->{AutoCommit} = 0; -$dbh->{RaiseError} = 1; - -my %new_holiday = ( open_hour => 0, +my $new_holiday = { open_hour => 0, open_minute => 0, close_hour => 0, close_minute => 0, title => 'example week_day_holiday', - description => 'This is an example week_day_holiday used for testing' ); + description => 'This is an example week_day_holiday used for testing' }; # Weekly events -ModRepeatingEvent( 'UPL', { weekday => 1, %new_holiday } ); +ModRepeatingEvent( 'MPL', 1, undef, undef, $new_holiday ); -my $weekly_events = GetWeeklyEvents( 'UPL' ); -is( $weekly_events->[0]->{'title'}, $new_holiday{'title'}, 'weekly title' ); -is( $weekly_events->[0]->{'description'}, $new_holiday{'description'}, 'weekly description' ); +my $weekly_events = GetWeeklyEvents( 'MPL' ); +is( $weekly_events->[0]->{'title'}, $new_holiday->{'title'}, 'weekly title' ); +is( $weekly_events->[0]->{'description'}, $new_holiday->{'description'}, 'weekly description' ); +is( $weekly_events->[0]->{'open_hour'}, 0, 'weekly open_hour' ); -$new_holiday{close_hour} = 24; +$new_holiday->{open_hour} = 7; -ModRepeatingEvent( 'UPL', { weekday => 1, %new_holiday } ); -$weekly_events = GetWeeklyEvents( 'UPL' ); -is( scalar @$weekly_events, 0, 'weekly modification, not insertion' ); +ModRepeatingEvent( 'MPL', 1, undef, undef, $new_holiday ); +$weekly_events = GetWeeklyEvents( 'MPL' ); +is( scalar @$weekly_events, 1, 'weekly modification, not insertion' ); +is( $weekly_events->[0]->{'open_hour'}, 7, 'weekly open_hour modified' ); -$new_holiday{close_hour} = 0; -ModRepeatingEvent( 'UPL', { weekday => 1, %new_holiday } ); # Yearly events -ModRepeatingEvent( 'UPL', { month => 6, day => 26, %new_holiday } ); +$new_holiday->{open_hour} = 0; +ModRepeatingEvent( 'MPL', undef, 6, 26, $new_holiday ); -my $yearly_events = GetYearlyEvents( 'UPL' ); -is( $yearly_events->[0]->{'title'}, $new_holiday{'title'}, 'yearly title' ); -is( $yearly_events->[0]->{'description'}, $new_holiday{'description'}, 'yearly description' ); +my $yearly_events = GetYearlyEvents( 'MPL' ); +is( $yearly_events->[0]->{'title'}, $new_holiday->{'title'}, 'yearly title' ); +is( $yearly_events->[0]->{'description'}, $new_holiday->{'description'}, 'yearly description' ); +is( $yearly_events->[0]->{'open_hour'}, 0, 'yearly open_hour' ); -$new_holiday{close_hour} = 24; +$new_holiday->{open_hour} = 8; -ModRepeatingEvent( 'UPL', { month => 6, day => 26, %new_holiday } ); -$yearly_events = GetYearlyEvents( 'UPL' ); -is( scalar @$yearly_events, 0, 'yearly modification, not insertion' ); - -$new_holiday{close_hour} = 0; -ModRepeatingEvent( 'UPL', { month => 6, day => 26, %new_holiday } ); +ModRepeatingEvent( 'MPL', undef, 6, 26, $new_holiday ); +$yearly_events = GetYearlyEvents( 'MPL' ); +is( scalar @$yearly_events, 1, 'yearly modification, not insertion' ); +is( $yearly_events->[0]->{'open_hour'}, 8, 'yearly open_hour' ); # Single events -ModSingleEvent( 'UPL', { date => '2013-03-17', %new_holiday } ); +$new_holiday->{open_hour} = 0; +ModSingleEvent( 'MPL', '2013-03-17', $new_holiday ); -my $single_events = GetSingleEvents( 'UPL' ); -is( $single_events->[0]->{'title'}, $new_holiday{'title'}, 'single title' ); -is( $single_events->[0]->{'description'}, $new_holiday{'description'}, 'single description' ); -is( $single_events->[0]->{'closed'}, 1, 'single closed' ); +my $single_events = GetSingleEvents( 'MPL' ); +is( $single_events->[0]->{'title'}, $new_holiday->{'title'}, 'single title' ); +is( $single_events->[0]->{'description'}, $new_holiday->{'description'}, 'single description' ); +is( $single_events->[0]->{'open_hour'}, 0, 'single open_hour' ); -$new_holiday{close_hour} = 24; +$new_holiday->{open_hour} = 11; -ModSingleEvent( 'UPL', { date => '2013-03-17', %new_holiday } ); -$single_events = GetSingleEvents( 'UPL' ); +ModSingleEvent( 'MPL', '2013-03-17', $new_holiday ); +$single_events = GetSingleEvents( 'MPL' ); is( scalar @$single_events, 1, 'single modification, not insertion' ); -is( $single_events->[0]->{'closed'}, 0, 'single closed' ); +is( $single_events->[0]->{'open_hour'}, 11, 'single open_hour' ); # delete -DelRepeatingEvent( 'UPL', { weekday => 1 } ); -$weekly_events = GetWeeklyEvents( 'UPL' ); +DelRepeatingEvent( 'MPL', 1, undef, undef ); +$weekly_events = GetWeeklyEvents( 'MPL' ); is( scalar @$weekly_events, 0, 'weekly deleted' ); -DelRepeatingEvent( 'UPL', { month => 6, day => 26 } ); -$yearly_events = GetYearlyEvents( 'UPL' ); +DelRepeatingEvent( 'MPL', undef, 6, 26 ); +$yearly_events = GetYearlyEvents( 'MPL' ); is( scalar @$yearly_events, 0, 'yearly deleted' ); -DelSingleEvent( 'UPL', { date => '2013-03-17' } ); +DelSingleEvent( 'MPL', '2013-03-17' ); -$single_events = GetSingleEvents( 'UPL' ); +$single_events = GetSingleEvents( 'MPL' ); is( scalar @$single_events, 0, 'single deleted' ); - -$dbh->rollback; diff --git a/tools/calendar.pl b/tools/calendar.pl index 0ba8f92..638a336 100755 --- a/tools/calendar.pl +++ b/tools/calendar.pl @@ -2,22 +2,22 @@ # This file is part of Koha. # -# 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. +# 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 2 of the License, or (at your option) any later +# version. # -# 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. +# 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 -# along with Koha; if not, see . +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA #####Sets holiday periods for each branch. Datedues will be extended if branch is closed -TG -use Modern::Perl; +use Modern::Perl '2009'; use CGI; @@ -55,13 +55,13 @@ unless($keydate = $calendarinput->output('iso')) { } $keydate =~ s/-/\//g; -my $branch= $input->param('branchName') || $input->param('branch') || C4::Context->userenv->{'branch'}; +my $branch= $input->param('branch') || C4::Context->userenv->{'branch'}; # Set all the branches. my $onlymine=(C4::Context->preference('IndependentBranches') && C4::Context->userenv && C4::Context->userenv->{flags} % 2 !=1 && C4::Context->userenv->{branch}?1:0); -if ( $onlymine ) { +if ( $onlymine ) { $branch = C4::Context->userenv->{'branch'}; } my $branchname = GetBranchName($branch); @@ -110,7 +110,7 @@ if ( $input->param( 'allBranches' ) || !$input->param( 'branchName' ) ) { if ( $op eq 'save' ) { my $date = $input->param( 'year' ) . '-' . $input->param( 'month' ) . '-' . $input->param( 'day' ); - local our ( $open_hour, $open_minute, $close_hour, $close_minute ); + my ( $open_hour, $open_minute, $close_hour, $close_minute ); if ( $input->param( 'hoursType' ) eq 'open' ) { ( $open_hour, $open_minute ) = ( 0, 0 ); @@ -124,10 +124,9 @@ if ( $op eq 'save' ) { } foreach my $branchcode ( @branches ) { - my %event_types = ( - 'single' => sub { - ModSingleEvent( $branchcode, { - date => $date, + given ( $input->param( 'eventType' ) ) { + when ( 'single' ) { + ModSingleEvent( $branchcode, $date, { title => $input->param( 'title' ), description => $input->param( 'description' ), open_hour => $open_hour, @@ -135,11 +134,10 @@ if ( $op eq 'save' ) { close_hour => $close_hour, close_minute => $close_minute } ); - }, + } - 'weekly' => sub { - ModRepeatingEvent( $branchcode, { - weekday => $input->param( 'weekday' ), + when ( 'weekly' ) { + ModRepeatingEvent( $branchcode, $input->param( 'weekday' ), undef, undef, { title => $input->param( 'title' ), description => $input->param( 'description' ), open_hour => $open_hour, @@ -147,12 +145,10 @@ if ( $op eq 'save' ) { close_hour => $close_hour, close_minute => $close_minute } ); - }, + } - 'yearly' => sub { - ModRepeatingEvent( $branchcode, { - month => $input->param( 'month' ), - day => $input->param( 'day' ), + when ( 'yearly' ) { + ModRepeatingEvent( $branchcode, undef, $input->param( 'month' ), $input->param( 'day' ), { title => $input->param( 'title' ), description => $input->param( 'description' ), open_hour => $open_hour, @@ -160,12 +156,11 @@ if ( $op eq 'save' ) { close_hour => $close_hour, close_minute => $close_minute } ); - }, + } - 'singlerange' => sub { + when ( 'singlerange' ) { foreach my $dt ( @ranged_dates ) { - ModSingleEvent( $branchcode, { - date => $dt->ymd, + ModSingleEvent( $branchcode, $dt->ymd, { title => $input->param( 'title' ), description => $input->param( 'description' ), open_hour => $open_hour, @@ -174,13 +169,11 @@ if ( $op eq 'save' ) { close_minute => $close_minute } ); } - }, + } - 'yearlyrange' => sub { + when ( 'yearlyrange' ) { foreach my $dt ( @ranged_dates ) { - ModRepeatingEvent( $branchcode, { - month => $dt->month, - day => $dt->day, + ModRepeatingEvent( $branchcode, undef, $dt->month, $dt->day, { title => $input->param( 'title' ), description => $input->param( 'description' ), open_hour => $open_hour, @@ -189,43 +182,37 @@ if ( $op eq 'save' ) { close_minute => $close_minute } ); } - }, - ); - - # Choose from the above options - $event_types{ $input->param( 'eventType' ) }->(); + } + } } } elsif ( $op eq 'delete' ) { my $date = $input->param( 'year' ) . '-' . $input->param( 'month' ) . '-' . $input->param( 'day' ); foreach my $branchcode ( @branches ) { - my %event_types = ( - 'single' => sub { - DelSingleEvent( $branchcode, { date => $date } ); - }, - - 'weekly' => sub { - DelRepeatingEvent( $branchcode, { weekday => $input->param( 'weekday' ) } ); - }, - - 'yearly' => sub { - DelRepeatingEvent( $branchcode, { month => $input->param( 'month' ), day => $input->param( 'day' ) } ); - }, - ); - - # Choose from the above options - $event_types{ $input->param( 'eventType' ) }->(); + given ( $input->param( 'eventType' ) ) { + when ( 'single' ) { + DelSingleEvent( $branchcode, $date ); + } + + when ( 'weekly' ) { + DelRepeatingEvent( $branchcode, $input->param( 'weekday' ), undef, undef ); + } + + when ( 'yearly' ) { + DelRepeatingEvent( $branchcode, undef, $input->param( 'month' ), $input->param( 'day' ) ); + } + } } } elsif ( $op eq 'deleterange' ) { foreach my $branchcode ( @branches ) { foreach my $dt ( @ranged_dates ) { - DelSingleEvent( $branchcode, { date => $dt->ymd } ); + DelSingleEvent( $branchcode, $dt->ymd ); } } } elsif ( $op eq 'deleterangerepeat' ) { foreach my $branchcode ( @branches ) { foreach my $dt ( @ranged_dates ) { - DelRepeatingEvent( $branchcode, { month => $dt->month, day => $dt->day } ); + DelRepeatingEvent( $branchcode, undef, $dt->month, $dt->day ); } } } elsif ( $op eq 'copyall' ) { -- 1.9.1