Bugzilla – Attachment 33895 Details for
Bug 11211
Move calculation code out of C4::Calendar
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 11211 - Move calculation code out of C4::Calendar
Bug-11211---Move-calculation-code-out-of-C4Calenda.patch (text/plain), 139.47 KB, created by
Kyle M Hall (khall)
on 2014-11-25 12:43:11 UTC
(
hide
)
Description:
Bug 11211 - Move calculation code out of C4::Calendar
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2014-11-25 12:43:11 UTC
Size:
139.47 KB
patch
obsolete
>From 32d41249a9c285e78517ac625276351e95030491 Mon Sep 17 00:00:00 2001 >From: Jesse Weaver <pianohacker@gmail.com> >Date: Tue, 28 Jan 2014 18:32:04 -0700 >Subject: [PATCH] Bug 11211 - Move calculation code out of C4::Calendar > >This patch moves the calculation code out of C4::Calendar, replacing any >references to it with Koha::Calendar. Additionally, it moves the >administration interface to a single script, tools/calendar.pl. > >NOTE: This is intended as a bridge to bug 8133, so the UI is a bit >awkward, and C4::Calendar has an API designed for adding hours to the >calendar. All features should still work, and 8133 will make things >better. > >Test plan: > 1) Install the new dependency, Template::Plugin::JavaScript. > 2) prove t/db_dependent/Calendar.t t/db_dependent/Holidays.t to verify > that the new C4::Calendar API works correctly. > 3) prove t/Calendar.t > 4) Add, remove and modify events of each type using the administrative > interface. In this version, changing a repeating event to "Open" > deletes it. > 5) Check out items to verify that the calculation code is using the > events you just created. > 6) If possible, verify that the two affected cronjobs still function > correctly. >--- > C4/Calendar.pm | 773 ++++---------------- > C4/Circulation.pm | 87 --- > C4/Installer/PerlDependencies.pm | 5 + > C4/Overdues.pm | 124 ---- > Koha/Calendar.pm | 27 +- > .../intranet-tmpl/prog/en/includes/tools-menu.inc | 2 +- > .../prog/en/modules/tools/calendar.tt | 594 +++++++++++++++ > .../prog/en/modules/tools/holidays.tt | 537 -------------- > .../prog/en/modules/tools/tools-home.tt | 2 +- > misc/cronjobs/staticfines.pl | 11 +- > .../thirdparty/TalkingTech_itiva_outbound.pl | 31 +- > t/Calendar.t | 6 +- > t/db_dependent/Calendar.t | 86 +++ > t/db_dependent/Holidays.t | 29 +- > tools/calendar.pl | 268 +++++++ > tools/copy-holidays.pl | 39 - > tools/exceptionHolidays.pl | 145 ---- > tools/holidays.pl | 164 ----- > tools/newHolidays.pl | 144 ---- > 19 files changed, 1138 insertions(+), 1936 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt > delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt > create mode 100644 t/db_dependent/Calendar.t > create mode 100755 tools/calendar.pl > delete mode 100755 tools/copy-holidays.pl > delete mode 100755 tools/exceptionHolidays.pl > delete mode 100755 tools/holidays.pl > delete mode 100755 tools/newHolidays.pl > >diff --git a/C4/Calendar.pm b/C4/Calendar.pm >index 1e687db..dee183d 100644 >--- a/C4/Calendar.pm >+++ b/C4/Calendar.pm >@@ -15,712 +15,250 @@ package C4::Calendar; > # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, > # Suite 330, Boston, MA 02111-1307 USA > >-use strict; >-use warnings; >+use Modern::Perl; > use vars qw($VERSION @EXPORT); > > use Carp; >-use Date::Calc qw( Date_to_Days Today); > >-use C4::Context; >+use Koha::Database; >+ >+our ( @ISA, @EXPORT ); >+ >+BEGIN { >+ @ISA = qw( Exporter ); >+ @EXPORT = qw( >+ GetSingleEvents >+ GetWeeklyEvents >+ GetYearlyEvents >+ ModSingleEvent >+ ModRepeatingEvent >+ DelSingleEvent >+ DelRepeatingEvent >+ CopyAllEvents >+ ); >+} > > use constant ISO_DATE_FORMAT => "%04d-%02d-%02d"; > =head1 NAME > >-C4::Calendar::Calendar - Koha module dealing with holidays. >+C4::Calendar - Koha module dealing with holidays. > > =head1 SYNOPSIS > >- use C4::Calendar::Calendar; >+ use C4::Calendar; > > =head1 DESCRIPTION > >-This package is used to deal with holidays. Through this package, you can set >-all kind of holidays for the library. >+This package is used to deal with hours and holidays; > > =head1 FUNCTIONS > >-=head2 new >- >- $calendar = C4::Calendar->new(branchcode => $branchcode); >- >-Each library branch has its own Calendar. >-C<$branchcode> specifies which Calendar you want. >- >-=cut >- >-sub new { >- my $classname = shift @_; >- my %options = @_; >- my $self = bless({}, $classname); >- foreach my $optionName (keys %options) { >- $self->{lc($optionName)} = $options{$optionName}; >- } >- defined($self->{branchcode}) or croak "No branchcode argument to new. Should be C4::Calendar->new(branchcode => \$branchcode)"; >- $self->_init($self->{branchcode}); >- return $self; >-} >- >-sub _init { >- my $self = shift @_; >- my $branch = shift; >- defined($branch) or die "No branchcode sent to _init"; # must test for defined here and above to allow "" >- my $dbh = C4::Context->dbh(); >- my $repeatable = $dbh->prepare( 'SELECT * >- FROM repeatable_holidays >- WHERE ( branchcode = ? ) >- AND (ISNULL(weekday) = ?)' ); >- $repeatable->execute($branch,0); >- my %week_days_holidays; >- while (my $row = $repeatable->fetchrow_hashref) { >- my $key = $row->{weekday}; >- $week_days_holidays{$key}{title} = $row->{title}; >- $week_days_holidays{$key}{description} = $row->{description}; >- } >- $self->{'week_days_holidays'} = \%week_days_holidays; >- >- $repeatable->execute($branch,1); >- my %day_month_holidays; >- while (my $row = $repeatable->fetchrow_hashref) { >- my $key = $row->{month} . "/" . $row->{day}; >- $day_month_holidays{$key}{title} = $row->{title}; >- $day_month_holidays{$key}{description} = $row->{description}; >- $day_month_holidays{$key}{day} = sprintf("%02d", $row->{day}); >- $day_month_holidays{$key}{month} = sprintf("%02d", $row->{month}); >- } >- $self->{'day_month_holidays'} = \%day_month_holidays; >- >- my $special = $dbh->prepare( 'SELECT day, month, year, title, description >- FROM special_holidays >- WHERE ( branchcode = ? ) >- AND (isexception = ?)' ); >- $special->execute($branch,1); >- my %exception_holidays; >- while (my ($day, $month, $year, $title, $description) = $special->fetchrow) { >- $exception_holidays{"$year/$month/$day"}{title} = $title; >- $exception_holidays{"$year/$month/$day"}{description} = $description; >- $exception_holidays{"$year/$month/$day"}{date} = >- sprintf(ISO_DATE_FORMAT, $year, $month, $day); >- } >- $self->{'exception_holidays'} = \%exception_holidays; >- >- $special->execute($branch,0); >- my %single_holidays; >- while (my ($day, $month, $year, $title, $description) = $special->fetchrow) { >- $single_holidays{"$year/$month/$day"}{title} = $title; >- $single_holidays{"$year/$month/$day"}{description} = $description; >- $single_holidays{"$year/$month/$day"}{date} = >- sprintf(ISO_DATE_FORMAT, $year, $month, $day); >- } >- $self->{'single_holidays'} = \%single_holidays; >- return $self; >-} >- >-=head2 get_week_days_holidays >- >- $week_days_holidays = $calendar->get_week_days_holidays(); >- >-Returns a hash reference to week days holidays. >- >-=cut >- >-sub get_week_days_holidays { >- my $self = shift @_; >- my $week_days_holidays = $self->{'week_days_holidays'}; >- return $week_days_holidays; >-} >- >-=head2 get_day_month_holidays >- >- $day_month_holidays = $calendar->get_day_month_holidays(); >- >-Returns a hash reference to day month holidays. >- >-=cut >- >-sub get_day_month_holidays { >- my $self = shift @_; >- my $day_month_holidays = $self->{'day_month_holidays'}; >- return $day_month_holidays; >-} >- >-=head2 get_exception_holidays >- >- $exception_holidays = $calendar->exception_holidays(); >- >-Returns a hash reference to exception holidays. This kind of days are those >-which stands for a holiday, but you wanted to make an exception for this particular >-date. >- >-=cut >- >-sub get_exception_holidays { >- my $self = shift @_; >- my $exception_holidays = $self->{'exception_holidays'}; >- return $exception_holidays; >-} >- >-=head2 get_single_holidays >- >- $single_holidays = $calendar->get_single_holidays(); >- >-Returns a hash reference to single holidays. This kind of holidays are those which >-happend just one time. >+=head2 GetSingleEvents > >-=cut >- >-sub get_single_holidays { >- my $self = shift @_; >- my $single_holidays = $self->{'single_holidays'}; >- return $single_holidays; >-} >- >-=head2 insert_week_day_holiday >- >- insert_week_day_holiday(weekday => $weekday, >- title => $title, >- description => $description); >+ \@events = GetSingleEvents( $branchcode ) > >-Inserts a new week day for $self->{branchcode}. >- >-C<$day> Is the week day to make holiday. >- >-C<$title> Is the title to store for the holiday formed by $year/$month/$day. >- >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >+Get the non-repeating events for the given library. > > =cut > >-sub insert_week_day_holiday { >- my $self = shift @_; >- my %options = @_; >- >- my $weekday = $options{weekday}; >- croak "Invalid weekday $weekday" unless $weekday =~ m/^[0-6]$/; >- >- my $dbh = C4::Context->dbh(); >- my $insertHoliday = $dbh->prepare("insert into repeatable_holidays (id,branchcode,weekday,day,month,title,description) values ( '',?,?,NULL,NULL,?,? )"); >- $insertHoliday->execute( $self->{branchcode}, $weekday, $options{title}, $options{description}); >- $self->{'week_days_holidays'}->{$weekday}{title} = $options{title}; >- $self->{'week_days_holidays'}->{$weekday}{description} = $options{description}; >- return $self; >+sub GetSingleEvents { >+ my ( $branchcode ) = @_; >+ >+ 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 >+ WHERE branchcode = ? >+ }, { Slice => {} }, $branchcode ); > } > >-=head2 insert_day_month_holiday >+=head2 GetWeeklyEvents > >- insert_day_month_holiday(day => $day, >- month => $month, >- title => $title, >- description => $description); >+ \@events = GetWeeklyEvents( $branchcode ) > >-Inserts a new day month holiday for $self->{branchcode}. >- >-C<$day> Is the day month to make the date to insert. >- >-C<$month> Is month to make the date to insert. >- >-C<$title> Is the title to store for the holiday formed by $year/$month/$day. >- >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >+Get the weekly-repeating events for the given library. > > =cut > >-sub insert_day_month_holiday { >- my $self = shift @_; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $insertHoliday = $dbh->prepare("insert into repeatable_holidays (id,branchcode,weekday,day,month,title,description) values ('', ?, NULL, ?, ?, ?,? )"); >- $insertHoliday->execute( $self->{branchcode}, $options{day},$options{month},$options{title}, $options{description}); >- $self->{'day_month_holidays'}->{"$options{month}/$options{day}"}{title} = $options{title}; >- $self->{'day_month_holidays'}->{"$options{month}/$options{day}"}{description} = $options{description}; >- return $self; >-} >- >-=head2 insert_single_holiday >- >- insert_single_holiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- >-Inserts a new single holiday for $self->{branchcode}. >+sub GetWeeklyEvents { >+ my ( $branchcode ) = @_; > >-C<$day> Is the day month to make the date to insert. >- >-C<$month> Is month to make the date to insert. >- >-C<$year> Is year to make the date to insert. >- >-C<$title> Is the title to store for the holiday formed by $year/$month/$day. >- >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >- >-=cut >- >-sub insert_single_holiday { >- my $self = shift @_; >- my %options = @_; >- >- @options{qw(year month day)} = ( $options{date} =~ m/(\d+)-(\d+)-(\d+)/o ) >- if $options{date} && !$options{day}; >- >- my $dbh = C4::Context->dbh(); >- my $isexception = 0; >- my $insertHoliday = $dbh->prepare("insert into special_holidays (id,branchcode,day,month,year,isexception,title,description) values ('', ?,?,?,?,?,?,?)"); >- $insertHoliday->execute( $self->{branchcode}, $options{day},$options{month},$options{year}, $isexception, $options{title}, $options{description}); >- $self->{'single_holidays'}->{"$options{year}/$options{month}/$options{day}"}{title} = $options{title}; >- $self->{'single_holidays'}->{"$options{year}/$options{month}/$options{day}"}{description} = $options{description}; >- return $self; >+ 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 >+ WHERE branchcode = ? AND weekday IS NOT NULL >+ }, { Slice => {} }, $branchcode ); > } > >-=head2 insert_exception_holiday >- >- insert_exception_holiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- >-Inserts a new exception holiday for $self->{branchcode}. >- >-C<$day> Is the day month to make the date to insert. >+=head2 GetYearlyEvents > >-C<$month> Is month to make the date to insert. >+ \@events = GetYearlyEvents( $branchcode ) > >-C<$year> Is year to make the date to insert. >- >-C<$title> Is the title to store for the holiday formed by $year/$month/$day. >- >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >+Get the yearly-repeating events for the given library. > > =cut > >-sub insert_exception_holiday { >- my $self = shift @_; >- my %options = @_; >- >- @options{qw(year month day)} = ( $options{date} =~ m/(\d+)-(\d+)-(\d+)/o ) >- if $options{date} && !$options{day}; >+sub GetYearlyEvents { >+ my ( $branchcode ) = @_; > >- my $dbh = C4::Context->dbh(); >- my $isexception = 1; >- my $insertException = $dbh->prepare("insert into special_holidays (id,branchcode,day,month,year,isexception,title,description) values ('', ?,?,?,?,?,?,?)"); >- $insertException->execute( $self->{branchcode}, $options{day},$options{month},$options{year}, $isexception, $options{title}, $options{description}); >- $self->{'exception_holidays'}->{"$options{year}/$options{month}/$options{day}"}{title} = $options{title}; >- $self->{'exception_holidays'}->{"$options{year}/$options{month}/$options{day}"}{description} = $options{description}; >- return $self; >+ 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 >+ WHERE branchcode = ? AND weekday IS NULL >+ }, { Slice => {} }, $branchcode ); > } > >-=head2 ModWeekdayholiday >- >- ModWeekdayholiday(weekday =>$weekday, >- title => $title, >- description => $description) >- >-Modifies the title and description of a weekday for $self->{branchcode}. >+=head2 ModSingleEvent > >-C<$weekday> Is the title to update for the holiday. >+ ModSingleEvent( $branchcode, \%info ) > >-C<$description> Is the description to update for the holiday. >+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. > > =cut > >-sub ModWeekdayholiday { >- my $self = shift @_; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $updateHoliday = $dbh->prepare("UPDATE repeatable_holidays SET title = ?, description = ? WHERE branchcode = ? AND weekday = ?"); >- $updateHoliday->execute( $options{title},$options{description},$self->{branchcode},$options{weekday}); >- $self->{'week_days_holidays'}->{$options{weekday}}{title} = $options{title}; >- $self->{'week_days_holidays'}->{$options{weekday}}{description} = $options{description}; >- return $self; >-} >- >-=head2 ModDaymonthholiday >- >- ModDaymonthholiday(day => $day, >- month => $month, >- title => $title, >- description => $description); >+sub ModSingleEvent { >+ my ( $branchcode, $info ) = @_; > >-Modifies the title and description for a day/month holiday for $self->{branchcode}. >+ my ( $year, $month, $day ) = ( $info->{date} =~ /(\d+)-(\d+)-(\d+)/ ); >+ return unless ( $year && $month && $day ); > >-C<$day> The day of the month for the update. >+ my $dbh = C4::Context->dbh; >+ my @args = ( ( map { $info->{$_} } qw(title description) ), $info->{close_hour} != 0, $branchcode, $year, $month, $day ); > >-C<$month> The month to be used for the update. >+ # 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 ); > >-C<$title> The title to be updated for the holiday. >- >-C<$description> The description to be update for the holiday. >- >-=cut >- >-sub ModDaymonthholiday { >- my $self = shift @_; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $updateHoliday = $dbh->prepare("UPDATE repeatable_holidays SET title = ?, description = ? WHERE month = ? AND day = ? AND branchcode = ?"); >- $updateHoliday->execute( $options{title},$options{description},$options{month},$options{day},$self->{branchcode}); >- $self->{'day_month_holidays'}->{"$options{month}/$options{day}"}{title} = $options{title}; >- $self->{'day_month_holidays'}->{"$options{month}/$options{day}"}{description} = $options{description}; >- return $self; >+ $dbh->do( q{ >+ INSERT >+ INTO special_holidays(title, description, isexception, branchcode, year, month, day) >+ VALUES (?, ?, ?, ?, ?, ?, ?) >+ }, {}, @args ) unless ( $affected > 0 ); > } > >-=head2 ModSingleholiday >- >- ModSingleholiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- >-Modifies the title and description for a single holiday for $self->{branchcode}. >- >-C<$day> Is the day of the month to make the update. >- >-C<$month> Is the month to make the update. >- >-C<$year> Is the year to make the update. >+=head2 ModRepeatingEvent > >-C<$title> Is the title to update for the holiday formed by $year/$month/$day. >+ ModRepeatingEvent( $branchcode, \%info ) > >-C<$description> Is the description to update for the holiday formed by $year/$month/$day. >+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. > > =cut > >-sub ModSingleholiday { >- my $self = shift @_; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $isexception = 0; >- my $updateHoliday = $dbh->prepare("UPDATE special_holidays SET title = ?, description = ? WHERE day = ? AND month = ? AND year = ? AND branchcode = ? AND isexception = ?"); >- $updateHoliday->execute($options{title},$options{description},$options{day},$options{month},$options{year},$self->{branchcode},$isexception); >- $self->{'single_holidays'}->{"$options{year}/$options{month}/$options{day}"}{title} = $options{title}; >- $self->{'single_holidays'}->{"$options{year}/$options{month}/$options{day}"}{description} = $options{description}; >- return $self; >-} >- >-=head2 ModExceptionholiday >- >- ModExceptionholiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- >-Modifies the title and description for an exception holiday for $self->{branchcode}. >- >-C<$day> Is the day of the month for the holiday. >- >-C<$month> Is the month for the holiday. >- >-C<$year> Is the year for the holiday. >- >-C<$title> Is the title to be modified for the holiday formed by $year/$month/$day. >- >-C<$description> Is the description to be modified for the holiday formed by $year/$month/$day. >+sub _get_compare { >+ my ( $colname, $value ) = @_; > >-=cut >- >-sub ModExceptionholiday { >- my $self = shift @_; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $isexception = 1; >- my $updateHoliday = $dbh->prepare("UPDATE special_holidays SET title = ?, description = ? WHERE day = ? AND month = ? AND year = ? AND branchcode = ? AND isexception = ?"); >- $updateHoliday->execute($options{title},$options{description},$options{day},$options{month},$options{year},$self->{branchcode},$isexception); >- $self->{'exception_holidays'}->{"$options{year}/$options{month}/$options{day}"}{title} = $options{title}; >- $self->{'exception_holidays'}->{"$options{year}/$options{month}/$options{day}"}{description} = $options{description}; >- return $self; >+ return ' AND ' . $colname . ' ' . ( defined( $value ) ? '=' : 'IS' ) . ' ?'; > } > >-=head2 delete_holiday >- >- delete_holiday(weekday => $weekday >- day => $day, >- month => $month, >- year => $year); >- >-Delete a holiday for $self->{branchcode}. >- >-C<$weekday> Is the week day to delete. >+sub ModRepeatingEvent { >+ my ( $branchcode, $info ) = @_; > >-C<$day> Is the day month to make the date to delete. >+ my $dbh = C4::Context->dbh; >+ my $open = ( $info->{close_hour} != 0 ); > >-C<$month> Is month to make the date to delete. >- >-C<$year> Is year to make the date to delete. >- >-=cut >- >-sub delete_holiday { >- my $self = shift @_; >- my %options = @_; >- >- # Verify what kind of holiday that day is. For example, if it is >- # a repeatable holiday, this should check if there are some exception >- # for that holiday rule. Otherwise, if it is a regular holiday, it´s >- # ok just deleting it. >- >- my $dbh = C4::Context->dbh(); >- my $isSingleHoliday = $dbh->prepare("SELECT id FROM special_holidays WHERE (branchcode = ?) AND (day = ?) AND (month = ?) AND (year = ?)"); >- $isSingleHoliday->execute($self->{branchcode}, $options{day}, $options{month}, $options{year}); >- if ($isSingleHoliday->rows) { >- my $id = $isSingleHoliday->fetchrow; >- $isSingleHoliday->finish; # Close the last query >- >- my $deleteHoliday = $dbh->prepare("DELETE FROM special_holidays WHERE id = ?"); >- $deleteHoliday->execute($id); >- delete($self->{'single_holidays'}->{"$options{year}/$options{month}/$options{day}"}); >+ 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 { >- $isSingleHoliday->finish; # Close the last query >- >- my $isWeekdayHoliday = $dbh->prepare("SELECT id FROM repeatable_holidays WHERE branchcode = ? AND weekday = ?"); >- $isWeekdayHoliday->execute($self->{branchcode}, $options{weekday}); >- if ($isWeekdayHoliday->rows) { >- my $id = $isWeekdayHoliday->fetchrow; >- $isWeekdayHoliday->finish; # Close the last query >- >- my $updateExceptions = $dbh->prepare("UPDATE special_holidays SET isexception = 0 WHERE (WEEKDAY(CONCAT(special_holidays.year,'-',special_holidays.month,'-',special_holidays.day)) = ?) AND (branchcode = ?)"); >- $updateExceptions->execute($options{weekday}, $self->{branchcode}); >- $updateExceptions->finish; # Close the last query >- >- my $deleteHoliday = $dbh->prepare("DELETE FROM repeatable_holidays WHERE id = ?"); >- $deleteHoliday->execute($id); >- delete($self->{'week_days_holidays'}->{$options{weekday}}); >- } else { >- $isWeekdayHoliday->finish; # Close the last query >- >- my $isDayMonthHoliday = $dbh->prepare("SELECT id FROM repeatable_holidays WHERE (branchcode = ?) AND (day = ?) AND (month = ?)"); >- $isDayMonthHoliday->execute($self->{branchcode}, $options{day}, $options{month}); >- if ($isDayMonthHoliday->rows) { >- my $id = $isDayMonthHoliday->fetchrow; >- $isDayMonthHoliday->finish; >- my $updateExceptions = $dbh->prepare("UPDATE special_holidays SET isexception = 0 WHERE (special_holidays.branchcode = ?) AND (special_holidays.day = ?) and (special_holidays.month = ?)"); >- $updateExceptions->execute($self->{branchcode}, $options{day}, $options{month}); >- $updateExceptions->finish; # Close the last query >- >- my $deleteHoliday = $dbh->prepare("DELETE FROM repeatable_holidays WHERE (id = ?)"); >- $deleteHoliday->execute($id); >- delete($self->{'day_month_holidays'}->{"$options{month}/$options{day}"}); >- } >- } >+ 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 ); > } >- return $self; >-} >-=head2 delete_holiday_range >- >- delete_holiday_range(day => $day, >- month => $month, >- year => $year); >- >-Delete a holiday range of dates for $self->{branchcode}. >- >-C<$day> Is the day month to make the date to delete. >- >-C<$month> Is month to make the date to delete. >- >-C<$year> Is year to make the date to delete. >- >-=cut >- >-sub delete_holiday_range { >- my $self = shift; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $sth = $dbh->prepare("DELETE FROM special_holidays WHERE (branchcode = ?) AND (day = ?) AND (month = ?) AND (year = ?)"); >- $sth->execute($self->{branchcode}, $options{day}, $options{month}, $options{year}); > } > >-=head2 delete_holiday_range_repeatable >+=head2 DelSingleEvent > >- delete_holiday_range_repeatable(day => $day, >- month => $month); >+ DelSingleEvent( $branchcode, \%info ) > >-Delete a holiday for $self->{branchcode}. >- >-C<$day> Is the day month to make the date to delete. >- >-C<$month> Is month to make the date to delete. >+Deletes an event for a single date. $info->{date} should be an ISO-formatted date string. > > =cut > >-sub delete_holiday_range_repeatable { >- my $self = shift; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $sth = $dbh->prepare("DELETE FROM repeatable_holidays WHERE (branchcode = ?) AND (day = ?) AND (month = ?)"); >- $sth->execute($self->{branchcode}, $options{day}, $options{month}); >-} >- >-=head2 delete_exception_holiday_range >+sub DelSingleEvent { >+ my ( $branchcode, $info ) = @_; > >- delete_exception_holiday_range(weekday => $weekday >- day => $day, >- month => $month, >- year => $year); >+ my ( $year, $month, $day ) = ( $info->{date} =~ /(\d+)-(\d+)-(\d+)/ ); >+ return unless ( $year && $month && $day ); > >-Delete a holiday for $self->{branchcode}. >- >-C<$day> Is the day month to make the date to delete. >- >-C<$month> Is month to make the date to delete. >- >-C<$year> Is year to make the date to delete. >- >-=cut >- >-sub delete_exception_holiday_range { >- my $self = shift; >- my %options = @_; >- >- my $dbh = C4::Context->dbh(); >- my $sth = $dbh->prepare("DELETE FROM special_holidays WHERE (branchcode = ?) AND (isexception = 1) AND (day = ?) AND (month = ?) AND (year = ?)"); >- $sth->execute($self->{branchcode}, $options{day}, $options{month}, $options{year}); >+ C4::Context->dbh->do( q{ >+ DELETE FROM special_holidays >+ WHERE branchcode = ? AND year = ? AND month = ? AND day = ? >+ }, {}, $branchcode, $year, $month, $day ); > } > >-=head2 isHoliday >- >- $isHoliday = isHoliday($day, $month $year); >- >-C<$day> Is the day to check whether if is a holiday or not. >- >-C<$month> Is the month to check whether if is a holiday or not. >- >-C<$year> Is the year to check whether if is a holiday or not. >- >-=cut >- >-sub isHoliday { >- my ($self, $day, $month, $year) = @_; >- # FIXME - date strings are stored in non-padded metric format. should change to iso. >- # FIXME - should change arguments to accept C4::Dates object >- $month=$month+0; >- $year=$year+0; >- $day=$day+0; >- my $weekday = &Date::Calc::Day_of_Week($year, $month, $day) % 7; >- my $weekDays = $self->get_week_days_holidays(); >- my $dayMonths = $self->get_day_month_holidays(); >- my $exceptions = $self->get_exception_holidays(); >- my $singles = $self->get_single_holidays(); >- if (defined($exceptions->{"$year/$month/$day"})) { >- return 0; >- } else { >- if ((exists($weekDays->{$weekday})) || >- (exists($dayMonths->{"$month/$day"})) || >- (exists($singles->{"$year/$month/$day"}))) { >- return 1; >- } else { >- return 0; >- } >- } >+=head2 DelRepeatingEvent > >-} >+ DelRepeatingEvent( $branchcode, \%info ) > >-=head2 copy_to_branch >- >- $calendar->copy_to_branch($target_branch) >+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. > > =cut > >-sub copy_to_branch { >- my ($self, $target_branch) = @_; >- >- croak "No target_branch" unless $target_branch; >+sub DelRepeatingEvent { >+ my ( $branchcode, $info ) = @_; > >- my $target_calendar = C4::Calendar->new(branchcode => $target_branch); >- >- my ($y, $m, $d) = Today(); >- my $today = sprintf ISO_DATE_FORMAT, $y,$m,$d; >- >- my $wdh = $self->get_week_days_holidays; >- $target_calendar->insert_week_day_holiday( weekday => $_, %{ $wdh->{$_} } ) >- foreach keys %$wdh; >- $target_calendar->insert_day_month_holiday(%$_) >- foreach values %{ $self->get_day_month_holidays }; >- $target_calendar->insert_exception_holiday(%$_) >- foreach grep { $_->{date} gt $today } values %{ $self->get_exception_holidays }; >- $target_calendar->insert_single_holiday(%$_) >- foreach grep { $_->{date} gt $today } values %{ $self->get_single_holidays }; >- >- return 1; >+ C4::Context->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} ); > } > >-=head2 addDate >+=head2 CopyAllEvents > >- my ($day, $month, $year) = $calendar->addDate($date, $offset) >+ CopyAllEvents( $from_branchcode, $to_branchcode ) > >-C<$date> is a C4::Dates object representing the starting date of the interval. >- >-C<$offset> Is the number of days that this function has to count from $date. >+Copies all events from one branch to another. > > =cut > >-sub addDate { >- my ($self, $startdate, $offset) = @_; >- my ($year,$month,$day) = split("-",$startdate->output('iso')); >- my $daystep = 1; >- if ($offset < 0) { # In case $offset is negative >- # $offset = $offset*(-1); >- $daystep = -1; >- } >- my $daysMode = C4::Context->preference('useDaysMode'); >- if ($daysMode eq 'Datedue') { >- ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, $offset ); >- while ($self->isHoliday($day, $month, $year)) { >- ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, $daystep); >- } >- } elsif($daysMode eq 'Calendar') { >- while ($offset != 0) { >- ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, $daystep); >- if (!($self->isHoliday($day, $month, $year))) { >- $offset = $offset - $daystep; >- } >- } >- } else { ## ($daysMode eq 'Days') >- ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, $offset ); >- } >- return(C4::Dates->new( sprintf(ISO_DATE_FORMAT,$year,$month,$day),'iso')); >+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 >+ 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 >+ WHERE branchcode = ? >+ }, {}, $to_branchcode, $from_branchcode ); > } > >-=head2 daysBetween >- >- my $daysBetween = $calendar->daysBetween($startdate, $enddate) >- >-C<$startdate> and C<$enddate> are C4::Dates objects that define the interval. >- >-Returns the number of non-holiday days in the interval. >-useDaysMode syspref has no effect here. >-=cut >- >-sub daysBetween { >- my $self = shift or return; >- my $startdate = shift or return; >- my $enddate = shift or return; >- my ($yearFrom,$monthFrom,$dayFrom) = split("-",$startdate->output('iso')); >- my ($yearTo, $monthTo, $dayTo ) = split("-", $enddate->output('iso')); >- if (Date_to_Days($yearFrom,$monthFrom,$dayFrom) > Date_to_Days($yearTo,$monthTo,$dayTo)) { >- return 0; >- # we don't go backwards ( FIXME - handle this error better ) >- } >- my $count = 0; >- while (1) { >- ($yearFrom != $yearTo or $monthFrom != $monthTo or $dayFrom != $dayTo) or last; # if they all match, it's the last day >- unless ($self->isHoliday($dayFrom, $monthFrom, $yearFrom)) { >- $count++; >- } >- ($yearFrom, $monthFrom, $dayFrom) = &Date::Calc::Add_Delta_Days($yearFrom, $monthFrom, $dayFrom, 1); >- } >- return($count); >-} > > 1; > >@@ -729,5 +267,6 @@ __END__ > =head1 AUTHOR > > Koha Physics Library UNLP <matias_veleda@hotmail.com> >+Jesse Weaver <jweaver@bywatersolutions.com> > > =cut >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index f24f2f7..d026e0c 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -3419,93 +3419,6 @@ sub CalcDateDue { > return $datedue; > } > >- >-=head2 CheckRepeatableHolidays >- >- $countrepeatable = CheckRepeatableHoliday($itemnumber,$week_day,$branchcode); >- >-This function checks if the date due is a repeatable holiday >- >-C<$date_due> = returndate calculate with no day check >-C<$itemnumber> = itemnumber >-C<$branchcode> = localisation of issue >- >-=cut >- >-sub CheckRepeatableHolidays{ >-my($itemnumber,$week_day,$branchcode)=@_; >-my $dbh = C4::Context->dbh; >-my $query = qq|SELECT count(*) >- FROM repeatable_holidays >- WHERE branchcode=? >- AND weekday=?|; >-my $sth = $dbh->prepare($query); >-$sth->execute($branchcode,$week_day); >-my $result=$sth->fetchrow; >-return $result; >-} >- >- >-=head2 CheckSpecialHolidays >- >- $countspecial = CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode); >- >-This function check if the date is a special holiday >- >-C<$years> = the years of datedue >-C<$month> = the month of datedue >-C<$day> = the day of datedue >-C<$itemnumber> = itemnumber >-C<$branchcode> = localisation of issue >- >-=cut >- >-sub CheckSpecialHolidays{ >-my ($years,$month,$day,$itemnumber,$branchcode) = @_; >-my $dbh = C4::Context->dbh; >-my $query=qq|SELECT count(*) >- FROM `special_holidays` >- WHERE year=? >- AND month=? >- AND day=? >- AND branchcode=? >- |; >-my $sth = $dbh->prepare($query); >-$sth->execute($years,$month,$day,$branchcode); >-my $countspecial=$sth->fetchrow ; >-return $countspecial; >-} >- >-=head2 CheckRepeatableSpecialHolidays >- >- $countspecial = CheckRepeatableSpecialHolidays($month,$day,$itemnumber,$branchcode); >- >-This function check if the date is a repeatble special holidays >- >-C<$month> = the month of datedue >-C<$day> = the day of datedue >-C<$itemnumber> = itemnumber >-C<$branchcode> = localisation of issue >- >-=cut >- >-sub CheckRepeatableSpecialHolidays{ >-my ($month,$day,$itemnumber,$branchcode) = @_; >-my $dbh = C4::Context->dbh; >-my $query=qq|SELECT count(*) >- FROM `repeatable_holidays` >- WHERE month=? >- AND day=? >- AND branchcode=? >- |; >-my $sth = $dbh->prepare($query); >-$sth->execute($month,$day,$branchcode); >-my $countspecial=$sth->fetchrow ; >-return $countspecial; >-} >- >- >- > sub CheckValidBarcode{ > my ($barcode) = @_; > my $dbh = C4::Context->dbh; >diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm >index 9e030a6..73daee5 100644 >--- a/C4/Installer/PerlDependencies.pm >+++ b/C4/Installer/PerlDependencies.pm >@@ -737,6 +737,11 @@ our $PERL_DEPS = { > 'required' => '0', > 'min_ver' => '5.61', > }, >+ 'Template::Plugin::JavaScript' => { >+ 'usage' => 'Core', >+ 'required' => '1', >+ 'min_ver' => '0.02', >+ }, > }; > > 1; >diff --git a/C4/Overdues.pm b/C4/Overdues.pm >index 185584f..ab862df 100644 >--- a/C4/Overdues.pm >+++ b/C4/Overdues.pm >@@ -313,130 +313,6 @@ sub _get_chargeable_units { > } > > >-=head2 GetSpecialHolidays >- >- &GetSpecialHolidays($date_dues,$itemnumber); >- >-return number of special days between date of the day and date due >- >-C<$date_dues> is the envisaged date of book return. >- >-C<$itemnumber> is the book's item number. >- >-=cut >- >-sub GetSpecialHolidays { >- my ( $date_dues, $itemnumber ) = @_; >- >- # calcul the today date >- my $today = join "-", &Today(); >- >- # return the holdingbranch >- my $iteminfo = GetIssuesIteminfo($itemnumber); >- >- # use sql request to find all date between date_due and today >- my $dbh = C4::Context->dbh; >- my $query = >- qq|SELECT DATE_FORMAT(concat(year,'-',month,'-',day),'%Y-%m-%d') as date >-FROM `special_holidays` >-WHERE DATE_FORMAT(concat(year,'-',month,'-',day),'%Y-%m-%d') >= ? >-AND DATE_FORMAT(concat(year,'-',month,'-',day),'%Y-%m-%d') <= ? >-AND branchcode=? >-|; >- my @result = GetWdayFromItemnumber($itemnumber); >- my @result_date; >- my $wday; >- my $dateinsec; >- my $sth = $dbh->prepare($query); >- $sth->execute( $date_dues, $today, $iteminfo->{'branchcode'} ) >- ; # FIXME: just use NOW() in SQL instead of passing in $today >- >- while ( my $special_date = $sth->fetchrow_hashref ) { >- push( @result_date, $special_date ); >- } >- >- my $specialdaycount = scalar(@result_date); >- >- for ( my $i = 0 ; $i < scalar(@result_date) ; $i++ ) { >- $dateinsec = UnixDate( $result_date[$i]->{'date'}, "%o" ); >- ( undef, undef, undef, undef, undef, undef, $wday, undef, undef ) = >- localtime($dateinsec); >- for ( my $j = 0 ; $j < scalar(@result) ; $j++ ) { >- if ( $wday == ( $result[$j]->{'weekday'} ) ) { >- $specialdaycount--; >- } >- } >- } >- >- return $specialdaycount; >-} >- >-=head2 GetRepeatableHolidays >- >- &GetRepeatableHolidays($date_dues, $itemnumber, $difference,); >- >-return number of day closed between date of the day and date due >- >-C<$date_dues> is the envisaged date of book return. >- >-C<$itemnumber> is item number. >- >-C<$difference> numbers of between day date of the day and date due >- >-=cut >- >-sub GetRepeatableHolidays { >- my ( $date_dues, $itemnumber, $difference ) = @_; >- my $dateinsec = UnixDate( $date_dues, "%o" ); >- my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = >- localtime($dateinsec); >- my @result = GetWdayFromItemnumber($itemnumber); >- my @dayclosedcount; >- my $j; >- >- for ( my $i = 0 ; $i < scalar(@result) ; $i++ ) { >- my $k = $wday; >- >- for ( $j = 0 ; $j < $difference ; $j++ ) { >- if ( $result[$i]->{'weekday'} == $k ) { >- push( @dayclosedcount, $k ); >- } >- $k++; >- ( $k = 0 ) if ( $k eq 7 ); >- } >- } >- return scalar(@dayclosedcount); >-} >- >- >-=head2 GetWayFromItemnumber >- >- &Getwdayfromitemnumber($itemnumber); >- >-return the different week day from repeatable_holidays table >- >-C<$itemnumber> is item number. >- >-=cut >- >-sub GetWdayFromItemnumber { >- my ($itemnumber) = @_; >- my $iteminfo = GetIssuesIteminfo($itemnumber); >- my @result; >- my $query = qq|SELECT weekday >- FROM repeatable_holidays >- WHERE branchcode=? >-|; >- my $sth = C4::Context->dbh->prepare($query); >- >- $sth->execute( $iteminfo->{'branchcode'} ); >- while ( my $weekday = $sth->fetchrow_hashref ) { >- push( @result, $weekday ); >- } >- return @result; >-} >- >- > =head2 GetIssuesIteminfo > > &GetIssuesIteminfo($itemnumber); >diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm >index 6013a25..ee5ee6d 100644 >--- a/Koha/Calendar.pm >+++ b/Koha/Calendar.pm >@@ -60,7 +60,7 @@ sub _init { > # 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 { >+sub _exception_holidays { > my ( $self ) = @_; > my $dbh = C4::Context->dbh; > my $branch = $self->{branchcode}; >@@ -88,7 +88,7 @@ sub exception_holidays { > return $exception_holidays; > } > >-sub single_holidays { >+sub _single_holidays { > my ( $self ) = @_; > my $dbh = C4::Context->dbh; > my $branchcode = $self->{branchcode}; >@@ -215,7 +215,7 @@ sub is_holiday { > > $localdt->truncate( to => 'day' ); > >- if ( $self->exception_holidays->contains($localdt) ) { >+ if ( $self->_exception_holidays->contains($localdt) ) { > # exceptions are not holidays > return 0; > } >@@ -235,7 +235,7 @@ sub is_holiday { > return 1; > } > >- if ( $self->single_holidays->contains($localdt) ) { >+ if ( $self->_single_holidays->contains($localdt) ) { > return 1; > } > >@@ -341,19 +341,6 @@ sub clear_weekly_closed_days { > return; > } > >-sub add_holiday { >- my $self = shift; >- my $new_dt = shift; >- my @dt = $self->single_holidays->as_list; >- push @dt, $new_dt; >- my $branchcode = $self->{branchcode}; >- $self->{single_holidays}{$branchcode} = >- DateTime::Set->from_datetimes( dates => \@dt ); >- $single_holidays->{$branchcode} = $self->{single_holidays}{$branchcode}; >- >- return; >-} >- > 1; > __END__ > >@@ -471,12 +458,6 @@ 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 > >-=head2 add_holiday >- >-Passed a datetime object this will add it to the calendar's list of >-closed days. This is for testing so that we can alter the Calenfar object's >-list of specified dates >- > =head1 DIAGNOSTICS > > Will croak if not passed a branchcode in new >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 ea3cf82..0ffb48e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >@@ -88,7 +88,7 @@ > <h5>Additional tools</h5> > <ul> > [% IF ( CAN_user_tools_edit_calendar ) %] >- <li><a href="/cgi-bin/koha/tools/holidays.pl">Calendar</a></li> >+ <li><a href="/cgi-bin/koha/tools/calendar.pl">Calendar</a></li> > [% END %] > [% IF ( CAN_user_tools_manage_csv_profiles ) %] > <li><a href="/cgi-bin/koha/tools/csv-profiles.pl">CSV profiles</a></li> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt >new file mode 100644 >index 0000000..b952253 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt >@@ -0,0 +1,594 @@ >+[% USE 'JavaScript' %] >+[% USE 'KohaDates' %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Tools › [% branchname %] Calendar</title> >+[% INCLUDE 'doc-head-close.inc' %] >+[% INCLUDE 'calendar.inc' %] >+<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> >+[% INCLUDE 'datatables.inc' %] >+<script language="JavaScript" type="text/javascript"> >+//<![CDATA[ >+ [% IF (dateformat == 'metric') %]dt_add_type_uk_date();[% END %] >+ var weekdays = new Array(_("Sundays"),_("Mondays"),_("Tuesdays"),_("Wednesdays"),_("Thursdays"),_("Fridays"),_("Saturdays")); >+ >+ var single_events = { >+ [% FOREACH event IN single_events %] >+ '[% event.event_date %]': { >+ title: '[% event.title | js %]', >+ description: '[% event.description | js %]', >+ closed: [% event.closed %], >+ eventType: 'single', >+ open_hour: '[% event.open_hour %]', >+ open_minute: '[% event.open_minute %]', >+ close_hour: '[% event.close_hour %]', >+ close_minute: '[% event.close_minute %]' >+ }, >+ [% END %] >+ }; >+ >+ var weekly_events = { >+ [% FOREACH event IN weekly_events %] >+ [% event.weekday %]: { >+ title: '[% event.title | js %]', >+ description: '[% event.description | js %]', >+ closed: [% event.closed %], >+ eventType: 'weekly', >+ weekday: [% event.weekday %], >+ open_hour: '[% event.open_hour %]', >+ open_minute: '[% event.open_minute %]', >+ close_hour: '[% event.close_hour %]', >+ close_minute: '[% event.close_minute %]' >+ }, >+ [% END %] >+ }; >+ >+ var yearly_events = { >+ [% FOREACH event IN yearly_events %] >+ '[% event.month %]-[% event.day %]': { >+ title: '[% event.title | js %]', >+ description: '[% event.description | js %]', >+ closed: [% event.closed %], >+ eventType: 'yearly', >+ month: [% event.month %], >+ day: [% event.day %], >+ open_hour: '[% event.open_hour %]', >+ open_minute: '[% event.open_minute %]', >+ close_hour: '[% event.close_hour %]', >+ close_minute: '[% event.close_minute %]' >+ }, >+ [% END %] >+ }; >+ >+ function eventOperation(formObject, opType) { >+ var op = document.getElementsByName('op'); >+ op[0].value = opType; >+ formObject.submit(); >+ } >+ >+ function zeroPad(value) { >+ return value >= 10 ? value : ('0' + value); >+ } >+ >+ // This function shows the "Show Event" panel // >+ function showEvent(dayName, day, month, year, weekDay, event) { >+ $("#newEvent").slideUp("fast"); >+ $("#showEvent").slideDown("fast"); >+ $('#showDaynameOutput').html(dayName); >+ $('#showDayname').val(dayName); >+ $('#showBranchNameOutput').html($("#branch :selected").text()); >+ $('#showBranchName').val($("#branch").val()); >+ $('#showDayOutput').html(day); >+ $('#showDay').val(day); >+ $('#showMonthOutput').html(month); >+ $('#showMonth').val(month); >+ $('#showYearOutput').html(year); >+ $('#showYear').val(year); >+ $('#showDescription').val(event.description); >+ $('#showWeekday:first').val(weekDay); >+ $('#showTitle').val(event.title); >+ $('#showEventType').val(event.eventType); >+ >+ if (event.closed) { >+ $('#showHoursTypeClosed')[0].checked = true; >+ } else if (event.close_hour == 24) { >+ $('#showHoursTypeOpen')[0].checked = true; >+ } else { >+ $('#showHoursTypeOpenSet')[0].checked = true; >+ $('#showHoursTypeOpenSet').change(); >+ $('#showOpenTime').val(event.open_hour + ':' + zeroPad(event.open_minute)); >+ $('#showCloseTime').val(event.close_hour + ':' + zeroPad(event.close_minute)); >+ } >+ >+ $("#operationDelLabel").html(_("Delete this event.")); >+ if(event.eventType == 'weekly') { >+ $("#holtype").attr("class","key repeatableweekly").html(_("Event repeating weekly")); >+ } else if(event.eventType == 'yearly') { >+ $("#holtype").attr("class","key repeatableyearly").html(_("Event repeating yearly")); >+ } else { >+ $("#holtype").attr("class","key event").html(_("Single event")); >+ } >+ } >+ >+ // This function shows the "Add Event" panel // >+ function newEvent (dayName, day, month, year, weekDay) { >+ $("#showEvent").slideUp("fast"); >+ $("#newEvent").slideDown("fast"); >+ $("#newDaynameOutput").html(dayName); >+ $("#newDayname").val(dayName); >+ $("#newBranchNameOutput").html($('#branch :selected').text()); >+ $("#newBranchName").val($('#branch').val()); >+ $("#newDayOutput").html(day); >+ $("#newDay").val(day); >+ $("#newMonthOutput").html(month); >+ $("#newMonth").val(month); >+ $("#newYearOutput").html(year); >+ $("#newYear").val(year); >+ $("#newWeekday:first").val(weekDay); >+ } >+ >+ function hidePanel(aPanelName) { >+ $("#"+aPanelName).slideUp("fast"); >+ } >+ >+ function changeBranch () { >+ var branch = $("#branch option:selected").val(); >+ location.href='/cgi-bin/koha/tools/calendar.pl?branch=' + branch + '&calendardate=' + "[% calendardate %]"; >+ } >+ >+ /* This function gives css clases to each kind of day */ >+ function dateStatusHandler(date) { >+ date = new Date(date); >+ var day = date.getDate(); >+ var month = date.getMonth() + 1; >+ var year = date.getFullYear(); >+ var weekDay = date.getDay(); >+ var dayMonth = month + '-' + day; >+ var dateString = year + '-' + zeroPad(month) + '-' + zeroPad(day); >+ >+ if ( single_events[dateString] != null) { >+ return [true, "event", "Single event: "+single_events[dateString].title]; >+ } else if ( yearly_events[dayMonth] != null ) { >+ return [true, "repeatableyearly", "Yearly event: "+yearly_events[dayMonth].title]; >+ } else if ( weekly_events[weekDay] != null ){ >+ return [true, "repeatableweekly", "Weekly event: "+weekly_events[weekDay].title]; >+ } else { >+ return [true, "normalday", "Normal day"]; >+ } >+ } >+ >+ /* This function is in charge of showing the correct panel considering the kind of event */ >+ function dateChanged(calendar) { >+ calendar = new Date(calendar); >+ var day = calendar.getDate(); >+ var month = calendar.getMonth() + 1; >+ var year = calendar.getFullYear(); >+ var weekDay = calendar.getDay(); >+ var dayName = weekdays[weekDay]; >+ var dayMonth = month + '-' + day; >+ var dateString = year + '-' + zeroPad(month) + '-' + zeroPad(day); >+ if ( single_events[dateString] != null ) { >+ showEvent( dayName, day, month, year, weekDay, single_events[dateString] ); >+ } else if ( yearly_events[dayMonth] != null ) { >+ showEvent( dayName, day, month, year, weekDay, yearly_events[dayMonth] ); >+ } else if ( weekly_events[weekDay] != null ) { >+ showEvent( dayName, day, month, year, weekDay, weekly_events[weekDay] ); >+ } else { >+ newEvent( dayName, day, month, year, weekDay ); >+ } >+ }; >+ >+ $(document).ready(function() { >+ >+ $(".hint").hide(); >+ $("#branch").change(function(){ >+ changeBranch(); >+ }); >+ $("#weekly-events,#single-events").dataTable($.extend(true, {}, dataTablesDefaults, { >+ "sDom": 't', >+ "bPaginate": false >+ })); >+ $("#yearly-events").dataTable($.extend(true, {}, dataTablesDefaults, { >+ "sDom": 't', >+ "aoColumns": [ >+ { "sType": "title-string" },null,null,null >+ ], >+ "bPaginate": false >+ })); >+ $("a.helptext").click(function(){ >+ $(this).parent().find(".hint").toggle(); return false; >+ }); >+ $("#dateofrange").datepicker(); >+ $("#datecancelrange").datepicker(); >+ $("#dateofrange").each(function () { this.value = "" }); >+ $("#datecancelrange").each(function () { this.value = "" }); >+ $("#jcalendar-container").datepicker({ >+ beforeShowDay: function(thedate) { >+ var day = thedate.getDate(); >+ var month = thedate.getMonth() + 1; >+ var year = thedate.getFullYear(); >+ var dateString = year + '/' + month + '/' + day; >+ return dateStatusHandler(dateString); >+ }, >+ onSelect: function(dateText, inst) { >+ dateChanged($(this).datepicker("getDate")); >+ }, >+ defaultDate: new Date("[% keydate %]") >+ }); >+ $(".hourssel input").change(function() { >+ $(".hoursentry", this.form).toggle(this.value == 'openSet'); >+ }).each( function() { this.checked = false } ); >+ }); >+//]]> >+</script> >+<style type="text/css"> .key { padding : 3px; white-space:nowrap; line-height:230%; } >+.ui-datepicker { font-size : 150%; } >+.ui-datepicker th, .ui-datepicker .ui-datepicker-title select { font-size : 80%; } >+.ui-datepicker td a { padding : .5em; } >+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { font-size : 80%; } >+.key { padding : 3px; white-space:nowrap; line-height:230%; } >+.normalday { background-color : #EDEDED; color : Black; border : 1px solid #BCBCBC; } >+.exception { background-color : #b3d4ff; color : Black; border : 1px solid #BCBCBC; } >+.event { background-color : #ffaeae; color : Black; border : 1px solid #BCBCBC; } >+.repeatableweekly { background-color : #FFFF99; color : Black; border : 1px solid #BCBCBC; } >+.repeatableyearly { background-color : #FFCC66; color : Black; border : 1px solid #BCBCBC; } >+td.exception a.ui-state-default { background: #b3d4ff none; color : Black; border : 1px solid #BCBCBC; } >+td.event a.ui-state-default { background: #ffaeae none; color : Black; border : 1px solid #BCBCBC; } >+td.repeatableweekly a.ui-state-default { background: #FFFF99 none; color : Black; border : 1px solid #BCBCBC; } >+td.repeatableyearly a.ui-state-default { background: #FFCC66 none; color : Black; border : 1px solid #BCBCBC; } >+.information { z-index : 1; background-color : #DCD2F1; width : 300px; display : none; border : 1px solid #000000; color : #000000; font-size : 8pt; font-weight : bold; background-color : #FFD700; cursor : pointer; padding : 2px; } >+.panel { z-index : 1; display : none; border : 3px solid #CCC; padding : 3px; margin-top: .3em; background-color: #FEFEFE; } fieldset.brief { border : 0; margin-top: 0; } >+#showEvent { margin : .5em 0; } h1 select { width: 20em; } div.yui-b fieldset.brief ol { font-size:100%; } div.yui-b fieldset.brief li, div.yui-b fieldset.brief li.radio { padding:0.2em 0; } .help { margin:.3em 0;border:1px solid #EEE;padding:.3em .7em; font-size : 90%; } #single-events, #weekly-events, #yearly-events { font-size : 90%; margin-bottom : 1em;} .calendar td, .calendar th, .calendar .button, .calendar tbody .day { padding : .7em; font-size: 110%; } .calendar { width: auto; border : 0; } >+li.hourssel { >+ margin-top: .5em; >+} >+li.hourssel label { >+ padding-left: .2em; >+ padding-right: .5em; >+} >+li.hoursentry { >+ margin-bottom: .5em; >+} >+li.hoursentry input { >+ padding-left: .2em; >+ padding-right: .5em; >+} >+</style> >+</head> >+<body id="tools_events" class="tools"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › [% branchname %] Calendar</div> >+ >+<div id="doc3" class="yui-t1"> >+ >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ <h2>[% branchname %] Calendar</h2> >+ <div class="yui-g"> >+ <div class="yui-u first"> >+ <label for="branch">Calendar for:</label> >+ <select id="branch" name="branch"> >+ [% FOREACH branchloo IN branchloop %] >+ [% IF ( branchloo.selected ) %] >+ <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option> >+ [% ELSE %] >+ <option value="[% branchloo.value %]">[% branchloo.branchname %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ >+ <!-- ******************************** FLAT PANELS ******************************************* --> >+ <!-- ***** Makes all the flat panel to deal with events ***** --> >+ <!-- **************************************************************************************** --> >+ >+ <!-- ********************** Panel for showing already loaded events *********************** --> >+ <div class="panel" id="showEvent"> >+ <form action="/cgi-bin/koha/tools/calendar.pl" method="post"> >+ <input type="hidden" id="showEventType" name="eventType" value="" /> >+ <fieldset class="brief"> >+ <h3>Edit this event</h3> >+ <span id="holtype"></span> >+ <ol> >+ <li> >+ <strong>Library:</strong> <span id="showBranchNameOutput"></span> >+ <input type="hidden" id="showBranchName" name="branchName" /> >+ </li> >+ <li> >+ <strong>From Date:</strong> >+ <span id="showDaynameOutput"></span>, >+ >+ [% IF ( dateformat == "us" ) %]<span id="showMonthOutput"></span>/<span id="showDayOutput"></span>/<span id="showYearOutput"></span>[% ELSIF ( dateformat == "metric" ) %]<span id="showDayOutput"></span>/<span id="showMonthOutput"></span>/<span id="showYearOutput"></span>[% ELSE %]<span id="showYearOutput"></span>/<span id="showMonthOutput"></span>/<span id="showDayOutput"></span>[% END %] >+ >+ <input type="hidden" id="showWeekday" name="weekday" /> >+ <input type="hidden" id="showDay" name="day" /> >+ <input type="hidden" id="showMonth" name="month" /> >+ <input type="hidden" id="showYear" name="year" /> >+ </li> >+ <li class="dateinsert"> >+ <b>To Date : </b> >+ <input type="text" id="datecancelrange" name="dateofrange" size="20" value="[% dateofrange %]" class="datepicker"/> >+ </li> >+ <li class="radio hourssel"> >+ <input type="radio" name="hoursType" id="showHoursTypeOpen" value="open" /><label for="showHoursTypeOpen">Open (will delete repeating events)</label> >+ <input type="radio" name="hoursType" id="showHoursTypeClosed" value="closed" /><label for="showHoursTypeClosed">Closed</label> >+ </li> >+ <li class="radio hoursentry" style="display:none"> >+ <label for="showOpenTime">Open at:</label> >+ <input type="time" name="openTime" id="showOpenTime" size="3" maxlength="5" value="0:00" pattern="(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])" /> >+ <label for="showCloseTime">Closed at:</label> >+ <input type="time" name="closeTime" id="showCloseTime" size="3" maxlength="5" value="23:59" pattern="(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])" /> >+ </li> >+ <li><label for="showTitle">Title: </label><input type="text" name="title" id="showTitle" size="35" /></li> >+ <!-- showTitle is necessary for exception radio button to work properly --> >+ <label for="showDescription">Description:</label> >+ <textarea rows="2" cols="40" id="showDescription" name="description"></textarea> >+ </li> >+ <li class="radio"><input type="radio" name="op" id="showOperationDel" value="delete" /> <label for="showOperationDel" id="showOperationDelLabel">Delete this event</label> >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">This will delete this event rule. >+ <li class="radio"><input type="radio" name="op" id="showOperationDelRange" value="deleterange" /> <label for="showOperationDelRange" id="showOperationDelLabelRange">Delete the single events on a range</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">This will delete the single events only. The repeatable events will not be deleted.</div> >+ </li> >+ <li class="radio"><input type="radio" name="op" id="showOperationDelRangeRepeat" value="deleterangerepeat" /> <label for="showOperationDelRangeRepeat" id="showOperationDelLabelRangeRepeat">Delete the repeated events on a range</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">This will delete the yearly repeated events only.</div> >+ </li> >+ <li class="radio"><input type="radio" name="op" id="showOperationEdit" value="save" checked="checked" /> <label for="showOperationEdit">Edit this event</label> >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">This will save changes to the event's title and description. If the information for a repeatable event is modified, it affects all of the dates on which the event is repeated.</div></li> >+ </ol> >+ <fieldset class="action"> >+ <input type="submit" name="submit" value="Save" /> >+ <a href="#" class="cancel" name="cancel2" onclick=" hidePanel('showEvent');">Cancel</a> >+ </fieldset> >+ </fieldset> >+ </form> >+ </div> >+ >+ <!-- ***************************** Panel to deal with new events ********************** --> >+ <div class="panel" id="newEvent"> >+ <form action="/cgi-bin/koha/tools/calendar.pl" method="post"> >+ <input type="hidden" name="branchCodes" id="branchCodes" value="[% branchcodes %]" /> >+ <input type="hidden" name="op" value="save" /> >+ <fieldset class="brief"> >+ <h3>Add new event</h3> >+ >+ <ol> >+ <li> >+ <strong>Library:</strong> >+ <span id="newBranchNameOutput"></span> >+ <input type="hidden" id="newBranchName" name="branchName" /> >+ </li> >+ <li> >+ <strong>From date:</strong> >+ <span id="newDaynameOutput"></span>, >+ >+ [% IF ( dateformat == "us" ) %]<span id="newMonthOutput"></span>/<span id="newDayOutput"></span>/<span id="newYearOutput"></span>[% ELSIF ( dateformat == "metric" ) %]<span id="newDayOutput"></span>/<span id="newMonthOutput"></span>/<span id="newYearOutput"></span>[% ELSE %]<span id="newYearOutput"></span>/<span id="newMonthOutput"></span>/<span id="newDayOutput"></span>[% END %] >+ >+ <input type="hidden" id="newWeekday" name="weekday" /> >+ <input type="hidden" id="newDay" name="day" /> >+ <input type="hidden" id="newMonth" name="month" /> >+ <input type="hidden" id="newYear" name="year" /> >+ </li> >+ <li class="dateinsert"> >+ <b>To date : </b> >+ <input type="text" id="dateofrange" name="dateofrange" size="20" value="[% dateofrange %]" class="datepicker" /> >+ </li> >+ <li class="radio hourssel"> >+ <input type="radio" name="hoursType" id="newHoursTypeOpen" value="open" /><label for="newHoursTypeOpen">Open (will not work for repeating events)</label> >+ <input type="radio" name="hoursType" id="newHoursTypeClosed" value="closed" /><label for="newHoursTypeClosed">Closed</label> >+ </li> >+ <li class="radio hoursentry" style="display:none"> >+ <label for="newOpenTime">Open at:</label> >+ <input type="time" name="openTime" id="newOpenTime" size="3" maxlength="5" value="0:00" pattern="(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])" /> >+ <label for="newCloseTime">Closed at:</label> >+ <input type="time" name="closeTime" id="newCloseTime" size="3" maxlength="5" value="23:59" pattern="(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])" /> >+ </li> >+ <li><label for="title">Title: </label><input type="text" name="title" id="title" size="35" /></li> >+ <li><label for="newDescription">Description:</label> >+ <textarea rows="2" cols="40" id="newDescription" name="description"></textarea> >+ </li> >+ <li class="radio"><input type="radio" name="eventType" id="newOperationOnce" value="single" checked="checked" /> >+ <label for="newOperationOnce">Event only on this day</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">Make a single event. For example, selecting August 1st, 2012 will not affect August 1st in other years.</div> >+ </li> >+ <li class="radio"><input type="radio" name="eventType" id="newOperationDay" value="weekly" /> >+ <label for="newOperationDay">Event repeated weekly</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">Make this weekday an event, every week. For example, if your library is closed on Saturdays, use this option to make every Saturday a event.</div> >+ </li> >+ <li class="radio"><input type="radio" name="eventType" id="newOperationYear" value="yearly" /> >+ <label for="newOperationYear">Event repeated yearly</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">Make this day of the year an event, every year. For example, selecting August 1st will set the hours for August 1st every year.</div> >+ </li> >+ <li class="radio"><input type="radio" name="eventType" id="newOperationField" value="singlerange" /> >+ <label for="newOperationField">Events on a range</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">Make events for a range of days. For example, selecting August 1st, 2012 and August 10st, 2012 will make all days between 1st and 10st event, but will not affect August 1-10 in other years.</div> >+ </li> >+ <li class="radio"><input type="radio" name="eventType" id="newOperationFieldyear" value="yearlyrange" /> >+ <label for="newOperationFieldyear">Events repeated yearly on a range</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">Make a single event on a range repeated yearly. For example, selecting August 1st, 2012 and August 10st, 2012 will make all days between 1st and 10st event, and will affect August 1-10 in other years.</div> >+ </li> >+ <li class="radio"> >+ <input type="checkbox" name="allBranches" id="allBranches" /> >+ <label for="allBranches">Copy to all libraries</label>. >+ <a href="#" class="helptext">[?]</a> >+ <div class="hint">If checked, this event will be copied to all libraries. If the event already exists for a library, no change is made.</div> >+ </li></ol> >+ <fieldset class="action"> >+ <input type="submit" name="submit" value="Save" /> >+ <a href="#" class="cancel" name="cancel2" onclick=" hidePanel('newEvent');">Cancel</a> >+ </fieldset> >+ </fieldset> >+ </form> >+ </div> >+ >+ <!-- *************************************************************************************** --> >+ <!-- ****** END OF FLAT PANELS ****** --> >+ <!-- *************************************************************************************** --> >+ >+<!-- ************************************************************************************** --> >+<!-- ****** MAIN SCREEN CODE ****** --> >+<!-- ************************************************************************************** --> >+<h3>Calendar information</h3> >+<div id="jcalendar-container"></div> >+ >+<div style="margin-top: 2em;"> >+<form action="/cgi-bin/koha/tools/calendar.pl" method="post"> >+ <input type="hidden" name="op" value="copyall" /> >+ <input type="hidden" name="from_branchcode" value="[% branch %]" /> >+ <label for="branchcode">Copy events to:</label> >+ <select id="branchcode" name="branchcode" required> >+ <option value=""></option> >+ [% FOREACH branchloo IN branchloop %] >+ <option value="[% branchloo.value %]">[% branchloo.branchname %]</option> >+ [% END %] >+ </select> >+ <input type="submit" value="Copy" /> >+</form> >+</div> >+ >+</div> >+<div class="yui-u"> >+<div class="help"> >+<h4>Hints</h4> >+ <ul> >+ <li>Search in the calendar the day you want to set as event.</li> >+ <li>Click the date to add or edit a event.</li> >+ <li>Enter a title and description for the event.</li> >+ <li>Specify how the event should repeat.</li> >+ <li>Click Save to finish.</li> >+ </ul> >+<h4>Key</h4> >+ <p> >+ <span class="key normalday">Working day</span> >+ <span class="key event">Unique event</span> >+ <span class="key repeatableweekly">Event repeating weekly</span> >+ <span class="key repeatableyearly">Event repeating yearly</span> >+ </p> >+</div> >+<div id="event-list"> >+[% IF ( weekly_events ) %] >+<h3>Weekly - Repeatable Events</h3> >+<table id="weekly-events"> >+<thead> >+<tr> >+ <th class="repeatableweekly">Day of week</th> >+ <th class="repeatableweekly">Title</th> >+ <th class="repeatableweekly">Description</th> >+ <th class="repeatableweekly">Hours</th> >+</tr> >+</thead> >+<tbody> >+ [% FOREACH event IN weekly_events %] >+ <tr> >+ <td> >+<script type="text/javascript"> >+ document.write(weekdays[ [% event.weekday %]]); >+</script> >+ </td> >+ <td>[% event.title %]</td> >+ <td>[% event.description %]</td> >+ <td> >+ [% 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.close_hour %]:[% event.close_minute > 10 ? event.close_minute : ( '0' _ event.close_minute) %] >+ [% END %] >+ </td> >+ </tr> >+ [% END %] >+</tbody> >+</table> >+[% END %] >+ >+[% IF ( yearly_events ) %] >+<h3>Yearly - Repeatable Events</h3> >+<table id="yearly-events"> >+<thead> >+<tr> >+ [% IF ( dateformat == "metric" ) %] >+ <th class="repeatableyearly">Day/Month</th> >+ [% ELSE %] >+ <th class="repeatableyearly">Month/Day</th> >+ [% END %] >+ <th class="repeatableyearly">Title</th> >+ <th class="repeatableyearly">Description</th> >+ <th class="repeatableyearly">Hours</th> >+</tr> >+</thead> >+<tbody> >+ [% FOREACH event IN yearly_events %] >+ <tr> >+ <td><span title="[% event.month_day_display %]">[% event.month_day_sort %]</span></td> >+ <td>[% event.title %]</td> >+ <td>[% event.description %]</td> >+ <td> >+ [% 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.close_hour %]:[% event.close_minute > 10 ? event.close_minute : ( '0' _ event.close_minute) %] >+ [% END %] >+ </td> >+ </tr> >+ [% END %] >+</tbody> >+</table> >+[% END %] >+ >+[% IF ( single_events ) %] >+<h3>Single Events</h3> >+<table id="single-events"> >+<thead> >+<tr> >+ <th class="event">Date</th> >+ <th class="event">Title</th> >+ <th class="event">Description</th> >+ <th class="event">Hours</th> >+</tr> >+</thead> >+<tbody> >+ [% FOREACH event IN single_events %] >+<tr> >+ <td><a href="/cgi-bin/koha/tools/calendar.pl?branch=[% branch %]&calendardate=[% event.event_date | $KohaDates %]"><span title="[% event.event_date %]">[% event.event_date | $KohaDates %]</span></a></td> >+ <td>[% event.title %]</td> >+ <td>[% event.description %]</td> >+ <td> >+ [% 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.close_hour %]:[% event.close_minute > 10 ? event.close_minute : ( '0' _ event.close_minute) %] >+ [% END %] >+ </td> >+</tr> >+ [% END %] >+</tbody> >+</table> >+[% END %] >+</div> >+</div> >+</div> >+</div> >+</div> >+ >+<div class="yui-b noprint"> >+[% INCLUDE 'tools-menu.inc' %] >+</div> >+</div> >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt >deleted file mode 100644 >index 3fb10e4..0000000 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt >+++ /dev/null >@@ -1,537 +0,0 @@ >-[% INCLUDE 'doc-head-open.inc' %] >-<title>Koha › Tools › [% branchname %] calendar</title> >-[% INCLUDE 'doc-head-close.inc' %] >-[% INCLUDE 'calendar.inc' %] >-<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> >-[% INCLUDE 'datatables.inc' %] >-<script type="text/javascript"> >-//<![CDATA[ >- var weekdays = new Array(_("Sundays"),_("Mondays"),_("Tuesdays"),_("Wednesdays"),_("Thursdays"),_("Fridays"),_("Saturdays")); >- >- /* Creates all the structures to deal with all different kinds of holidays */ >- var week_days = new Array(); >- var holidays = new Array(); >- var holidates = new Array(); >- var exception_holidays = new Array(); >- var day_month_holidays = new Array(); >- var hola= "[% code %]"; >- [% FOREACH WEEK_DAYS_LOO IN WEEK_DAYS_LOOP %] >- week_days["[% WEEK_DAYS_LOO.KEY %]"] = {title:"[% WEEK_DAYS_LOO.TITLE %]", description:"[% WEEK_DAYS_LOO.DESCRIPTION %]"}; >- [% END %] >- [% FOREACH HOLIDAYS_LOO IN HOLIDAYS_LOOP %] >- holidates.push("[% HOLIDAYS_LOO.KEY %]"); >- holidays["[% HOLIDAYS_LOO.KEY %]"] = {title:"[% HOLIDAYS_LOO.TITLE %]", description:"[% HOLIDAYS_LOO.DESCRIPTION %]"}; >- >- [% END %] >- [% FOREACH EXCEPTION_HOLIDAYS_LOO IN EXCEPTION_HOLIDAYS_LOOP %] >- exception_holidays["[% EXCEPTION_HOLIDAYS_LOO.KEY %]"] = {title:"[% EXCEPTION_HOLIDAYS_LOO.TITLE %]", description:"[% EXCEPTION_HOLIDAYS_LOO.DESCRIPTION %]"}; >- [% END %] >- [% FOREACH DAY_MONTH_HOLIDAYS_LOO IN DAY_MONTH_HOLIDAYS_LOOP %] >- day_month_holidays["[% DAY_MONTH_HOLIDAYS_LOO.KEY %]"] = {title:"[% DAY_MONTH_HOLIDAYS_LOO.TITLE %]", description:"[% DAY_MONTH_HOLIDAYS_LOO.DESCRIPTION %]"}; >- [% END %] >- >- function holidayOperation(formObject, opType) { >- var op = document.getElementsByName('operation'); >- op[0].value = opType; >- formObject.submit(); >- } >- >- // This function shows the "Show Holiday" panel // >- function showHoliday (exceptionPosibility, dayName, day, month, year, weekDay, title, description, holidayType) { >- $("#newHoliday").slideUp("fast"); >- $("#showHoliday").slideDown("fast"); >- $('#showDaynameOutput').html(dayName); >- $('#showDayname').val(dayName); >- $('#showBranchNameOutput').html($("#branch :selected").text()); >- $('#showBranchName').val($("#branch").val()); >- $('#showDayOutput').html(day); >- $('#showDay').val(day); >- $('#showMonthOutput').html(month); >- $('#showMonth').val(month); >- $('#showYearOutput').html(year); >- $('#showYear').val(year); >- $('#showDescription').val(description); >- $('#showWeekday:first').val(weekDay); >- $('#showTitle').val(title); >- $('#showHolidayType').val(holidayType); >- >- if (holidayType == 'exception') { >- $("#showOperationDelLabel").html(_("Delete this exception.")); >- $("#holtype").attr("class","key exception").html(_("Holiday exception")); >- } else if(holidayType == 'weekday') { >- $("#showOperationDelLabel").html(_("Delete this holiday.")); >- $("#holtype").attr("class","key repeatableweekly").html(_("Holiday repeating weekly")); >- } else if(holidayType == 'daymonth') { >- $("#showOperationDelLabel").html(_("Delete this holiday.")); >- $("#holtype").attr("class","key repeatableyearly").html(_("Holiday repeating yearly")); >- } else { >- $("#showOperationDelLabel").html(_("Delete this holiday.")); >- $("#holtype").attr("class","key holiday").html(_("Unique holiday")); >- } >- >- if (exceptionPosibility == 1) { >- $("#exceptionPosibility").parent().show(); >- } else { >- $("#exceptionPosibility").parent().hide(); >- } >- } >- >- // This function shows the "Add Holiday" panel // >- function newHoliday (dayName, day, month, year, weekDay) { >- $("#showHoliday").slideUp("fast"); >- $("#newHoliday").slideDown("fast"); >- $("#newDaynameOutput").html(dayName); >- $("#newDayname").val(dayName); >- $("#newBranchNameOutput").html($('#branch :selected').text()); >- $("#newBranchName").val($('#branch').val()); >- $("#newDayOutput").html(day); >- $("#newDay").val(day); >- $("#newMonthOutput").html(month); >- $("#newMonth").val(month); >- $("#newYearOutput").html(year); >- $("#newYear").val(year); >- $("#newWeekday:first").val(weekDay); >- } >- >- function hidePanel(aPanelName) { >- $("#"+aPanelName).slideUp("fast"); >- } >- >- function changeBranch () { >- var branch = $("#branch option:selected").val(); >- location.href='/cgi-bin/koha/tools/holidays.pl?branch=' + branch + '&calendardate=' + "[% calendardate %]"; >- } >- >- function Help() { >- newin=window.open("/cgi-bin/koha/help.pl","KohaHelp",'width=600,height=600,toolbar=false,scrollbars=yes'); >- } >- >- /* This function gives css clases to each kind of day */ >- function dateStatusHandler(date) { >- date = new Date(date); >- var day = date.getDate(); >- var month = date.getMonth() + 1; >- var year = date.getFullYear(); >- var weekDay = date.getDay(); >- var dayMonth = month + '/' + day; >- var dateString = year + '/' + month + '/' + day; >- if (exception_holidays[dateString] != null) { >- return [true, "exception", _("Exception: %s").format(exception_holidays[dateString].title)]; >- } else if ( week_days[weekDay] != null ){ >- return [true, "repeatableweekly", _("Weekly holiday: %s").format(week_days[weekDay].title)]; >- } else if ( day_month_holidays[dayMonth] != null ) { >- return [true, "repeatableyearly", _("Yearly holiday: %s").format(day_month_holidays[dayMonth].title)]; >- } else if (holidays[dateString] != null) { >- return [true, "holiday", _("Single holiday: %s").format(holidays[dateString].title)]; >- } else { >- return [true, "normalday", _("Normal day")]; >- } >- } >- >- /* This function is in charge of showing the correct panel considering the kind of holiday */ >- function dateChanged(calendar) { >- calendar = new Date(calendar); >- var day = calendar.getDate(); >- var month = calendar.getMonth() + 1; >- var year = calendar.getFullYear(); >- var weekDay = calendar.getDay(); >- var dayName = weekdays[weekDay]; >- var dayMonth = month + '/' + day; >- var dateString = year + '/' + month + '/' + day; >- if (holidays[dateString] != null) { >- showHoliday(0, dayName, day, month, year, weekDay, holidays[dateString].title, holidays[dateString].description, 'ymd'); >- } else if (exception_holidays[dateString] != null) { >- showHoliday(0, dayName, day, month, year, weekDay, exception_holidays[dateString].title, exception_holidays[dateString].description, 'exception'); >- } else if (week_days[weekDay] != null) { >- showHoliday(1, dayName, day, month, year, weekDay, week_days[weekDay].title, week_days[weekDay].description, 'weekday'); >- } else if (day_month_holidays[dayMonth] != null) { >- showHoliday(1, dayName, day, month, year, weekDay, day_month_holidays[dayMonth].title, day_month_holidays[dayMonth].description, 'daymonth'); >- } else { >- newHoliday(dayName, day, month, year, weekDay); >- } >- }; >- >- $(document).ready(function() { >- >- $(".hint").hide(); >- $("#branch").change(function(){ >- changeBranch(); >- }); >- $("#holidayweeklyrepeatable>tbody>tr").each(function(){ >- var first_td = $(this).find('td').first(); >- first_td.html(weekdays[first_td.html()]); >- }); >- $("#holidayweeklyrepeatable").dataTable($.extend(true, {}, dataTablesDefaults, { >- "sDom": 't', >- "bPaginate": false >- })); >- $("#holidayexceptions,#holidaysyearlyrepeatable,#holidaysunique").dataTable($.extend(true, {}, dataTablesDefaults, { >- "sDom": 't', >- "aoColumns": [ >- { "sType": "title-string" },null,null >- ], >- "bPaginate": false >- })); >- $("a.helptext").click(function(){ >- $(this).parent().find(".hint").toggle(); return false; >- }); >- $("#dateofrange").datepicker(); >- $("#datecancelrange").datepicker(); >- $("#dateofrange").each(function () { this.value = "" }); >- $("#datecancelrange").each(function () { this.value = "" }); >- $("#jcalendar-container").datepicker({ >- beforeShowDay: function(thedate) { >- var day = thedate.getDate(); >- var month = thedate.getMonth() + 1; >- var year = thedate.getFullYear(); >- var dateString = year + '/' + month + '/' + day; >- return dateStatusHandler(dateString); >- }, >- onSelect: function(dateText, inst) { >- dateChanged($(this).datepicker("getDate")); >- }, >- defaultDate: new Date("[% keydate %]") >- }); >- }); >-//]]> >-</script> >-<style type="text/css"> .key { padding : 3px; white-space:nowrap; line-height:230%; } >-.ui-datepicker { font-size : 150%; } >-.ui-datepicker th, .ui-datepicker .ui-datepicker-title select { font-size : 80%; } >-.ui-datepicker td a { padding : .5em; } >-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { font-size : 80%; } >-.key { padding : 3px; white-space:nowrap; line-height:230%; } >-.normalday { background-color : #EDEDED; color : Black; border : 1px solid #BCBCBC; } >-.exception { background-color : #b3d4ff; color : Black; border : 1px solid #BCBCBC; } >-.holiday { background-color : #ffaeae; color : Black; border : 1px solid #BCBCBC; } >-.repeatableweekly { background-color : #FFFF99; color : Black; border : 1px solid #BCBCBC; } >-.repeatableyearly { background-color : #FFCC66; color : Black; border : 1px solid #BCBCBC; } >-td.exception a.ui-state-default { background: #b3d4ff none; color : Black; border : 1px solid #BCBCBC; } >-td.holiday a.ui-state-default { background: #ffaeae none; color : Black; border : 1px solid #BCBCBC; } >-td.repeatableweekly a.ui-state-default { background: #FFFF99 none; color : Black; border : 1px solid #BCBCBC; } >-td.repeatableyearly a.ui-state-default { background: #FFCC66 none; color : Black; border : 1px solid #BCBCBC; } >-.information { z-index : 1; background-color : #DCD2F1; width : 300px; display : none; border : 1px solid #000000; color : #000000; font-size : 8pt; font-weight : bold; background-color : #FFD700; cursor : pointer; padding : 2px; } >-.panel { z-index : 1; display : none; border : 3px solid #CCC; padding : 3px; margin-top: .3em; background-color: #FEFEFE; } fieldset.brief { border : 0; margin-top: 0; } >-#showHoliday { margin : .5em 0; } h1 select { width: 20em; } div.yui-b fieldset.brief ol { font-size:100%; } div.yui-b fieldset.brief li, div.yui-b fieldset.brief li.radio { padding:0.2em 0; } .help { margin:.3em 0;border:1px solid #EEE;padding:.3em .7em; font-size : 90%; } #holidayweeklyrepeatable, #holidaysyearlyrepeatable, #holidaysunique, #holidayexceptions { font-size : 90%; margin-bottom : 1em;} .calendar td, .calendar th, .calendar .button, .calendar tbody .day { padding : .7em; font-size: 110%; } .calendar { width: auto; border : 0; } >-</style> >-</head> >-<body id="tools_holidays" class="tools"> >-[% INCLUDE 'header.inc' %] >-[% INCLUDE 'cat-search.inc' %] >- >-<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › [% branchname %] calendar</div> >- >-<div id="doc3" class="yui-t1"> >- >- <div id="bd"> >- <div id="yui-main"> >- <div class="yui-b"> >- <h2>[% branchname %] calendar</h2> >- <div class="yui-g"> >- <div class="yui-u first"> >- <label for="branch">Define the holidays for:</label> >- <select id="branch" name="branch"> >- [% FOREACH branchloo IN branchloop %] >- [% IF ( branchloo.selected ) %] >- <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option> >- [% ELSE %] >- <option value="[% branchloo.value %]">[% branchloo.branchname %]</option> >- [% END %] >- [% END %] >- </select> >- >- <!-- ******************************** FLAT PANELS ******************************************* --> >- <!-- ***** Makes all the flat panel to deal with holidays ***** --> >- <!-- **************************************************************************************** --> >- >- <!-- ********************** Panel for showing already loaded holidays *********************** --> >- <div class="panel" id="showHoliday"> >- <form action="/cgi-bin/koha/tools/exceptionHolidays.pl" method="post"> >- <input type="hidden" id="showHolidayType" name="showHolidayType" value="" /> >- <fieldset class="brief"> >- <h3>Edit this holiday</h3> >- <span id="holtype"></span> >- <ol> >- <li> >- <strong>Library:</strong> <span id="showBranchNameOutput"></span> >- <input type="hidden" id="showBranchName" name="showBranchName" /> >- </li> >- <li> >- <strong>From date:</strong> >- <span id="showDaynameOutput"></span>, >- >- [% IF ( dateformat == "us" ) %]<span id="showMonthOutput"></span>/<span id="showDayOutput"></span>/<span id="showYearOutput"></span>[% ELSIF ( dateformat == "metric" ) %]<span id="showDayOutput"></span>/<span id="showMonthOutput"></span>/<span id="showYearOutput"></span>[% ELSE %]<span id="showYearOutput"></span>/<span id="showMonthOutput"></span>/<span id="showDayOutput"></span>[% END %] >- >- <input type="hidden" id="showDayname" name="showDayname" /> >- <input type="hidden" id="showWeekday" name="showWeekday" /> >- <input type="hidden" id="showDay" name="showDay" /> >- <input type="hidden" id="showMonth" name="showMonth" /> >- <input type="hidden" id="showYear" name="showYear" /> >- </li> >- <li class="dateinsert"> >- <b>To Date : </b> >- <input type="text" id="datecancelrange" name="datecancelrange" size="20" value="[% datecancelrange %]" class="datepicker"/> >- </li> >- <li><label for="showTitle">Title: </label><input type="text" name="showTitle" id="showTitle" size="35" /></li> >- <!-- showTitle is necessary for exception radio button to work properly --> >- <li> >- <label for="showDescription">Description:</label> >- <textarea rows="2" cols="40" id="showDescription" name="showDescription"></textarea> >- </li> >- <li class="radio"><div id="exceptionPosibility" style="position:static"> >- <input type="radio" name="showOperation" id="showOperationExc" value="exception" /> <label for="showOperationExc">Generate an exception for this repeated holiday.</label> >- <a href="#" class="helptext">[?]</a> >- <div class="hint">You can make an exception for this holiday rule. This means that you will be able to say that for a repeatable holiday there is one day which is going to be an exception.</div> >- </div></li> >- <li class="radio"><input type="radio" name="showOperation" id="showOperationExcRange" value="exceptionrange" /> >- <label for="showOperationExcRange">Generate exceptions on a range of dates.</label> >- <a href="#" class="helptext">[?]</a> >- <div class="hint">You can make an exception on a range of dates repeated yearly.</div> >- </li> >- <li class="radio"><input type="radio" name="showOperation" id="showOperationDel" value="delete" /> <label for="showOperationDel" id="showOperationDelLabel">Delete this holiday</label> >- <a href="#" class="helptext">[?]</a> >- <div class="hint">This will delete this holiday rule. If it is a repeatable holiday, this option checks for possible exceptions. If an exception exists, this option will remove the exception and set the date to a regular holiday.</div></li> >- <li class="radio"><input type="radio" name="showOperation" id="showOperationDelRange" value="deleterange" /> <label for="showOperationDelRange" id="showOperationDelLabelRange">Delete the single holidays on a range</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">This will delete the single holidays rules only. The repeatable holidays and exceptions will not be deleted.</div> >- </li> >- <li class="radio"><input type="radio" name="showOperation" id="showOperationDelRangeRepeat" value="deleterangerepeat" /> <label for="showOperationDelRangeRepeat" id="showOperationDelLabelRangeRepeat">Delete the repeated holidays on a range</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">This will delete the repeated holidays rules only. The repeatable holidays will be deleted but not the exceptions.</div> >- </li> >- <li class="radio"><input type="radio" name="showOperation" id="showOperationDelRangeRepeatExcept" value="deleterangerepeatexcept" /> <label for="showOperationDelRangeRepeatExcept" id="showOperationDelLabelRangeRepeatExcept">Delete the exceptions on a range</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">This will delete the exceptions inside a given range. Be careful about your scope range if it is oversized you could slow down Koha.</div> >- </li> >- <li class="radio"><input type="radio" name="showOperation" id="showOperationEdit" value="edit" checked="checked" /> <label for="showOperationEdit">Edit this holiday</label> >- <a href="#" class="helptext">[?]</a> >- <div class="hint">This will save changes to the holiday's title and description. If the information for a repeatable holiday is modified, it affects all of the dates on which the holiday is repeated.</div></li> >- </ol> >- <fieldset class="action"> >- <input type="submit" name="submit" value="Save" /> >- <a href="#" class="cancel" onclick=" hidePanel('showHoliday');">Cancel</a> >- </fieldset> >- </fieldset> >- </form> >- </div> >- >- <!-- ***************************** Panel to deal with new holidays ********************** --> >- <div class="panel" id="newHoliday"> >- <form action="/cgi-bin/koha/tools/newHolidays.pl" method="post"> >- <input type="hidden" name="branchCodes" id="branchCodes" value="[% branchcodes %]" /> >- <fieldset class="brief"> >- <h3>Add new holiday</h3> >- <ol> >- <li> >- <strong>Library:</strong> >- <span id="newBranchNameOutput"></span> >- <input type="hidden" id="newBranchName" name="newBranchName" /> >- </li> >- <li> >- <strong>From date:</strong> >- <span id="newDaynameOutput"></span>, >- >- [% IF ( dateformat == "us" ) %]<span id="newMonthOutput"></span>/<span id="newDayOutput"></span>/<span id="newYearOutput"></span>[% ELSIF ( dateformat == "metric" ) %]<span id="newDayOutput"></span>/<span id="newMonthOutput"></span>/<span id="newYearOutput"></span>[% ELSE %]<span id="newYearOutput"></span>/<span id="newMonthOutput"></span>/<span id="newDayOutput"></span>[% END %] >- >- <input type="hidden" id="newDayname" name="showDayname" /> >- <input type="hidden" id="newWeekday" name="newWeekday" /> >- <input type="hidden" id="newDay" name="newDay" /> >- <input type="hidden" id="newMonth" name="newMonth" /> >- <input type="hidden" id="newYear" name="newYear" /> >- </li> >- <li class="dateinsert"> >- <b>To date: </b> >- <input type="text" id="dateofrange" name="dateofrange" size="20" value="[% dateofrange %]" class="datepicker" /> >- </li> >- <li><label for="title">Title: </label><input type="text" name="newTitle" id="title" size="35" /></li> >- <li><label for="newDescription">Description:</label> >- <textarea rows="2" cols="40" id="newDescription" name="newDescription"></textarea> >- </li> >- <li class="radio"><input type="radio" name="newOperation" id="newOperationOnce" value="holiday" checked="checked" /> >- <label for="newOperationOnce">Holiday only on this day</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">Make a single holiday. For example, selecting August 1, 2012 will make it a holiday, but will not affect August 1 in other years.</div> >- </li> >- <li class="radio"><input type="radio" name="newOperation" id="newOperationDay" value="weekday" /> >- <label for="newOperationDay">Holiday repeated every same day of the week</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">Make this weekday a holiday, every week. For example, if your library is closed on Saturdays, use this option to make every Saturday a holiday.</div> >- </li> >- <li class="radio"><input type="radio" name="newOperation" id="newOperationYear" value="repeatable" /> >- <label for="newOperationYear">Holiday repeated yearly on the same date</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">This will take this day and month as a reference to make it a holiday. Through this option, you can repeat this rule for every year. For example, selecting August 1 will make August 1 a holiday every year.</div> >- </li> >- <li class="radio"><input type="radio" name="newOperation" id="newOperationField" value="holidayrange" /> >- <label for="newOperationField">Holidays on a range</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">Make a single holiday on a range. For example, selecting August 1, 2012 and August 10, 2012 will make all days between August 1 and 10 a holiday, but will not affect August 1-10 in other years.</div> >- </li> >- <li class="radio"><input type="radio" name="newOperation" id="newOperationFieldyear" value="holidayrangerepeat" /> >- <label for="newOperationFieldyear">Holidays repeated yearly on a range</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">Make a single holiday on a range repeated yearly. For example, selecting August 1, 2012 and August 10, 2012 will make all days between August 1 and 10 a holiday, and will affect August 1-10 in other years.</div> >- </li> >- <li class="radio"> >- <input type="checkbox" name="allBranches" id="allBranches" /> >- <label for="allBranches">Copy to all libraries</label>. >- <a href="#" class="helptext">[?]</a> >- <div class="hint">If checked, this holiday will be copied to all libraries. If the holiday already exists for a library, no change is made.</div> >- </li></ol> >- <fieldset class="action"> >- <input type="submit" name="submit" value="Save" /> >- <a href="#" class="cancel" onclick=" hidePanel('newHoliday');">Cancel</a> >- </fieldset> >- </fieldset> >- </form> >- </div> >- >- <!-- *************************************************************************************** --> >- <!-- ****** END OF FLAT PANELS ****** --> >- <!-- *************************************************************************************** --> >- >-<!-- ************************************************************************************** --> >-<!-- ****** MAIN SCREEN CODE ****** --> >-<!-- ************************************************************************************** --> >-<h3>Calendar information</h3> >-<div id="jcalendar-container"></div> >- >-<div style="margin-top: 2em;"> >-<form action="copy-holidays.pl" method="post"> >- <input type="hidden" name="from_branchcode" value="[% branch %]" /> >- <label for="branchcode">Copy holidays to:</label> >- <select id="branchcode" name="branchcode"> >- <option value=""></option> >- [% FOREACH branchloo IN branchloop %] >- <option value="[% branchloo.value %]">[% branchloo.branchname %]</option> >- [% END %] >- </select> >- <input type="submit" value="Copy" /> >-</form> >-</div> >- >-</div> >-<div class="yui-u"> >-<div class="help"> >-<h4>Hints</h4> >- <ul> >- <li>Search in the calendar the day you want to set as holiday.</li> >- <li>Click the date to add or edit a holiday.</li> >- <li>Enter a title and description for the holiday.</li> >- <li>Specify how the holiday should repeat.</li> >- <li>Click Save to finish.</li> >- </ul> >-<h4>Key</h4> >- <p> >- <span class="key normalday">Working day</span> >- <span class="key holiday">Unique holiday</span> >- <span class="key repeatableweekly">Holiday repeating weekly</span> >- <span class="key repeatableyearly">Holiday repeating yearly</span> >- <span class="key exception">Holiday exception</span> >- </p> >-</div> >-<div id="holiday-list"> >-<!-- Exceptions First --> >-<!-- this will probably always have the least amount of data --> >-[% IF ( EXCEPTION_HOLIDAYS_LOOP ) %] >-<h3>Exceptions</h3> >- <table id="holidayexceptions"> >-<thead><tr> >- <th class="exception">Date</th> >- <th class="exception">Title</th> >- <th class="exception">Description</th> >-</tr> >-</thead> >-<tbody> >- [% FOREACH EXCEPTION_HOLIDAYS_LOO IN EXCEPTION_HOLIDAYS_LOOP %] >- <tr> >- <td><a href="/cgi-bin/koha/tools/holidays.pl?branch=[% branch %]&calendardate=[% EXCEPTION_HOLIDAYS_LOO.DATE %]"><span title="[% EXCEPTION_HOLIDAYS_LOO.DATE_SORT %]">[% EXCEPTION_HOLIDAYS_LOO.DATE %]</span></a></td> >- <td>[% EXCEPTION_HOLIDAYS_LOO.TITLE %]</td> >- <td>[% EXCEPTION_HOLIDAYS_LOO.DESCRIPTION %]</td> >- </tr> >- [% END %] >-</tbody> >-</table> >-[% END %] >- >-[% IF ( WEEK_DAYS_LOOP ) %] >-<h3>Weekly - Repeatable holidays</h3> >-<table id="holidayweeklyrepeatable"> >-<thead> >-<tr> >- <th class="repeatableweekly">Day of week</th> >- <th class="repeatableweekly">Title</th> >- <th class="repeatableweekly">Description</th> >-</tr> >-</thead> >-<tbody> >- [% FOREACH WEEK_DAYS_LOO IN WEEK_DAYS_LOOP %] >- <tr> >- <td>[% WEEK_DAYS_LOO.KEY %]</td> >- </td> >- <td>[% WEEK_DAYS_LOO.TITLE %]</td> >- <td>[% WEEK_DAYS_LOO.DESCRIPTION %]</td> >- </tr> >- [% END %] >-</tbody> >-</table> >-[% END %] >- >-[% IF ( DAY_MONTH_HOLIDAYS_LOOP ) %] >-<h3>Yearly - Repeatable holidays</h3> >-<table id="holidaysyearlyrepeatable"> >-<thead> >-<tr> >- [% IF ( dateformat == "metric" ) %] >- <th class="repeatableyearly">Day/month</th> >- [% ELSE %] >- <th class="repeatableyearly">Month/day</th> >- [% END %] >- <th class="repeatableyearly">Title</th> >- <th class="repeatableyearly">Description</th> >-</tr> >-</thead> >-<tbody> >- [% FOREACH DAY_MONTH_HOLIDAYS_LOO IN DAY_MONTH_HOLIDAYS_LOOP %] >- <tr> >- <td><span title="[% DAY_MONTH_HOLIDAYS_LOO.DATE_SORT %]">[% DAY_MONTH_HOLIDAYS_LOO.DATE %]</span></td> >- <td>[% DAY_MONTH_HOLIDAYS_LOO.TITLE %]</td> >- <td>[% DAY_MONTH_HOLIDAYS_LOO.DESCRIPTION %]</td> >- </tr> >- [% END %] >-</tbody> >-</table> >-[% END %] >- >-[% IF ( HOLIDAYS_LOOP ) %] >-<h3>Unique holidays</h3> >-<table id="holidaysunique"> >-<thead> >-<tr> >- <th class="holiday">Date</th> >- <th class="holiday">Title</th> >- <th class="holiday">Description</th> >-</tr> >-</thead> >-<tbody> >- [% FOREACH HOLIDAYS_LOO IN HOLIDAYS_LOOP %] >-<tr> >- <td><a href="/cgi-bin/koha/tools/holidays.pl?branch=[% branch %]&calendardate=[% HOLIDAYS_LOO.DATE %]"><span title="[% HOLIDAYS_LOO.DATE_SORT %]">[% HOLIDAYS_LOO.DATE %]</span></a></td> >- <td>[% HOLIDAYS_LOO.TITLE %]</td> >- <td>[% HOLIDAYS_LOO.DESCRIPTION %]</td> >-</tr> >- [% END %] >-</tbody> >-</table> >-[% END %] >-</div> >-</div> >-</div> >-</div> >-</div> >- >-<div class="yui-b noprint"> >-[% INCLUDE 'tools-menu.inc' %] >-</div> >-</div> >-[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >index a87857c..c24f221 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >@@ -73,7 +73,7 @@ > <h3>Additional tools</h3> > <dl> > [% IF ( CAN_user_tools_edit_calendar ) %] >- <dt><a href="/cgi-bin/koha/tools/holidays.pl">Calendar</a></dt> >+ <dt><a href="/cgi-bin/koha/tools/calendar.pl">Calendar</a></dt> > <dd>Define days when the library is closed</dd> > [% END %] > >diff --git a/misc/cronjobs/staticfines.pl b/misc/cronjobs/staticfines.pl >index 2520fc5..f3fc98d 100755 >--- a/misc/cronjobs/staticfines.pl >+++ b/misc/cronjobs/staticfines.pl >@@ -40,9 +40,10 @@ use Date::Calc qw/Date_to_Days/; > use C4::Context; > use C4::Circulation; > use C4::Overdues; >-use C4::Calendar qw(); # don't need any exports from Calendar > use C4::Biblio; > use C4::Debug; # supplying $debug and $cgi_debug >+use Koha::Calendar; >+ > use Getopt::Long; > use List::MoreUtils qw/none/; > use Koha::DateUtils; >@@ -172,10 +173,14 @@ for ( my $i = 0 ; $i < scalar(@$data) ; $i++ ) { > > my $calendar; > unless ( defined( $calendars{$branchcode} ) ) { >- $calendars{$branchcode} = C4::Calendar->new( branchcode => $branchcode ); >+ $calendars{$branchcode} = Koha::Calendar->new( branchcode => $branchcode ); > } > $calendar = $calendars{$branchcode}; >- my $isHoliday = $calendar->isHoliday( $tday, $tmonth, $tyear ); >+ my $isHoliday = $calendar->is_holiday( DateTime->new( >+ year => $tyear, >+ month => $tmonth, >+ day => $tday >+ ) ); > > # Reassing datedue_days if -delay specified in commandline > $bigdebug and warn "Using commandline supplied delay : $delay" if ($delay); >diff --git a/misc/cronjobs/thirdparty/TalkingTech_itiva_outbound.pl b/misc/cronjobs/thirdparty/TalkingTech_itiva_outbound.pl >index d7054c2..3b256a0 100755 >--- a/misc/cronjobs/thirdparty/TalkingTech_itiva_outbound.pl >+++ b/misc/cronjobs/thirdparty/TalkingTech_itiva_outbound.pl >@@ -37,7 +37,7 @@ use C4::Items; > use C4::Letters; > use C4::Overdues; > use C4::Dates; >-use C4::Calendar; >+use Koha::Calendar; > > sub usage { > pod2usage( -verbose => 2 ); >@@ -312,23 +312,18 @@ sub GetWaitingHolds { > sprintf( "%04d-%02d-%02d", $date_due[0], $date_due[1], $date_due[2] ); > $issue->{'level'} = 1; # only one level for Hold Waiting notifications > >- my $days_to_subtract = 0; >- my $calendar = C4::Calendar->new( branchcode => $issue->{'site'} ); >- while ( >- $calendar->isHoliday( >- reverse( >- Add_Delta_Days( >- $waitingdate[0], $waitingdate[1], >- $waitingdate[2], $days_to_subtract >- ) >- ) >- ) >- ) >- { >- $days_to_subtract++; >- } >- $issue->{'days_since_waiting'} = >- $issue->{'days_since_waiting'} - $days_to_subtract; >+ my $calendar = Koha::Calendar->new( branchcode => $issue->{'site'} ); >+ $issue->{'days_since_waiting'} = $calendar->days_between( >+ DateTime->new( >+ year => $waitingdate[0], >+ month => $waitingdate[1], >+ day => $waitingdate[2], >+ time_zone => C4::Context->tz, >+ ), >+ DateTime->now( >+ time_zone => C4::Context->tz, >+ ), >+ ); > > if ( > ( >diff --git a/t/Calendar.t b/t/Calendar.t >index 8648968..8c30c77 100755 >--- a/t/Calendar.t >+++ b/t/Calendar.t >@@ -4,17 +4,13 @@ use strict; > use warnings; > use DateTime; > use DateTime::Duration; >-use Test::More tests => 35; >+use Test::More tests => 34; > use Test::MockModule; > use DBD::Mock; > use Koha::DateUtils; > > BEGIN { > use_ok('Koha::Calendar'); >- >- # This was the only test C4 had >- # Remove when no longer used >- use_ok('C4::Calendar'); > } > > my $module_context = new Test::MockModule('C4::Context'); >diff --git a/t/db_dependent/Calendar.t b/t/db_dependent/Calendar.t >new file mode 100644 >index 0000000..162e09b >--- /dev/null >+++ b/t/db_dependent/Calendar.t >@@ -0,0 +1,86 @@ >+use Modern::Perl; >+ >+use Test::More tests => 14; >+ >+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, >+ 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' ); >+ >+# Weekly events >+ModRepeatingEvent( 'UPL', { weekday => 1, %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' ); >+ >+$new_holiday{close_hour} = 24; >+ >+ModRepeatingEvent( 'UPL', { weekday => 1, %new_holiday } ); >+$weekly_events = GetWeeklyEvents( 'UPL' ); >+is( scalar @$weekly_events, 0, 'weekly modification, not insertion' ); >+ >+$new_holiday{close_hour} = 0; >+ModRepeatingEvent( 'UPL', { weekday => 1, %new_holiday } ); >+ >+# Yearly events >+ >+ModRepeatingEvent( 'UPL', { month => 6, day => 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' ); >+ >+$new_holiday{close_hour} = 24; >+ >+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 } ); >+ >+# Single events >+ >+ModSingleEvent( 'UPL', { date => '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' ); >+ >+$new_holiday{close_hour} = 24; >+ >+ModSingleEvent( 'UPL', { date => '2013-03-17', %new_holiday } ); >+$single_events = GetSingleEvents( 'UPL' ); >+is( scalar @$single_events, 1, 'single modification, not insertion' ); >+is( $single_events->[0]->{'closed'}, 0, 'single closed' ); >+ >+ >+# delete >+ >+DelRepeatingEvent( 'UPL', { weekday => 1 } ); >+$weekly_events = GetWeeklyEvents( 'UPL' ); >+is( scalar @$weekly_events, 0, 'weekly deleted' ); >+ >+DelRepeatingEvent( 'UPL', { month => 6, day => 26 } ); >+$yearly_events = GetYearlyEvents( 'UPL' ); >+is( scalar @$yearly_events, 0, 'yearly deleted' ); >+ >+DelSingleEvent( 'UPL', { date => '2013-03-17' } ); >+ >+$single_events = GetSingleEvents( 'UPL' ); >+is( scalar @$single_events, 0, 'single deleted' ); >+ >+$dbh->rollback; >diff --git a/t/db_dependent/Holidays.t b/t/db_dependent/Holidays.t >index 75bbc1c..3541e98 100755 >--- a/t/db_dependent/Holidays.t >+++ b/t/db_dependent/Holidays.t >@@ -5,11 +5,9 @@ use DateTime; > use DateTime::TimeZone; > > use C4::Context; >-use Koha::DateUtils; >-use Test::More tests => 12; >+use Test::More tests => 6; > > BEGIN { use_ok('Koha::Calendar'); } >-BEGIN { use_ok('C4::Calendar'); } > > my $dbh = C4::Context->dbh(); > # Start transaction >@@ -19,10 +17,8 @@ $dbh->{RaiseError} = 1; > my $branchcode = 'MPL'; > > my $koha_calendar = Koha::Calendar->new( branchcode => $branchcode ); >-my $c4_calendar = C4::Calendar->new( branchcode => $branchcode ); > > isa_ok( $koha_calendar, 'Koha::Calendar', 'Koha::Calendar class returned' ); >-isa_ok( $c4_calendar, 'C4::Calendar', 'C4::Calendar class returned' ); > > my $sunday = DateTime->new( > year => 2011, >@@ -49,26 +45,3 @@ is( $koha_calendar->is_holiday($sunday), 1, 'Sunday is a closed day' ); > is( $koha_calendar->is_holiday($monday), 0, 'Monday is not a closed day' ); > is( $koha_calendar->is_holiday($christmas), 1, 'Christmas is a closed day' ); > is( $koha_calendar->is_holiday($newyear), 1, 'New Years day is a closed day' ); >- >-$dbh->do("DELETE FROM repeatable_holidays"); >-$dbh->do("DELETE FROM special_holidays"); >- >-my $custom_holiday = DateTime->new( >- year => 2013, >- month => 11, >- day => 12, >-); >-is( $koha_calendar->is_holiday($custom_holiday), 0, '2013-11-10 does not start off as a holiday' ); >-$koha_calendar->add_holiday($custom_holiday); >-is( $koha_calendar->is_holiday($custom_holiday), 1, 'able to add holiday for testing' ); >- >-my $today = dt_from_string(); >-C4::Calendar->new( branchcode => 'CPL' )->insert_single_holiday( >- day => $today->day(), >- month => $today->month(), >- year => $today->year(), >- title => "$today", >- description => "$today", >-); >-is( Koha::Calendar->new( branchcode => 'CPL' )->is_holiday( $today ), 1, "Today is a holiday for CPL" ); >-is( Koha::Calendar->new( branchcode => 'MPL' )->is_holiday( $today ), 0, "Today is not a holiday for MPL"); >diff --git a/tools/calendar.pl b/tools/calendar.pl >new file mode 100755 >index 0000000..d4bcf48 >--- /dev/null >+++ b/tools/calendar.pl >@@ -0,0 +1,268 @@ >+#!/usr/bin/perl >+ >+# 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 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 <http://www.gnu.org/licenses>. >+ >+#####Sets holiday periods for each branch. Datedues will be extended if branch is closed -TG >+ >+use Modern::Perl; >+ >+use CGI; >+ >+use C4::Auth; >+use C4::Output; >+ >+use C4::Branch; # GetBranches >+use C4::Calendar; >+ >+my $input = new CGI; >+ >+my $dbh = C4::Context->dbh(); >+# Get the template to use >+my ($template, $loggedinuser, $cookie) >+ = get_template_and_user({template_name => "tools/calendar.tt", >+ type => "intranet", >+ query => $input, >+ authnotrequired => 0, >+ flagsrequired => {tools => 'edit_calendar'}, >+ debug => 1, >+ }); >+ >+# keydate - date passed to calendar.js. calendar.js does not process dashes within a date. >+my $keydate; >+# calendardate - date passed in url for human readability (syspref) >+my $calendardate; >+my $today = C4::Dates->new(); >+my $calendarinput = C4::Dates->new($input->param('calendardate')) || $today; >+# if the url has an invalid date default to 'now.' >+unless($calendardate = $calendarinput->output('syspref')) { >+ $calendardate = $today->output('syspref'); >+} >+unless($keydate = $calendarinput->output('iso')) { >+ $keydate = $today->output('iso'); >+} >+$keydate =~ s/-/\//g; >+ >+my $branch= $input->param('branchName') || $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 ) { >+ $branch = C4::Context->userenv->{'branch'}; >+} >+my $branchname = GetBranchName($branch); >+my $branches = GetBranches($onlymine); >+my @branchloop; >+for my $thisbranch ( >+ sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } >+ keys %{$branches} ) { >+ push @branchloop, >+ { value => $thisbranch, >+ selected => $thisbranch eq $branch, >+ branchname => $branches->{$thisbranch}->{'branchname'}, >+ }; >+} >+ >+# branches calculated - put branch codes in a single string so they can be passed in a form >+my $branchcodes = join '|', keys %{$branches}; >+ >+my $op = $input->param( 'op' ) // ''; >+ >+my @ranged_dates; >+ >+if ( my $dateofrange = $input->param( 'dateofrange' ) ) { >+ my $date = $input->param( 'year' ) . '-' . $input->param( 'month' ) . '-' . $input->param( 'day' ); >+ >+ my ( $start_year, $start_month, $start_day ) = split( /-/, $date ); >+ my ( $end_year, $end_month, $end_day ) = split( /-/, C4::Dates->new( $dateofrange )->output( 'iso' ) ); >+ >+ if ( $end_year && $end_month && $end_day ){ >+ my $first_dt = DateTime->new(year => $start_year, month => $start_month, day => $start_day); >+ my $end_dt = DateTime->new(year => $end_year, month => $end_month, day => $end_day); >+ >+ for ( my $dt = $first_dt->clone(); $dt <= $end_dt; $dt->add(days => 1) ) { >+ push @ranged_dates, $dt->clone(); >+ } >+ } >+} >+ >+my @branches; >+if ( $input->param( 'allBranches' ) || !$input->param( 'branchName' ) ) { >+ @branches = split /\|/, $input->param( 'branchcodes' ); >+} else { >+ @branches = ( $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 ); >+ >+ if ( $input->param( 'hoursType' ) eq 'open' ) { >+ ( $open_hour, $open_minute ) = ( 0, 0 ); >+ ( $close_hour, $close_minute ) = ( 24, 0 ); >+ } elsif ( $input->param( 'hoursType' ) eq 'closed' ) { >+ ( $open_hour, $open_minute ) = ( 0, 0 ); >+ ( $close_hour, $close_minute ) = ( 0, 0 ); >+ } else { >+ ( $open_hour, $open_minute ) = ( $input->param( 'openTime' ) =~ /(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])/ ); >+ ( $close_hour, $close_minute ) = ( $input->param( 'closeTime' ) =~ /(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9])/ ); >+ } >+ >+ foreach my $branchcode ( @branches ) { >+ my %event_types = ( >+ 'single' => sub { >+ ModSingleEvent( $branchcode, { >+ date => $date, >+ title => $input->param( 'title' ), >+ description => $input->param( 'description' ), >+ open_hour => $open_hour, >+ open_minute => $open_minute, >+ close_hour => $close_hour, >+ close_minute => $close_minute >+ } ); >+ }, >+ >+ 'weekly' => sub { >+ ModRepeatingEvent( $branchcode, { >+ weekday => $input->param( 'weekday' ), >+ title => $input->param( 'title' ), >+ description => $input->param( 'description' ), >+ open_hour => $open_hour, >+ open_minute => $open_minute, >+ close_hour => $close_hour, >+ close_minute => $close_minute >+ } ); >+ }, >+ >+ 'yearly' => sub { >+ ModRepeatingEvent( $branchcode, { >+ month => $input->param( 'month' ), >+ day => $input->param( 'day' ), >+ title => $input->param( 'title' ), >+ description => $input->param( 'description' ), >+ open_hour => $open_hour, >+ open_minute => $open_minute, >+ close_hour => $close_hour, >+ close_minute => $close_minute >+ } ); >+ }, >+ >+ 'singlerange' => sub { >+ foreach my $dt ( @ranged_dates ) { >+ ModSingleEvent( $branchcode, { >+ date => $dt->ymd, >+ title => $input->param( 'title' ), >+ description => $input->param( 'description' ), >+ open_hour => $open_hour, >+ open_minute => $open_minute, >+ close_hour => $close_hour, >+ close_minute => $close_minute >+ } ); >+ } >+ }, >+ >+ 'yearlyrange' => sub { >+ foreach my $dt ( @ranged_dates ) { >+ ModRepeatingEvent( $branchcode, { >+ month => $dt->month, >+ day => $dt->day, >+ title => $input->param( 'title' ), >+ description => $input->param( 'description' ), >+ open_hour => $open_hour, >+ open_minute => $open_minute, >+ close_hour => $close_hour, >+ 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' ) }->(); >+ } >+} elsif ( $op eq 'deleterange' ) { >+ foreach my $branchcode ( @branches ) { >+ foreach my $dt ( @ranged_dates ) { >+ DelSingleEvent( $branchcode, { date => $dt->ymd } ); >+ } >+ } >+} elsif ( $op eq 'deleterangerepeat' ) { >+ foreach my $branchcode ( @branches ) { >+ foreach my $dt ( @ranged_dates ) { >+ DelRepeatingEvent( $branchcode, { month => $dt->month, day => $dt->day } ); >+ } >+ } >+} elsif ( $op eq 'copyall' ) { >+ CopyAllEvents( $input->param( 'from_branchcode' ), $input->param( 'branchcode' ) ); >+} >+ >+my $yearly_events = GetYearlyEvents($branch); >+foreach my $event ( @$yearly_events ) { >+ # Determine date format on month and day. >+ my $day_monthdate; >+ my $day_monthdate_sort; >+ if (C4::Context->preference("dateformat") eq "metric") { >+ $day_monthdate_sort = "$event->{month}-$event->{day}"; >+ $day_monthdate = "$event->{day}/$event->{month}"; >+ } elsif (C4::Context->preference("dateformat") eq "us") { >+ $day_monthdate = "$event->{month}/$event->{day}"; >+ $day_monthdate_sort = $day_monthdate; >+ } else { >+ $day_monthdate = "$event->{month}-$event->{day}"; >+ $day_monthdate_sort = $day_monthdate; >+ } >+ >+ $event->{month_day_display} = $day_monthdate; >+ $event->{month_day_sort} = $day_monthdate_sort; >+} >+ >+$template->param( >+ weekly_events => GetWeeklyEvents($branch), >+ yearly_events => $yearly_events, >+ single_events => GetSingleEvents($branch), >+ branchloop => \@branchloop, >+ calendardate => $calendardate, >+ keydate => $keydate, >+ branchcodes => $branchcodes, >+ branch => $branch, >+ branchname => $branchname, >+); >+ >+# Shows the template with the real values replaced >+output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/tools/copy-holidays.pl b/tools/copy-holidays.pl >deleted file mode 100755 >index 83c9761..0000000 >--- a/tools/copy-holidays.pl >+++ /dev/null >@@ -1,39 +0,0 @@ >-#!/usr/bin/perl >- >-# Copyright 2012 Catalyst IT >-# >-# 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 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. >-# >-# You should have received a copy of the GNU General Public License along >-# with Koha; if not, write to the Free Software Foundation, Inc., >-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >- >-use strict; >-use warnings; >- >-use CGI; >- >-use C4::Auth; >-use C4::Output; >- >- >-use C4::Calendar; >- >-my $input = new CGI; >-my $dbh = C4::Context->dbh(); >- >-my $branchcode = $input->param('branchcode'); >-my $from_branchcode = $input->param('from_branchcode'); >- >-C4::Calendar->new(branchcode => $from_branchcode)->copy_to_branch($branchcode) if $from_branchcode && $branchcode; >- >-print $input->redirect("/cgi-bin/koha/tools/holidays.pl?branch=".($branchcode || $from_branchcode)); >diff --git a/tools/exceptionHolidays.pl b/tools/exceptionHolidays.pl >deleted file mode 100755 >index 0a36a20..0000000 >--- a/tools/exceptionHolidays.pl >+++ /dev/null >@@ -1,145 +0,0 @@ >-#!/usr/bin/perl >- >-use strict; >-use warnings; >- >-use CGI; >- >-use C4::Auth; >-use C4::Output; >-use DateTime; >- >-use C4::Calendar; >- >-my $input = new CGI; >-my $dbh = C4::Context->dbh(); >- >-my $branchcode = $input->param('showBranchName'); >-my $weekday = $input->param('showWeekday'); >-my $day = $input->param('showDay'); >-my $month = $input->param('showMonth'); >-my $year = $input->param('showYear'); >-my $day1; >-my $month1; >-my $year1; >-my $title = $input->param('showTitle'); >-my $description = $input->param('showDescription'); >-my $holidaytype = $input->param('showHolidayType'); >-my $datecancelrange = $input->param('datecancelrange'); >-my $calendardate = sprintf("%04d-%02d-%02d", $year, $month, $day); >-my $isodate = C4::Dates->new($calendardate, 'iso'); >-$calendardate = $isodate->output('syspref'); >- >-my $calendar = C4::Calendar->new(branchcode => $branchcode); >- >-$title || ($title = ''); >-if ($description) { >- $description =~ s/\r/\\r/g; >- $description =~ s/\n/\\n/g; >-} else { >- $description = ''; >-} >- >-# We format the date >-my @dateend = split(/[\/-]/, $datecancelrange); >-if (C4::Context->preference("dateformat") eq "metric") { >- $day1 = $dateend[0]; >- $month1 = $dateend[1]; >- $year1 = $dateend[2]; >-}elsif (C4::Context->preference("dateformat") eq "us") { >- $month1 = $dateend[0]; >- $day1 = $dateend[1]; >- $year1 = $dateend[2]; >-} else { >- $year1 = $dateend[0]; >- $month1 = $dateend[1]; >- $day1 = $dateend[2]; >-} >- >-# We make an array with holiday's days >-my @holiday_list; >-if ($year1 && $month1 && $day1){ >- my $first_dt = DateTime->new(year => $year, month => $month, day => $day); >- my $end_dt = DateTime->new(year => $year1, month => $month1, day => $day1); >- >- for (my $dt = $first_dt->clone(); >- $dt <= $end_dt; >- $dt->add(days => 1) ) >- { >- push @holiday_list, $dt->clone(); >- } >-} >-if ($input->param('showOperation') eq 'exception') { >- $calendar->insert_exception_holiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >-} elsif ($input->param('showOperation') eq 'exceptionrange' ) { >- if (@holiday_list){ >- foreach my $date (@holiday_list){ >- $calendar->insert_exception_holiday( >- day => $date->{local_c}->{day}, >- month => $date->{local_c}->{month}, >- year => $date->{local_c}->{year}, >- title => $title, >- description => $description >- ); >- } >- } >-} elsif ($input->param('showOperation') eq 'edit') { >- if($holidaytype eq 'weekday') { >- $calendar->ModWeekdayholiday(weekday => $weekday, >- title => $title, >- description => $description); >- } elsif ($holidaytype eq 'daymonth') { >- $calendar->ModDaymonthholiday(day => $day, >- month => $month, >- title => $title, >- description => $description); >- } elsif ($holidaytype eq 'ymd') { >- $calendar->ModSingleholiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- } elsif ($holidaytype eq 'exception') { >- $calendar->ModExceptionholiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- } >-} elsif ($input->param('showOperation') eq 'delete') { >- $calendar->delete_holiday(weekday => $weekday, >- day => $day, >- month => $month, >- year => $year); >-}elsif ($input->param('showOperation') eq 'deleterange') { >- if (@holiday_list){ >- foreach my $date (@holiday_list){ >- $calendar->delete_holiday_range(weekday => $weekday, >- day => $date->{local_c}->{day}, >- month => $date->{local_c}->{month}, >- year => $date->{local_c}->{year}); >- } >- } >-}elsif ($input->param('showOperation') eq 'deleterangerepeat') { >- if (@holiday_list){ >- foreach my $date (@holiday_list){ >- $calendar->delete_holiday_range_repeatable(weekday => $weekday, >- day => $date->{local_c}->{day}, >- month => $date->{local_c}->{month}); >- } >- } >-}elsif ($input->param('showOperation') eq 'deleterangerepeatexcept') { >- if (@holiday_list){ >- foreach my $date (@holiday_list){ >- $calendar->delete_exception_holiday_range(weekday => $weekday, >- day => $date->{local_c}->{day}, >- month => $date->{local_c}->{month}, >- year => $date->{local_c}->{year}); >- } >- } >-} >-print $input->redirect("/cgi-bin/koha/tools/holidays.pl?branch=$branchcode&calendardate=$calendardate"); >diff --git a/tools/holidays.pl b/tools/holidays.pl >deleted file mode 100755 >index 23468d1..0000000 >--- a/tools/holidays.pl >+++ /dev/null >@@ -1,164 +0,0 @@ >-#!/usr/bin/perl >- >-# 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 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. >-# >-# 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 strict; >-use warnings; >- >-use CGI; >- >-use C4::Auth; >-use C4::Output; >- >-use C4::Branch; # GetBranches >-use C4::Calendar; >- >-my $input = new CGI; >- >-my $dbh = C4::Context->dbh(); >-# Get the template to use >-my ($template, $loggedinuser, $cookie) >- = get_template_and_user({template_name => "tools/holidays.tt", >- type => "intranet", >- query => $input, >- authnotrequired => 0, >- flagsrequired => {tools => 'edit_calendar'}, >- debug => 1, >- }); >- >-# keydate - date passed to calendar.js. calendar.js does not process dashes within a date. >-my $keydate; >-# calendardate - date passed in url for human readability (syspref) >-my $calendardate; >-my $today = C4::Dates->new(); >-my $calendarinput = C4::Dates->new($input->param('calendardate')) || $today; >-# if the url has an invalid date default to 'now.' >-unless($calendardate = $calendarinput->output('syspref')) { >- $calendardate = $today->output('syspref'); >-} >-unless($keydate = $calendarinput->output('iso')) { >- $keydate = $today->output('iso'); >-} >-$keydate =~ s/-/\//g; >- >-my $branch= $input->param('branch') || C4::Context->userenv->{'branch'}; >-# Set all the branches. >-my $onlymine = >- ( C4::Context->preference('IndependentBranches') >- && C4::Context->userenv >- && !C4::Context->IsSuperLibrarian() >- && C4::Context->userenv->{branch} ? 1 : 0 ); >-if ( $onlymine ) { >- $branch = C4::Context->userenv->{'branch'}; >-} >-my $branchname = GetBranchName($branch); >-my $branches = GetBranches($onlymine); >-my @branchloop; >-for my $thisbranch ( >- sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } >- keys %{$branches} ) { >- push @branchloop, >- { value => $thisbranch, >- selected => $thisbranch eq $branch, >- branchname => $branches->{$thisbranch}->{'branchname'}, >- }; >-} >- >-# branches calculated - put branch codes in a single string so they can be passed in a form >-my $branchcodes = join '|', keys %{$branches}; >- >-# Get all the holidays >- >-my $calendar = C4::Calendar->new(branchcode => $branch); >-my $week_days_holidays = $calendar->get_week_days_holidays(); >-my @week_days; >-foreach my $weekday (keys %$week_days_holidays) { >-# warn "WEEK DAY : $weekday"; >- my %week_day; >- %week_day = (KEY => $weekday, >- TITLE => $week_days_holidays->{$weekday}{title}, >- DESCRIPTION => $week_days_holidays->{$weekday}{description}); >- push @week_days, \%week_day; >-} >- >-my $day_month_holidays = $calendar->get_day_month_holidays(); >-my @day_month_holidays; >-foreach my $monthDay (keys %$day_month_holidays) { >- # Determine date format on month and day. >- my $day_monthdate; >- my $day_monthdate_sort; >- if (C4::Context->preference("dateformat") eq "metric") { >- $day_monthdate_sort = "$day_month_holidays->{$monthDay}{month}-$day_month_holidays->{$monthDay}{day}"; >- $day_monthdate = "$day_month_holidays->{$monthDay}{day}/$day_month_holidays->{$monthDay}{month}"; >- } elsif (C4::Context->preference("dateformat") eq "us") { >- $day_monthdate = "$day_month_holidays->{$monthDay}{month}/$day_month_holidays->{$monthDay}{day}"; >- $day_monthdate_sort = $day_monthdate; >- } else { >- $day_monthdate = "$day_month_holidays->{$monthDay}{month}-$day_month_holidays->{$monthDay}{day}"; >- $day_monthdate_sort = $day_monthdate; >- } >- my %day_month; >- %day_month = (KEY => $monthDay, >- DATE_SORT => $day_monthdate_sort, >- DATE => $day_monthdate, >- TITLE => $day_month_holidays->{$monthDay}{title}, >- DESCRIPTION => $day_month_holidays->{$monthDay}{description}); >- push @day_month_holidays, \%day_month; >-} >- >-my $exception_holidays = $calendar->get_exception_holidays(); >-my @exception_holidays; >-foreach my $yearMonthDay (keys %$exception_holidays) { >- my $exceptiondate = C4::Dates->new($exception_holidays->{$yearMonthDay}{date}, "iso"); >- my %exception_holiday; >- %exception_holiday = (KEY => $yearMonthDay, >- DATE_SORT => $exception_holidays->{$yearMonthDay}{date}, >- DATE => $exceptiondate->output("syspref"), >- TITLE => $exception_holidays->{$yearMonthDay}{title}, >- DESCRIPTION => $exception_holidays->{$yearMonthDay}{description}); >- push @exception_holidays, \%exception_holiday; >-} >- >-my $single_holidays = $calendar->get_single_holidays(); >-my @holidays; >-foreach my $yearMonthDay (keys %$single_holidays) { >- my $holidaydate = C4::Dates->new($single_holidays->{$yearMonthDay}{date}, "iso"); >- my %holiday; >- %holiday = (KEY => $yearMonthDay, >- DATE_SORT => $single_holidays->{$yearMonthDay}{date}, >- DATE => $holidaydate->output("syspref"), >- TITLE => $single_holidays->{$yearMonthDay}{title}, >- DESCRIPTION => $single_holidays->{$yearMonthDay}{description}); >- push @holidays, \%holiday; >-} >- >-$template->param( >- WEEK_DAYS_LOOP => \@week_days, >- branchloop => \@branchloop, >- HOLIDAYS_LOOP => \@holidays, >- EXCEPTION_HOLIDAYS_LOOP => \@exception_holidays, >- DAY_MONTH_HOLIDAYS_LOOP => \@day_month_holidays, >- calendardate => $calendardate, >- keydate => $keydate, >- branchcodes => $branchcodes, >- branch => $branch, >- branchname => $branchname, >- branch => $branch, >-); >- >-# Shows the template with the real values replaced >-output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/tools/newHolidays.pl b/tools/newHolidays.pl >deleted file mode 100755 >index 646276c..0000000 >--- a/tools/newHolidays.pl >+++ /dev/null >@@ -1,144 +0,0 @@ >-#!/usr/bin/perl >- >-use strict; >-use warnings; >- >-use CGI; >- >-use C4::Auth; >-use C4::Output; >- >- >-use C4::Calendar; >-use DateTime; >- >-my $input = new CGI; >-my $dbh = C4::Context->dbh(); >- >-our $branchcode = $input->param('newBranchName'); >-my $originalbranchcode = $branchcode; >-our $weekday = $input->param('newWeekday'); >-our $day = $input->param('newDay'); >-our $month = $input->param('newMonth'); >-our $year = $input->param('newYear'); >-my $day1; >-my $month1; >-my $year1; >-my $dateofrange = $input->param('dateofrange'); >-our $title = $input->param('newTitle'); >-our $description = $input->param('newDescription'); >-our $newoperation = $input->param('newOperation'); >-my $allbranches = $input->param('allBranches'); >- >-my $calendardate = sprintf("%04d-%02d-%02d", $year, $month, $day); >-my $isodate = C4::Dates->new($calendardate, 'iso'); >-$calendardate = $isodate->output('syspref'); >- >-my @dateend = split(/[\/-]/, $dateofrange); >-if (C4::Context->preference("dateformat") eq "metric") { >- $day1 = $dateend[0]; >- $month1 = $dateend[1]; >- $year1 = $dateend[2]; >-}elsif (C4::Context->preference("dateformat") eq "us") { >- $month1 = $dateend[0]; >- $day1 = $dateend[1]; >- $year1 = $dateend[2]; >-} else { >- $year1 = $dateend[0]; >- $month1 = $dateend[1]; >- $day1 = $dateend[2]; >-} >-$title || ($title = ''); >-if ($description) { >- $description =~ s/\r/\\r/g; >- $description =~ s/\n/\\n/g; >-} else { >- $description = ''; >-} >- >-# We make an array with holiday's days >-our @holiday_list; >-if ($year1 && $month1 && $day1){ >- my $first_dt = DateTime->new(year => $year, month => $month, day => $day); >- my $end_dt = DateTime->new(year => $year1, month => $month1, day => $day1); >- >- for (my $dt = $first_dt->clone(); >- $dt <= $end_dt; >- $dt->add(days => 1) ) >- { >- push @holiday_list, $dt->clone(); >- } >-} >- >-if($allbranches) { >- my $branch; >- my @branchcodes = split(/\|/, $input->param('branchCodes')); >- foreach $branch (@branchcodes) { >- add_holiday($newoperation, $branch, $weekday, $day, $month, $year, $title, $description); >- } >-} else { >- add_holiday($newoperation, $branchcode, $weekday, $day, $month, $year, $title, $description); >-} >- >-print $input->redirect("/cgi-bin/koha/tools/holidays.pl?branch=$originalbranchcode&calendardate=$calendardate"); >- >-sub add_holiday { >- ($newoperation, $branchcode, $weekday, $day, $month, $year, $title, $description) = @_; >- my $calendar = C4::Calendar->new(branchcode => $branchcode); >- >- if ($newoperation eq 'weekday') { >- unless ( $weekday && ($weekday ne '') ) { >- # was dow calculated by javascript? original code implies it was supposed to be. >- # if not, we need it. >- $weekday = &Date::Calc::Day_of_Week($year, $month, $day) % 7 unless($weekday); >- } >- unless($calendar->isHoliday($day, $month, $year)) { >- $calendar->insert_week_day_holiday(weekday => $weekday, >- title => $title, >- description => $description); >- } >- } elsif ($newoperation eq 'repeatable') { >- unless($calendar->isHoliday($day, $month, $year)) { >- $calendar->insert_day_month_holiday(day => $day, >- month => $month, >- title => $title, >- description => $description); >- } >- } elsif ($newoperation eq 'holiday') { >- unless($calendar->isHoliday($day, $month, $year)) { >- $calendar->insert_single_holiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- } >- >- } elsif ( $newoperation eq 'holidayrange' ) { >- if (@holiday_list){ >- foreach my $date (@holiday_list){ >- unless ( $calendar->isHoliday( $date->{local_c}->{day}, $date->{local_c}->{month}, $date->{local_c}->{year} ) ) { >- $calendar->insert_single_holiday( >- day => $date->{local_c}->{day}, >- month => $date->{local_c}->{month}, >- year => $date->{local_c}->{year}, >- title => $title, >- description => $description >- ); >- } >- } >- } >- } elsif ( $newoperation eq 'holidayrangerepeat' ) { >- if (@holiday_list){ >- foreach my $date (@holiday_list){ >- unless ( $calendar->isHoliday( $date->{local_c}->{day}, $date->{local_c}->{month}, $date->{local_c}->{year} ) ) { >- $calendar->insert_day_month_holiday( >- day => $date->{local_c}->{day}, >- month => $date->{local_c}->{month}, >- title => $title, >- description => $description >- ); >- } >- } >- } >- } >-} >-- >1.7.2.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 11211
:
24856
|
25528
|
25556
|
26434
|
29731
|
30959
|
32110
|
32867
|
32978
|
32992
|
33415
|
33895
|
33896
|
33898
|
33899
|
33908
|
34040