Bugzilla – Attachment 19326 Details for
Bug 8133
hourly loans doesn't know when library closed
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 8133 - hourly loans doesn't know when library closed
Bug-8133---hourly-loans-doesnt-know-when-library-c.patch (text/plain), 184.67 KB, created by
Jesse Weaver
on 2013-07-01 21:05:38 UTC
(
hide
)
Description:
Bug 8133 - hourly loans doesn't know when library closed
Filename:
MIME Type:
Creator:
Jesse Weaver
Created:
2013-07-01 21:05:38 UTC
Size:
184.67 KB
patch
obsolete
>From 436037fda4b86aa2ca94c6d2cf2da6f4526889c1 Mon Sep 17 00:00:00 2001 >From: Jesse Weaver <pianohacker@gmail.com> >Date: Thu, 20 Jun 2013 16:54:32 -0600 >Subject: [PATCH] Bug 8133 - hourly loans doesn't know when library closed > >This adds support for storing library hours in the calendar, and using >those hours to compute hourly loan duetimes. > >A large amount of cleanup was also performed to expunge duplication of >code between C4::Calendar and Koha::Calendar. > >Test plan: >1) Apply patch. >2) Update database. >3) Verify that the calendar administration interface still exists and > works as expected. >4) Run t/Calendar.t and t/db_dependent/Calendar.t. >--- > C4/Calendar.pm | 738 ++++---------------- > C4/Circulation.pm | 88 --- > C4/Overdues.pm | 124 ---- > Koha/Calendar.pm | 342 ++++----- > .../data/mysql/de-DE/optional/sample_holidays.sql | 10 +- > .../data/mysql/en/optional/sample_holidays.sql | 8 +- > .../data/mysql/es-ES/optional/sample_holidays.sql | 8 +- > .../data/mysql/it-IT/necessari/sample_holidays.sql | 10 +- > installer/data/mysql/kohastructure.sql | 70 +- > .../mysql/nb-NO/2-Valgfritt/sample_holidays.sql | 14 +- > .../data/mysql/pl-PL/optional/sample_holidays.sql | 8 +- > installer/data/mysql/ru-RU/optional/holidays.sql | 30 +- > installer/data/mysql/uk-UA/optional/holidays.sql | 42 +- > installer/data/mysql/updatedatabase.pl | 75 ++ > .../intranet-tmpl/prog/en/includes/tools-menu.inc | 2 +- > .../prog/en/modules/tools/calendar.tt | 597 ++++++++++++++++ > .../prog/en/modules/tools/holidays.tt | 538 -------------- > .../prog/en/modules/tools/tools-home.tt | 2 +- > misc/cronjobs/staticfines.pl | 11 +- > .../thirdparty/TalkingTech_itiva_outbound.pl | 31 +- > t/Calendar.t | 143 +++- > t/db_dependent/Calendar.t | 78 +++ > t/db_dependent/lib/KohaTest/Calendar/New.pm | 186 ----- > t/db_dependent/lib/KohaTest/Circulation.pm | 3 - > t/db_dependent/lib/KohaTest/Overdues.pm | 3 - > tools/calendar.pl | 255 +++++++ > tools/copy-holidays.pl | 39 -- > tools/exceptionHolidays.pl | 145 ---- > tools/holidays.pl | 163 ----- > tools/newHolidays.pl | 144 ---- > 30 files changed, 1539 insertions(+), 2368 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 > delete mode 100644 t/db_dependent/lib/KohaTest/Calendar/New.pm > 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..7131b56 100644 >--- a/C4/Calendar.pm >+++ b/C4/Calendar.pm >@@ -15,712 +15,210 @@ 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; > >+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 >+=head2 GetSingleEvents > >- $calendar = C4::Calendar->new(branchcode => $branchcode); >+ \@events = GetSingleEvents( $branchcode ) > >-Each library branch has its own Calendar. >-C<$branchcode> specifies which Calendar you want. >+Get the non-repeating events for the given library. > > =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 GetSingleEvents { >+ my ( $branchcode ) = @_; > >-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; >+ return C4::Context->dbh->selectall_arrayref( q{ >+ SELECT >+ event_date, open_hour, open_minute, close_hour, close_minute, title, description, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_events >+ WHERE branchcode = ? >+ }, { Slice => {} }, $branchcode ); > } > >-=head2 get_week_days_holidays >+=head2 GetWeeklyEvents > >- $week_days_holidays = $calendar->get_week_days_holidays(); >+ \@events = GetWeeklyEvents( $branchcode ) > >-Returns a hash reference to week days holidays. >+Get the weekly-repeating events for the given library. > > =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 GetWeeklyEvents { >+ my ( $branchcode ) = @_; > >-sub get_day_month_holidays { >- my $self = shift @_; >- my $day_month_holidays = $self->{'day_month_holidays'}; >- return $day_month_holidays; >+ return C4::Context->dbh->selectall_arrayref( q{ >+ SELECT >+ weekday, open_hour, open_minute, close_hour, close_minute, title, description, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_repeats >+ WHERE branchcode = ? AND weekday IS NOT NULL >+ }, { Slice => {} }, $branchcode ); > } > >-=head2 get_exception_holidays >+=head2 GetYearlyEvents > >- $exception_holidays = $calendar->exception_holidays(); >+ \@events = GetYearlyEvents( $branchcode ) > >-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. >+Get the yearly-repeating events for the given library. > > =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(); >+sub GetYearlyEvents { >+ my ( $branchcode ) = @_; > >-Returns a hash reference to single holidays. This kind of holidays are those which >-happend just one time. >- >-=cut >- >-sub get_single_holidays { >- my $self = shift @_; >- my $single_holidays = $self->{'single_holidays'}; >- return $single_holidays; >+ return C4::Context->dbh->selectall_arrayref( q{ >+ SELECT >+ month, day, open_hour, open_minute, close_hour, close_minute, title, description, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_repeats >+ WHERE branchcode = ? AND weekday IS NULL >+ }, { Slice => {} }, $branchcode ); > } > >-=head2 insert_week_day_holiday >- >- insert_week_day_holiday(weekday => $weekday, >- title => $title, >- description => $description); >- >-Inserts a new week day for $self->{branchcode}. >- >-C<$day> Is the week day to make holiday. >+=head2 ModSingleEvent > >-C<$title> Is the title to store for the holiday formed by $year/$month/$day. >+ ModSingleEvent( $branchcode, $date, \%info ) > >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >+Creates or updates an event for a single date. $date should be an ISO-formatted >+date string, and \%info should contain the following keys: open_hour, >+open_minute, close_hour, close_minute, title and description. > > =cut > >-sub insert_week_day_holiday { >- my $self = shift @_; >- my %options = @_; >+sub ModSingleEvent { >+ my ( $branchcode, $date, $info ) = @_; > >- 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; >+ C4::Context->dbh->do( q{ >+ INSERT INTO calendar_events(branchcode, event_date, open_hour, open_minute, close_hour, close_minute, title, description) >+ VALUES (?, ?, ?, ?, ?, ?, ?, ?) >+ ON DUPLICATE KEY UPDATE open_hour = ?, open_minute = ?, close_hour = ?, close_minute = ?, title = ?, description = ? >+ }, {}, $branchcode, $date, ( map { $info->{$_} } qw(open_hour open_minute close_hour close_minute title description) ) x 2 ); > } > >-=head2 insert_day_month_holiday >- >- insert_day_month_holiday(day => $day, >- month => $month, >- title => $title, >- description => $description); >- >-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. >+=head2 ModRepeatingEvent > >-C<$title> Is the title to store for the holiday formed by $year/$month/$day. >+ ModRepeatingEvent( $branchcode, $weekday, $month, $day, \%info ) > >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >+Creates or updates a weekly- or yearly-repeating event. Either $weekday, >+or $month and $day should be set, for a weekly or yearly event, respectively. > > =cut > >-sub insert_day_month_holiday { >- my $self = shift @_; >- my %options = @_; >+sub ModRepeatingEvent { >+ my ( $branchcode, $weekday, $month, $day, $info ) = @_; > >- 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; >+ C4::Context->dbh->do( q{ >+ INSERT INTO calendar_repeats(branchcode, weekday, month, day, open_hour, open_minute, close_hour, close_minute, title, description) >+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) >+ ON DUPLICATE KEY UPDATE open_hour = ?, open_minute = ?, close_hour = ?, close_minute = ?, title = ?, description = ? >+ }, {}, $branchcode, $weekday, $month, $day, ( map { $info->{$_} } qw(open_hour open_minute close_hour close_minute title description) ) x 2 ); > } > >-=head2 insert_single_holiday >- >- insert_single_holiday(day => $day, >- month => $month, >- year => $year, >- title => $title, >- description => $description); >- >-Inserts a new single 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. >+=head2 DelSingleEvent > >-C<$year> Is year to make the date to insert. >+ DelSingleEvent( $branchcode, $date, \%info ) > >-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. >+Deletes an event for a single date. $date should be an ISO-formatted date string. > > =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; >-} >- >-=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. >- >-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. >+sub DelSingleEvent { >+ my ( $branchcode, $date ) = @_; > >-C<$description> Is the description to store for the holiday formed by $year/$month/$day. >- >-=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}; >- >- 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; >+ C4::Context->dbh->do( q{ >+ DELETE FROM calendar_events >+ WHERE branchcode = ? AND event_date = ? >+ }, {}, $branchcode, $date ); > } > >-=head2 ModWeekdayholiday >- >- ModWeekdayholiday(weekday =>$weekday, >- title => $title, >- description => $description) >- >-Modifies the title and description of a weekday for $self->{branchcode}. >- >-C<$weekday> Is the title to update for the holiday. >- >-C<$description> Is the description to update for the holiday. >+sub _get_compare { >+ my ( $colname, $value ) = @_; > >-=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; >+ return ' AND ' . $colname . ' ' . ( defined( $value ) ? '=' : 'IS' ) . ' ?'; > } > >-=head2 ModDaymonthholiday >- >- ModDaymonthholiday(day => $day, >- month => $month, >- title => $title, >- description => $description); >- >-Modifies the title and description for a day/month holiday for $self->{branchcode}. >+=head2 DelRepeatingEvent > >-C<$day> The day of the month for the update. >+ DelRepeatingEvent( $branchcode, $weekday, $month, $day ) > >-C<$month> The month to be used for the update. >- >-C<$title> The title to be updated for the holiday. >- >-C<$description> The description to be update for the holiday. >+Deletes a weekly- or yearly-repeating event. Either $weekday, or $month and >+$day should be set, for a weekly or yearly event, respectively. > > =cut > >-sub ModDaymonthholiday { >- my $self = shift @_; >- my %options = @_; >+sub DelRepeatingEvent { >+ my ( $branchcode, $weekday, $month, $day ) = @_; > >- 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; >+ C4::Context->dbh->do( q{ >+ DELETE FROM calendar_repeats >+ WHERE branchcode = ? >+ } . _get_compare( 'weekday', $weekday ) . _get_compare( 'month', $month ) . _get_compare( 'day', $day ), {}, $branchcode, $weekday, $month, $day ); > } > >-=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}. >+=head2 CopyAllEvents > >-C<$day> Is the day of the month to make the update. >+ CopyAllEvents( $from_branchcode, $to_branchcode ) > >-C<$month> Is the month to make the update. >- >-C<$year> Is the year to make the update. >- >-C<$title> Is the title to update for the holiday formed by $year/$month/$day. >- >-C<$description> Is the description to update for the holiday formed by $year/$month/$day. >+Copies all events from one branch to another. > > =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. >+sub CopyAllEvents { >+ my ( $from_branchcode, $to_branchcode ) = @_; > >-C<$year> Is the year for the holiday. >+ C4::Context->dbh->do( q{ >+ INSERT IGNORE INTO calendar_events(branchcode, event_date, open_hour, open_minute, close_hour, close_minute, title, description) >+ SELECT ?, event_date, open_hour, open_minute, close_hour, close_minute, title, description >+ FROM calendar_events >+ WHERE branchcode = ? >+ }, {}, $to_branchcode, $from_branchcode ); > >-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. >- >-=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; >+ C4::Context->dbh->do( q{ >+ INSERT IGNORE INTO calendar_repeats(branchcode, weekday, month, day, open_hour, open_minute, close_hour, close_minute, title, description) >+ SELECT ?, weekday, month, day, open_hour, open_minute, close_hour, close_minute, title, description >+ FROM calendar_repeats >+ WHERE branchcode = ? >+ }, {}, $to_branchcode, $from_branchcode ); > } > >-=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. >- >-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 { >- 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}"}); >- } 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}"}); >- } >- } >- } >- 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 >- >- delete_holiday_range_repeatable(day => $day, >- month => $month); >- >-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. >- >-=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 >- >- delete_exception_holiday_range(weekday => $weekday >- day => $day, >- month => $month, >- year => $year); >- >-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}); >-} >- >-=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 copy_to_branch >- >- $calendar->copy_to_branch($target_branch) >- >-=cut >- >-sub copy_to_branch { >- my ($self, $target_branch) = @_; >- >- croak "No target_branch" unless $target_branch; >- >- 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; >-} >- >-=head2 addDate >- >- my ($day, $month, $year) = $calendar->addDate($date, $offset) >- >-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. >- >-=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')); >-} >- >-=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; > >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index 30cbe2f..ec3989a 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -3101,94 +3101,6 @@ sub CalcDateDue { > } > > >-=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; >-$sth->finish; >-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 ; >-$sth->finish; >-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 ; >-$sth->finish; >-return $countspecial; >-} >- >- > > sub CheckValidBarcode{ > my ($barcode) = @_; >diff --git a/C4/Overdues.pm b/C4/Overdues.pm >index 4fd0b84..f441cd7 100644 >--- a/C4/Overdues.pm >+++ b/C4/Overdues.pm >@@ -306,130 +306,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 6a12530..77db08a 100644 >--- a/Koha/Calendar.pm >+++ b/Koha/Calendar.pm >@@ -18,10 +18,6 @@ sub new { > my $o = lc $o_name; > $self->{$o} = $options{$o_name}; > } >- if ( exists $options{TEST_MODE} ) { >- $self->_mockinit(); >- return $self; >- } > if ( !defined $self->{branchcode} ) { > croak 'No branchcode argument passed to Koha::Calendar->new'; > } >@@ -33,57 +29,36 @@ sub _init { > my $self = shift; > my $branch = $self->{branchcode}; > my $dbh = C4::Context->dbh(); >- my $weekly_closed_days_sth = $dbh->prepare( >-'SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL' >- ); >- $weekly_closed_days_sth->execute( $branch ); >- $self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ]; >- Readonly::Scalar my $sunday => 7; >- while ( my $tuple = $weekly_closed_days_sth->fetchrow_hashref ) { >- $self->{weekly_closed_days}->[ $tuple->{weekday} ] = 1; >- } >- my $day_month_closed_days_sth = $dbh->prepare( >-'SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL' >- ); >- $day_month_closed_days_sth->execute( $branch ); >- $self->{day_month_closed_days} = {}; >- while ( my $tuple = $day_month_closed_days_sth->fetchrow_hashref ) { >- $self->{day_month_closed_days}->{ $tuple->{month} }->{ $tuple->{day} } = >- 1; >- } > >- my $exception_holidays_sth = $dbh->prepare( >-'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 1' >- ); >- $exception_holidays_sth->execute( $branch ); >- my $dates = []; >- while ( my ( $day, $month, $year ) = $exception_holidays_sth->fetchrow ) { >- push @{$dates}, >- DateTime->new( >- day => $day, >- month => $month, >- year => $year, >- time_zone => C4::Context->tz() >- )->truncate( to => 'day' ); >+ $self->{weekday_hours} = $dbh->selectall_hashref( q{ >+ SELECT >+ weekday, open_hour, open_minute, close_hour, close_minute, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_repeats >+ WHERE branchcode = ? AND weekday IS NOT NULL >+ }, 'weekday', { Slice => {} }, $branch ); >+ >+ my $day_month_hours = $dbh->selectall_arrayref( q{ >+ SELECT >+ month, day, open_hour, open_minute, close_hour, close_minute, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_repeats >+ WHERE branchcode = ? AND weekday IS NULL >+ }, { Slice => {} }, $branch ); >+ >+ # DBD::Mock doesn't support multi-key selectall_hashref, so we do it ourselves for now >+ foreach my $day_month ( @$day_month_hours ) { >+ $self->{day_month_hours}->{ $day_month->{month} }->{ $day_month->{day} } = $day_month; > } >- $self->{exception_holidays} = >- DateTime::Set->from_datetimes( dates => $dates ); >- >- my $single_holidays_sth = $dbh->prepare( >-'SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 0' >- ); >- $single_holidays_sth->execute( $branch ); >- $dates = []; >- while ( my ( $day, $month, $year ) = $single_holidays_sth->fetchrow ) { >- push @{$dates}, >- DateTime->new( >- day => $day, >- month => $month, >- year => $year, >- time_zone => C4::Context->tz() >- )->truncate( to => 'day' ); >- } >- $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates ); >+ >+ $self->{date_hours} = $dbh->selectall_hashref( q{ >+ SELECT >+ event_date, open_hour, open_minute, close_hour, close_minute, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_events >+ WHERE branchcode = ? >+ }, 'event_date', { Slice => {} }, $branch ); >+ > $self->{days_mode} = C4::Context->preference('useDaysMode'); > $self->{test} = 0; > return; >@@ -101,10 +76,7 @@ sub addDate { > my $dt; > > if ( $unit eq 'hours' ) { >- # Fixed for legacy support. Should be set as a branch parameter >- Readonly::Scalar my $return_by_hour => 10; >- >- $dt = $self->addHours($startdate, $add_duration, $return_by_hour); >+ $dt = $self->addHours($startdate, $add_duration); > } else { > # days > $dt = $self->addDays($startdate, $add_duration); >@@ -114,25 +86,73 @@ sub addDate { > } > > sub addHours { >- my ( $self, $startdate, $hours_duration, $return_by_hour ) = @_; >+ my ( $self, $startdate, $hours_duration ) = @_; > my $base_date = $startdate->clone(); > >- $base_date->add_duration($hours_duration); >+ if ( $self->{days_mode} eq 'Days' ) { >+ $base_date->add_duration( $hours_duration ); >+ return $base_date; >+ } >+ my $hours = $self->get_hours_full( $base_date ); >+ >+ if ( $hours_duration->is_negative() ) { >+ if ( $base_date <= $hours->{open_time} ) { >+ # Library is already closed >+ $base_date = $self->prev_open_day( $base_date ); >+ $hours = $self->get_hours_full( $base_date ); >+ $base_date = $hours->{close_time}->clone; >+ >+ if ( $self->{days_mode} eq 'Calendar' ) { >+ return $base_date; >+ } >+ } > >- # If we are using the calendar behave for now as if Datedue >- # was the chosen option (current intended behaviour) >+ while ( $hours_duration->is_negative ) { >+ my $day_len = $hours->{open_time} - $base_date; > >- if ( $self->{days_mode} ne 'Days' && >- $self->is_holiday($base_date) ) { >+ if ( DateTime::Duration->compare( $day_len, $hours_duration, $base_date ) > 0 ) { >+ if ( $self->{days_mode} eq 'Calendar' ) { >+ return $hours->{open_time}; >+ } > >- if ( $hours_duration->is_negative() ) { >- $base_date = $self->prev_open_day($base_date); >- } else { >- $base_date = $self->next_open_day($base_date); >+ $hours_duration->subtract( $day_len ); >+ $base_date = $self->prev_open_day( $base_date ); >+ $hours = $self->get_hours_full( $base_date ); >+ $base_date = $hours->{close_time}->clone; >+ } else { >+ $base_date->add_duration( $hours_duration ); >+ return $base_date; >+ } >+ } >+ } else { >+ if ( $base_date >= $hours->{close_time} ) { >+ # Library is already closed >+ $base_date = $self->next_open_day( $base_date ); >+ $hours = $self->get_hours_full( $base_date ); >+ $base_date = $hours->{open_time}->clone; >+ >+ if ( $self->{days_mode} eq 'Calendar' ) { >+ return $base_date; >+ } > } > >- $base_date->set_hour($return_by_hour); >+ while ( $hours_duration->is_positive ) { >+ my $day_len = $hours->{close_time} - $base_date; >+ >+ if ( DateTime::Duration->compare( $day_len, $hours_duration, $base_date ) < 0 ) { >+ if ( $self->{days_mode} eq 'Calendar' ) { >+ return $hours->{close_time}; >+ } > >+ $hours_duration->subtract( $day_len ); >+ $base_date = $self->next_open_day( $base_date ); >+ $hours = $self->get_hours_full( $base_date ); >+ $base_date = $hours->{open_time}->clone; >+ } else { >+ $base_date->add_duration( $hours_duration ); >+ return $base_date; >+ } >+ } > } > > return $base_date; >@@ -182,33 +202,25 @@ sub addDays { > > sub is_holiday { > my ( $self, $dt ) = @_; >- my $localdt = $dt->clone(); >- my $day = $localdt->day; >- my $month = $localdt->month; >- >- $localdt->truncate( to => 'day' ); >+ my $day = $dt->day; >+ my $month = $dt->month; > >- if ( $self->{exception_holidays}->contains($localdt) ) { >- # exceptions are not holidays >+ if ( exists $self->{date_hours}->{ $dt->ymd } && !$self->{date_hours}->{ $dt->ymd }->{closed} ) { > return 0; > } > >- my $dow = $localdt->day_of_week; >- # Representation fix >- # TODO: Shouldn't we shift the rest of the $dow also? >- if ( $dow == 7 ) { >- $dow = 0; >- } >- >- if ( $self->{weekly_closed_days}->[$dow] == 1 ) { >+ if ( ( $self->{day_month_hours}->{$month}->{$day} || {} )->{closed} ) { > return 1; > } > >- if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) { >+ # We use 0 for Sunday, not 7 >+ my $dow = $dt->day_of_week % 7; >+ >+ if ( ( $self->{weekday_hours}->{ $dow } || {} )->{closed} ) { > return 1; > } > >- if ( $self->{single_holidays}->contains($localdt) ) { >+ if ( ( $self->{date_hours}->{ $dt->ymd } || {} )->{closed} ) { > return 1; > } > >@@ -216,6 +228,60 @@ sub is_holiday { > return 0; > } > >+sub get_hours { >+ my ( $self, $dt ) = @_; >+ my $day = $dt->day; >+ my $month = $dt->month; >+ >+ if ( exists $self->{date_hours}->{ $dt->ymd } ) { >+ return $self->{date_hours}->{ $dt->ymd }; >+ } >+ >+ if ( exists $self->{day_month_hours}->{$month}->{$day} ) { >+ return $self->{day_month_hours}->{$month}->{$day}; >+ } >+ >+ # We use 0 for Sunday, not 7 >+ my $dow = $dt->day_of_week % 7; >+ >+ if ( exists $self->{weekday_hours}->{ $dow } ) { >+ return $self->{weekday_hours}->{ $dow }; >+ } >+ >+ # Assume open >+ return { >+ open_hour => 0, >+ open_minute => 0, >+ close_hour => 24, >+ close_minute => 0, >+ closed => 0 >+ }; >+} >+ >+sub get_hours_full { >+ my ( $self, $dt ) = @_; >+ >+ my $hours = { %{ $self->get_hours( $dt ) } }; >+ >+ $hours->{open_time} = $dt >+ ->clone->truncate( to => 'day' ) >+ ->set_hour( $hours->{open_hour} ) >+ ->set_minute( $hours->{open_minute} ); >+ >+ if ( $hours->{close_hour} == 24 ) { >+ $hours->{close_time} = $dt >+ ->clone->truncate( to => 'day' ) >+ ->add( days => 1 ); >+ } else { >+ $hours->{close_time} = $dt >+ ->clone->truncate( to => 'day' ) >+ ->set_hour( $hours->{close_hour} ) >+ ->set_minute( $hours->{close_minute} ); >+ } >+ >+ return $hours; >+} >+ > sub next_open_day { > my ( $self, $dt ) = @_; > my $base_date = $dt->clone(); >@@ -273,81 +339,39 @@ sub hours_between { > my ($self, $start_date, $end_date) = @_; > my $start_dt = $start_date->clone(); > my $end_dt = $end_date->clone(); >- my $duration = $end_dt->delta_ms($start_dt); >- $start_dt->truncate( to => 'day' ); >- $end_dt->truncate( to => 'day' ); >- # NB this is a kludge in that it assumes all days are 24 hours >- # However for hourly loans the logic should be expanded to >- # take into account open/close times then it would be a duration >- # of library open hours >- my $skipped_days = 0; >- for (my $dt = $start_dt->clone(); >- $dt <= $end_dt; >- $dt->add(days => 1) >- ) { >- if ($self->is_holiday($dt)) { >- ++$skipped_days; >- } >- } >- if ($skipped_days) { >- $duration->subtract_duration(DateTime::Duration->new( hours => 24 * $skipped_days)); >+ >+ if ( $start_dt->compare($end_dt) > 0 ) { >+ # swap dates >+ my $int_dt = $end_dt; >+ $end_dt = $start_dt; >+ $start_dt = $int_dt; > } > >- return $duration; >+ my $start_hours = $self->get_hours_full( $start_dt ); >+ my $end_hours = $self->get_hours_full( $end_dt ); > >-} >+ $start_dt = $start_hours->{open_time} if ( $start_dt < $start_hours->{open_time} ); >+ $end_dt = $end_hours->{close_time} if ( $end_dt > $end_hours->{close_time} ); > >-sub _mockinit { >- my $self = shift; >- $self->{weekly_closed_days} = [ 1, 0, 0, 0, 0, 0, 0 ]; # Sunday only >- $self->{day_month_closed_days} = { 6 => { 16 => 1, } }; >- my $dates = []; >- $self->{exception_holidays} = >- DateTime::Set->from_datetimes( dates => $dates ); >- my $special = DateTime->new( >- year => 2011, >- month => 6, >- day => 1, >- time_zone => 'Europe/London', >- ); >- push @{$dates}, $special; >- $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates ); >- >- # if not defined, days_mode defaults to 'Calendar' >- if ( !defined($self->{days_mode}) ) { >- $self->{days_mode} = 'Calendar'; >- } >+ return $end_dt - $start_dt if ( $start_dt->ymd eq $end_dt->ymd ); > >- $self->{test} = 1; >- return; >-} >+ my $duration = DateTime::Duration->new; >+ >+ $duration->add_duration( $start_hours->{close_time} - $start_dt ) if ( $start_dt < $start_hours->{close_time} ); > >-sub set_daysmode { >- my ( $self, $mode ) = @_; >+ for (my $date = $start_dt->clone->truncate( to => 'day' )->add( days => 1 ); >+ $date->ymd lt $end_dt->ymd; >+ $date->add(days => 1) >+ ) { >+ my $hours = $self->get_hours_full( $date ); > >- # if not testing this is a no op >- if ( $self->{test} ) { >- $self->{days_mode} = $mode; >+ $duration->add_duration( $hours->{close_time}->delta_ms( $hours->{open_time} ) ); > } > >- return; >-} >- >-sub clear_weekly_closed_days { >- my $self = shift; >- $self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ]; # Sunday only >- return; >-} >+ $duration->add_duration( $end_dt - $end_hours->{open_time} ) if ( $end_dt > $start_hours->{open_time} ); > >-sub add_holiday { >- my $self = shift; >- my $new_dt = shift; >- my @dt = $self->{single_holidays}->as_list; >- push @dt, $new_dt; >- $self->{single_holidays} = >- DateTime::Set->from_datetimes( dates => \@dt ); >+ return $duration; > >- return; > } > > 1; >@@ -403,14 +427,12 @@ parameter will be removed when issuingrules properly cope with that > > =head2 addHours > >- my $dt = $calendar->addHours($date, $dur, $return_by_hour ) >+ my $dt = $calendar->addHours($date, $dur ) > > C<$date> is a DateTime object representing the starting date of the interval. > > C<$offset> is a DateTime::Duration to add to it > >-C<$return_by_hour> is an integer value representing the opening hour for the branch >- > > =head2 addDays > >@@ -457,22 +479,6 @@ Passed a Datetime returns another Datetime representing the previous open day. I > intended for use to calculate the due date when useDaysMode syspref is set to either > 'Datedue' or 'Calendar'. > >-=head2 set_daysmode >- >-For testing only allows the calling script to change days mode >- >-=head2 clear_weekly_closed_days >- >-In test mode changes the testing set of closed days to a new set with >-no closed days. TODO passing an array of closed days to this would >-allow testing of more configurations >- >-=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/installer/data/mysql/de-DE/optional/sample_holidays.sql b/installer/data/mysql/de-DE/optional/sample_holidays.sql >index 124fcad..7f18bf2 100644 >--- a/installer/data/mysql/de-DE/optional/sample_holidays.sql >+++ b/installer/data/mysql/de-DE/optional/sample_holidays.sql >@@ -1,5 +1,5 @@ >-INSERT INTO `repeatable_holidays` VALUES >-(2,'MPL',0,NULL,NULL,'','Sonntag'), >-(3,'MPL',NULL,1,1,'','Neujahr'), >-(4,'MPL',NULL,25,12,'','1. Weihnachtsfeiertag'), >-(5,'MPL',NULL,25,12,'','2. Weihnachtsfeiertag'); >+INSERT INTO `calendar_repeats` VALUES >+(2,'MPL',0,NULL,NULL,'','Sonntag',0,0,0,0), >+(3,'MPL',NULL,1,1,'','Neujahr',0,0,0,0), >+(4,'MPL',NULL,12,25,'','1. Weihnachtsfeiertag',0,0,0,0), >+(5,'MPL',NULL,12,25,'','2. Weihnachtsfeiertag',0,0,0,0); >diff --git a/installer/data/mysql/en/optional/sample_holidays.sql b/installer/data/mysql/en/optional/sample_holidays.sql >index 33b6ff6..866c14f 100644 >--- a/installer/data/mysql/en/optional/sample_holidays.sql >+++ b/installer/data/mysql/en/optional/sample_holidays.sql >@@ -1,4 +1,4 @@ >-INSERT INTO `repeatable_holidays` VALUES >-(2,'MPL',0,NULL,NULL,'','Sundays'), >-(3,'MPL',NULL,1,1,'','New Year\'s Day'), >-(4,'MPL',NULL,25,12,'','Christmas'); >+INSERT INTO `calendar_repeats` VALUES >+(2,'MPL',0,NULL,NULL,'','Sundays',0,0,0,0), >+(3,'MPL',NULL,1,1,'','New Year\'s Day',0,0,0,0), >+(4,'MPL',NULL,12,25,'','Christmas',0,0,0,0); >diff --git a/installer/data/mysql/es-ES/optional/sample_holidays.sql b/installer/data/mysql/es-ES/optional/sample_holidays.sql >index e323317..1cf78ec 100644 >--- a/installer/data/mysql/es-ES/optional/sample_holidays.sql >+++ b/installer/data/mysql/es-ES/optional/sample_holidays.sql >@@ -1,4 +1,4 @@ >-INSERT INTO `repeatable_holidays` VALUES >-(2,'',0,NULL,NULL,'','Sundays'), >-(3,'',NULL,1,1,'','New Year\'s Day'), >-(4,'',NULL,25,12,'','Christmas'); >+INSERT INTO `calendar_repeats` VALUES >+(2,'',0,NULL,NULL,'','Sundays',0,0,0,0), >+(3,'',NULL,1,1,'','New Year\'s Day',0,0,0,0), >+(4,'',NULL,12,25,'','Christmas',0,0,0,0); >diff --git a/installer/data/mysql/it-IT/necessari/sample_holidays.sql b/installer/data/mysql/it-IT/necessari/sample_holidays.sql >index 67640a9..f1478de 100644 >--- a/installer/data/mysql/it-IT/necessari/sample_holidays.sql >+++ b/installer/data/mysql/it-IT/necessari/sample_holidays.sql >@@ -1,8 +1,8 @@ > SET FOREIGN_KEY_CHECKS=0; > >-INSERT INTO `repeatable_holidays` VALUES >-(2,'',0,NULL,NULL,'','Domenica'), >-(3,'',NULL,1,1,'','Nuovo anno'), >-(4,'',NULL,25,12,'','Natale'); >+INSERT INTO `calendar_repeats` VALUES >+(2,'',0,NULL,NULL,'','Domenica',0,0,0,0), >+(3,'',NULL,1,1,'','Nuovo anno',0,0,0,0), >+(4,'',NULL,12,25,'','Natale',0,0,0,0); > >-SET FOREIGN_KEY_CHECKS=1; >\ No newline at end of file >+SET FOREIGN_KEY_CHECKS=1; >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index d7eebdd..0721f7b 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -640,6 +640,43 @@ CREATE TABLE `default_circ_rules` ( > PRIMARY KEY (`singleton`) > ) ENGINE=InnoDB DEFAULT CHARSET=utf8; > >+ >+-- >+-- Table structure for table `calendar_events` >+-- >+DROP TABLE IF EXISTS `calendar_events`; >+CREATE TABLE `calendar_events` ( >+ `branchcode` varchar(10) NOT NULL DEFAULT '', >+ `event_date` date NOT NULL, >+ `title` varchar(50) NOT NULL DEFAULT '', >+ `description` text NOT NULL, >+ `open_hour` smallint(6) NOT NULL, >+ `open_minute` smallint(6) NOT NULL, >+ `close_hour` smallint(6) NOT NULL, >+ `close_minute` smallint(6) NOT NULL, >+ PRIMARY KEY (`branchcode`,`event_date`), >+ CONSTRAINT `calendar_events_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) >+) ENGINE=InnoDB DEFAULT CHARSET=utf8; >+ >+-- >+-- Table structure for table `calendar_repeats` >+-- >+DROP TABLE IF EXISTS `calendar_repeats`; >+CREATE TABLE `calendar_repeats` ( >+ `branchcode` varchar(10) NOT NULL DEFAULT '', >+ `weekday` smallint(6) DEFAULT NULL, >+ `month` smallint(6) DEFAULT NULL, >+ `day` smallint(6) DEFAULT NULL, >+ `title` varchar(50) NOT NULL DEFAULT '', >+ `description` text NOT NULL, >+ `open_hour` smallint(6) NOT NULL, >+ `open_minute` smallint(6) NOT NULL, >+ `close_hour` smallint(6) NOT NULL, >+ `close_minute` smallint(6) NOT NULL, >+ UNIQUE KEY `branchcode` (`branchcode`,`weekday`), >+ UNIQUE KEY `branchcode_2` (`branchcode`,`month`,`day`), >+ CONSTRAINT `calendar_repeats_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) >+) ENGINE=InnoDB DEFAULT CHARSET=utf8; > -- > -- Table structure for table `cities` > -- >@@ -1719,22 +1756,6 @@ CREATE TABLE `printers_profile` ( > ) ENGINE=InnoDB DEFAULT CHARSET=utf8; > > -- >--- Table structure for table `repeatable_holidays` >--- >- >-DROP TABLE IF EXISTS `repeatable_holidays`; >-CREATE TABLE `repeatable_holidays` ( -- information for the days the library is closed >- `id` int(11) NOT NULL auto_increment, -- unique identifier assigned by Koha >- `branchcode` varchar(10) NOT NULL default '', -- foreign key from the branches table, defines which branch this closing is for >- `weekday` smallint(6) default NULL, -- day of the week (0=Sunday, 1=Monday, etc) this closing is repeated on >- `day` smallint(6) default NULL, -- day of the month this closing is on >- `month` smallint(6) default NULL, -- month this closing is in >- `title` varchar(50) NOT NULL default '', -- title of this closing >- `description` text NOT NULL, -- description for this closing >- PRIMARY KEY (`id`) >-) ENGINE=InnoDB DEFAULT CHARSET=utf8; >- >--- > -- Table structure for table `reports_dictionary` > -- > >@@ -1917,23 +1938,6 @@ CREATE TABLE sessions ( > ) ENGINE=InnoDB DEFAULT CHARSET=utf8; > > -- >--- Table structure for table `special_holidays` >--- >- >-DROP TABLE IF EXISTS `special_holidays`; >-CREATE TABLE `special_holidays` ( -- non repeatable holidays/library closings >- `id` int(11) NOT NULL auto_increment, -- unique identifier assigned by Koha >- `branchcode` varchar(10) NOT NULL default '', -- foreign key from the branches table, defines which branch this closing is for >- `day` smallint(6) NOT NULL default 0, -- day of the month this closing is on >- `month` smallint(6) NOT NULL default 0, -- month this closing is in >- `year` smallint(6) NOT NULL default 0, -- year this closing is in >- `isexception` smallint(1) NOT NULL default 1, -- is this a holiday exception to a repeatable holiday (1 for yes, 0 for no) >- `title` varchar(50) NOT NULL default '', -- title for this closing >- `description` text NOT NULL, -- description of this closing >- PRIMARY KEY (`id`) >-) ENGINE=InnoDB DEFAULT CHARSET=utf8; >- >--- > -- Table structure for table `statistics` > -- > >diff --git a/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql b/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql >index 7df9e67..d2b5ab7 100644 >--- a/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql >+++ b/installer/data/mysql/nb-NO/2-Valgfritt/sample_holidays.sql >@@ -19,10 +19,10 @@ > -- with Koha; if not, write to the Free Software Foundation, Inc., > -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > >-INSERT INTO `repeatable_holidays` VALUES >-(2,'',0,NULL,NULL,'','Søndager'), >-(3,'',NULL,1,1,'','1. nyttÃ¥rsdag'), >-(4,'',NULL,1,5,'','1. mai'), >-(5,'',NULL,17,5,'','17. mai'), >-(6,'',NULL,25,12,'','1. juledag'), >-(7,'',NULL,26,12,'','2. juledag'); >+INSERT INTO `calendar_repeats` VALUES >+(2,'',0,NULL,NULL,'','Søndager',0,0,0,0), >+(3,'',NULL,1,1,'','1. nyttÃ¥rsdag',0,0,0,0), >+(4,'',NULL,5,1,'','1. mai',0,0,0,0), >+(5,'',NULL,5,17,'','17. mai',0,0,0,0), >+(6,'',NULL,12,25,'','1. juledag',0,0,0,0), >+(7,'',NULL,12,26,'','2. juledag',0,0,0,0); >diff --git a/installer/data/mysql/pl-PL/optional/sample_holidays.sql b/installer/data/mysql/pl-PL/optional/sample_holidays.sql >index bee37b5..6dfd59d 100644 >--- a/installer/data/mysql/pl-PL/optional/sample_holidays.sql >+++ b/installer/data/mysql/pl-PL/optional/sample_holidays.sql >@@ -1,4 +1,4 @@ >-INSERT INTO `repeatable_holidays` VALUES >-(2,'',0,NULL,NULL,'','Niedziele'), >-(3,'',NULL,1,1,'','Nowy Rok'), >-(4,'',NULL,25,12,'','Boże Narodzenie'); >+INSERT INTO `calendar_repeats` VALUES >+(2,'',0,NULL,NULL,'','Niedziele',0,0,0,0), >+(3,'',NULL,1,1,'','Nowy Rok',0,0,0,0), >+(4,'',NULL,12,25,'','Boże Narodzenie',0,0,0,0); >diff --git a/installer/data/mysql/ru-RU/optional/holidays.sql b/installer/data/mysql/ru-RU/optional/holidays.sql >index 42f3311..7d8e00b 100644 >--- a/installer/data/mysql/ru-RU/optional/holidays.sql >+++ b/installer/data/mysql/ru-RU/optional/holidays.sql >@@ -1,23 +1,23 @@ >-TRUNCATE repeatable_holidays; >+TRUNCATE calendar_repeats; > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (2, '',0,NULL,NULL,'','ÐоÑкÑеÑенÑÑ'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',0,NULL,NULL,'','ÐоÑкÑеÑенÑÑ', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (3, '',NULL,1,1,'','ÐовÑй год'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',NULL,1,1,'','ÐовÑй год', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (4, '',NULL,7,1,'','РождеÑÑво'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',NULL,7,1,'','РождеÑÑво', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (5, '',NULL,8,3,'','ÐеждÑнаÑоднÑй женÑкий денÑ'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',NULL,8,3,'','ÐеждÑнаÑоднÑй женÑкий денÑ', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (6, '',NULL,1,5,'','ÐÐµÐ½Ñ Ð¢ÑÑда'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',NULL,1,5,'','ÐÐµÐ½Ñ Ð¢ÑÑда', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (7, '',NULL,2,5,'','ÐÐµÐ½Ñ Ð¢ÑÑда'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',NULL,2,5,'','ÐÐµÐ½Ñ Ð¢ÑÑда', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`id`, `branchcode`, `weekday`, `day`, `month`, `title`, `description`) >-VALUES (8, '',NULL,9,5,'','ÐÐµÐ½Ñ ÐобедÑ'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) >+VALUES ('',NULL,9,5,'','ÐÐµÐ½Ñ ÐобедÑ', 0, 0, 0, 0); > >diff --git a/installer/data/mysql/uk-UA/optional/holidays.sql b/installer/data/mysql/uk-UA/optional/holidays.sql >index 55f45be..f6ce5bd 100644 >--- a/installer/data/mysql/uk-UA/optional/holidays.sql >+++ b/installer/data/mysql/uk-UA/optional/holidays.sql >@@ -1,24 +1,24 @@ >-TRUNCATE repeatable_holidays; >+TRUNCATE calendar_repeats; > >-INSERT INTO `repeatable_holidays` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`) VALUES >-('STL', 0, NULL, NULL,'', 'ÐедÑлÑ'), >-('STL', NULL, 1, 1, '', 'Ðовий ÑÑк'), >-('STL', NULL, 7, 1, '', 'Ð Ñздво'), >-('STL', NULL, 8, 3, '', 'ÐÑжнаÑодний жÑноÑий денÑ'), >-('STL', NULL, 1, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ'), >-('STL', NULL, 2, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ'), >-('STL', NULL, 9, 5, '', 'ÐÐµÐ½Ñ ÐеÑемоги'), >-('STL', NULL, 28, 6, '', 'ÐÐµÐ½Ñ ÐонÑÑиÑÑÑÑÑ'), >-('STL', NULL, 24, 8, '', 'ÐÐµÐ½Ñ ÐезалежноÑÑÑ'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) VALUES >+('STL', 0, NULL, NULL,'', 'ÐедÑлÑ', 0, 0, 0, 0), >+('STL', NULL, 1, 1, '', 'Ðовий ÑÑк', 0, 0, 0, 0), >+('STL', NULL, 7, 1, '', 'Ð Ñздво', 0, 0, 0, 0), >+('STL', NULL, 8, 3, '', 'ÐÑжнаÑодний жÑноÑий денÑ', 0, 0, 0, 0), >+('STL', NULL, 1, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ', 0, 0, 0, 0), >+('STL', NULL, 2, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ', 0, 0, 0, 0), >+('STL', NULL, 9, 5, '', 'ÐÐµÐ½Ñ ÐеÑемоги', 0, 0, 0, 0), >+('STL', NULL, 28, 6, '', 'ÐÐµÐ½Ñ ÐонÑÑиÑÑÑÑÑ', 0, 0, 0, 0), >+('STL', NULL, 24, 8, '', 'ÐÐµÐ½Ñ ÐезалежноÑÑÑ', 0, 0, 0, 0); > >-INSERT INTO `repeatable_holidays` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`) VALUES >-('LNSL', 0, NULL, NULL,'', 'ÐедÑлÑ'), >-('LNSL', NULL, 1, 1, '', 'Ðовий ÑÑк'), >-('LNSL', NULL, 7, 1, '', 'Ð Ñздво'), >-('LNSL', NULL, 8, 3, '', 'ÐÑжнаÑодний жÑноÑий денÑ'), >-('LNSL', NULL, 1, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ'), >-('LNSL', NULL, 2, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ'), >-('LNSL', NULL, 9, 5, '', 'ÐÐµÐ½Ñ ÐеÑемоги'), >-('LNSL', NULL, 28, 6, '', 'ÐÐµÐ½Ñ ÐонÑÑиÑÑÑÑÑ'), >-('LNSL', NULL, 24, 8, '', 'ÐÐµÐ½Ñ ÐезалежноÑÑÑ'); >+INSERT INTO `calendar_repeats` (`branchcode`, `weekday`, `day`, `month`, `title`, `description`, open_hour, open_minute, close_hour, close_minute) VALUES >+('LNSL', 0, NULL, NULL,'', 'ÐедÑлÑ', 0, 0, 0, 0), >+('LNSL', NULL, 1, 1, '', 'Ðовий ÑÑк', 0, 0, 0, 0), >+('LNSL', NULL, 7, 1, '', 'Ð Ñздво', 0, 0, 0, 0), >+('LNSL', NULL, 8, 3, '', 'ÐÑжнаÑодний жÑноÑий денÑ', 0, 0, 0, 0), >+('LNSL', NULL, 1, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ', 0, 0, 0, 0), >+('LNSL', NULL, 2, 5, '', 'ÐÐµÐ½Ñ ÐÑаÑÑ', 0, 0, 0, 0), >+('LNSL', NULL, 9, 5, '', 'ÐÐµÐ½Ñ ÐеÑемоги', 0, 0, 0, 0), >+('LNSL', NULL, 28, 6, '', 'ÐÐµÐ½Ñ ÐонÑÑиÑÑÑÑÑ', 0, 0, 0, 0), >+('LNSL', NULL, 24, 8, '', 'ÐÐµÐ½Ñ ÐезалежноÑÑÑ', 0, 0, 0, 0); > >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 5963d24..91c8167 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -7010,6 +7010,81 @@ CREATE TABLE IF NOT EXISTS borrower_files ( > SetVersion($DBversion); > } > >+$DBversion = "3.13.00.XXX"; >+if ( CheckVersion($DBversion) ) { >+ print "Upgrade to $DBversion done (Bug 8133: create tables, migrate data to calendar_*)\n"; >+ >+ $dbh->do( q{ >+ CREATE TABLE `calendar_events` ( >+ `branchcode` varchar(10) NOT NULL DEFAULT '', >+ `event_date` date NOT NULL, >+ `title` varchar(50) NOT NULL DEFAULT '', >+ `description` text NOT NULL, >+ `open_hour` smallint(6) NOT NULL, >+ `open_minute` smallint(6) NOT NULL, >+ `close_hour` smallint(6) NOT NULL, >+ `close_minute` smallint(6) NOT NULL, >+ PRIMARY KEY (`branchcode`,`event_date`), >+ CONSTRAINT `calendar_events_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8; >+ } ); >+ >+ $dbh->do( q{ >+ CREATE TABLE `calendar_repeats` ( >+ `branchcode` varchar(10) NOT NULL DEFAULT '', >+ `weekday` smallint(6) DEFAULT NULL, >+ `month` smallint(6) DEFAULT NULL, >+ `day` smallint(6) DEFAULT NULL, >+ `title` varchar(50) NOT NULL DEFAULT '', >+ `description` text NOT NULL, >+ `open_hour` smallint(6) NOT NULL, >+ `open_minute` smallint(6) NOT NULL, >+ `close_hour` smallint(6) NOT NULL, >+ `close_minute` smallint(6) NOT NULL, >+ UNIQUE KEY `branchcode` (`branchcode`,`weekday`), >+ UNIQUE KEY `branchcode_2` (`branchcode`,`month`,`day`), >+ CONSTRAINT `calendar_repeats_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8; >+ } ); >+ >+ $dbh->do( q{ >+ INSERT INTO >+ calendar_events(branchcode, event_date, title, description, open_hour, open_minute, close_hour, close_minute) >+ SELECT >+ branchcode, CONCAT_WS('-', year, month, day), title, description, 0, 0, 0, 0 >+ FROM special_holidays >+ WHERE isexception = 0 >+ } ); >+ >+ $dbh->do( q{ >+ INSERT INTO >+ calendar_events(branchcode, event_date, title, description, open_hour, open_minute, close_hour, close_minute) >+ SELECT >+ branchcode, CONCAT_WS('-', year, month, day), title, description, 0, 0, 24, 0 >+ FROM special_holidays >+ WHERE isexception = 1 >+ } ); >+ >+ $dbh->do( q{ >+ INSERT INTO >+ calendar_repeats(branchcode, weekday, month, day, title, description, open_hour, open_minute, close_hour, close_minute) >+ SELECT >+ branchcode, weekday, month, day, title, description, 0, 0, 0, 0 >+ FROM repeatable_holidays >+ WHERE weekday IS NULL >+ } ); >+ >+ $dbh->do( q{ >+ DROP TABLE repeatable_holidays; >+ } ); >+ >+ $dbh->do( q{ >+ DROP TABLE special_holidays; >+ } ); >+ >+ SetVersion($DBversion); >+} >+ > =head1 FUNCTIONS > > =head2 TableExists($table) >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 e4fd8c7..3811264 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >@@ -81,7 +81,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..10212f1 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/calendar.tt >@@ -0,0 +1,597 @@ >+[% 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" /> >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> >+[% INCLUDE 'datatables-strings.inc' %] >+<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> >+<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 %]', >+ description: '[% event.description %]', >+ 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 %]', >+ description: '[% event.description %]', >+ 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 %]', >+ description: '[% event.description %]', >+ 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</label> >+ <input type="radio" name="hoursType" id="showHoursTypeOpenSet" value="openSet" /><label for="showHoursTypeOpenSet">Open (with set hours)</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</label> >+ <input type="radio" name="hoursType" id="newHoursTypeOpenSet" value="openSet" /><label for="newHoursTypeOpenSet">Open (with set hours)</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 8d4e923..0000000 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt >+++ /dev/null >@@ -1,538 +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" /> >-<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> >-[% INCLUDE 'datatables-strings.inc' %] >-<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> >-<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")); >- >- /* Creates all the structures to deal with all diferents 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: "+exception_holidays[dateString].title]; >- } else if ( week_days[weekDay] != null ){ >- return [true, "repeatableweekly", "Weekly holdiay: "+week_days[weekDay].title]; >- } else if ( day_month_holidays[dayMonth] != null ) { >- return [true, "repeatableyearly", "Yearly holdiay: "+day_month_holidays[dayMonth].title]; >- } else if (holidays[dateString] != null) { >- return [true, "holiday", "Single holiday: "+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(); >- }); >- $("#holidayexceptions,#holidayweeklyrepeatable,#holidaysunique").dataTable($.extend(true, {}, dataTablesDefaults, { >- "sDom": 't', >- "bPaginate": false >- })); >- $("#holidaysyearlyrepeatable").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: #D8EFB3 none; color : Black; border : 1px solid #BCBCBC; } >-td.repeatableyearly a.ui-state-default { background: #FFFF99 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 --> >- <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="newOperationFieldException">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" name="cancel2" 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 1st, 2012 will make it a holiday, but will not affect August 1st 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 1st will make August 1st 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 1st, 2012 and August 10st, 2012 will make all days between 1st and 10st 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 1st, 2012 and August 10st, 2012 will make all days between 1st and 10st 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" name="cancel2" 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 holdiay.</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> >-<script type="text/javascript"> >- document.write(weekdays[ [% WEEK_DAYS_LOO.KEY %]]); >-</script> >- </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 4fff721..8aaccb8 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 >@@ -68,7 +68,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 0d819a5..779678d 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 b4d4e9c..e624f80 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 ); >@@ -311,23 +311,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..31e036a 100755 >--- a/t/Calendar.t >+++ b/t/Calendar.t >@@ -4,17 +4,15 @@ use strict; > use warnings; > use DateTime; > use DateTime::Duration; >-use Test::More tests => 35; >+use Test::More tests => 51; > 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'); >+ use Carp; >+ $SIG{ __DIE__ } = sub { Carp::confess( @_ ) }; > } > > my $module_context = new Test::MockModule('C4::Context'); >@@ -42,38 +40,55 @@ SKIP: { > skip "DBD::Mock is too old", 33 > unless $DBD::Mock::VERSION >= 1.45; > >+# Apologies for strange indentation, DBD::Mock is picky > my $holidays_session = DBD::Mock::Session->new('holidays_session' => ( > { # weekly holidays >- statement => "SELECT weekday FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NOT NULL", >+ statement => q{ >+ SELECT >+ weekday, open_hour, open_minute, close_hour, close_minute, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_repeats >+ WHERE branchcode = ? AND weekday IS NOT NULL >+ }, > results => [ >- ['weekday'], >- [0], # sundays >- [6] # saturdays >+ ['weekday', 'open_hour', 'open_minute', 'close_hour', 'close_minute', 'closed'], >+ [0, 0, 0, 0, 0, 1], # sundays >+ [1,10, 0,19, 0, 0], # mondays >+ [2,10, 0,19, 0, 0], # tuesdays >+ [6, 0, 0, 0, 0, 1] # saturdays > ] > }, > { # day and month repeatable holidays >- statement => "SELECT day, month FROM repeatable_holidays WHERE branchcode = ? AND weekday IS NULL", >+ statement => q{ >+ SELECT >+ month, day, open_hour, open_minute, close_hour, close_minute, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_repeats >+ WHERE branchcode = ? AND weekday IS NULL >+ }, > results => [ >- [ 'month', 'day' ], >- [ 1, 1 ], # new year's day >- [12,25] # christmas >+ [ 'month', 'day', 'open_hour', 'open_minute', 'close_hour', 'close_minute', 'closed' ], >+ [ 1, 1, 0, 0, 0, 0, 1], # new year's day >+ [ 6,26,10, 0,15, 0, 0], # wednesdays >+ [12,25, 0, 0, 0, 0, 1] # christmas > ] > }, > { # exception holidays >- statement => "SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 1", >- results => [ >- [ 'day', 'month', 'year' ], >- [ 11, 11, 2012 ] # sunday exception >- ] >+ statement => q{ >+ SELECT >+ event_date, open_hour, open_minute, close_hour, close_minute, >+ (open_hour = 0 AND open_minute = 0 AND close_hour = 0 AND close_minute = 0) AS closed >+ FROM calendar_events >+ WHERE branchcode = ? > }, >- { # single holidays >- statement => "SELECT day, month, year FROM special_holidays WHERE branchcode = ? AND isexception = 0", > results => [ >- [ 'day', 'month', 'year' ], >- [ 1, 6, 2011 ], # single holiday >- [ 4, 7, 2012 ] >+ [ 'event_date', 'open_hour', 'open_minute', 'close_hour', 'close_minute', 'closed' ], >+ [ '2012-11-11', 0, 0,24, 0, 0 ], # sunday exception >+ [ '2011-06-01', 0, 0, 0, 0, 1 ], # single holiday >+ [ '2012-07-04', 0, 0, 0, 0, 1 ], >+ [ '2014-06-26',12, 0,14, 0, 0 ] > ] >- } >+ }, > )); > > # Initialize the global $dbh variable >@@ -193,6 +208,22 @@ my $day_after_christmas = DateTime->new( > minute => 53, > ); > >+ my $same_day_dt = DateTime->new( # Monday >+ year => 2012, >+ month => 7, >+ day => 23, >+ hour => 13, >+ minute => 53, >+ ); >+ >+ my $after_close_dt = DateTime->new( # Monday >+ year => 2012, >+ month => 7, >+ day => 23, >+ hour => 22, >+ minute => 53, >+ ); >+ > my $later_dt = DateTime->new( # Monday > year => 2012, > month => 9, >@@ -236,13 +267,41 @@ my $day_after_christmas = DateTime->new( > is( $cal->addDate($day_after_christmas, -1, 'days')->ymd(), '2012-12-24', > 'Negative call to addDate (Datedue)' ); > >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -10 ), 'hours' ),'eq', >+ '2012-07-20T15:53:00', >+ 'Subtract 10 hours (Datedue)' ); >+ >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 10 ), 'hours' ),'eq', >+ '2012-07-24T12:53:00', >+ 'Add 10 hours (Datedue)' ); >+ >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -1 ), 'hours' ),'eq', >+ '2012-07-23T10:53:00', >+ 'Subtract 1 hours (Datedue)' ); >+ >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 1 ), 'hours' ),'eq', >+ '2012-07-23T12:53:00', >+ 'Add 1 hours (Datedue)' ); >+ > ## Note that the days_between API says closed days are not considered. > ## This tests are here as an API test. > cmp_ok( $cal->days_between( $test_dt, $later_dt )->in_units('days'), >- '==', 40, 'days_between calculates correctly (Days)' ); >+ '==', 40, 'days_between calculates correctly (Datedue)' ); > > cmp_ok( $cal->days_between( $later_dt, $test_dt )->in_units('days'), >- '==', 40, 'Test parameter order not relevant (Days)' ); >+ '==', 40, 'Test parameter order not relevant (Datedue)' ); >+ >+ cmp_ok( $cal->hours_between( $test_dt, $same_day_dt )->in_units('hours'), >+ '==', 2, 'hours_between calculates correctly (short period)' ); >+ >+ cmp_ok( $cal->hours_between( $test_dt, $after_close_dt )->in_units('hours'), >+ '==', 7, 'hours_between calculates correctly (after close)' ); >+ >+ cmp_ok( $cal->hours_between( $test_dt, $later_dt )->in_units('hours'), >+ '==', 725, 'hours_between calculates correctly (Datedue)' ); >+ >+ cmp_ok( $cal->hours_between( $later_dt, $test_dt )->in_units('hours'), >+ '==', 725, 'hours_between parameter order not relevant (Datedue)' ); > > > } >@@ -278,11 +337,33 @@ my $day_after_christmas = DateTime->new( > is( $cal->addDate($day_after_christmas, -1, 'days')->ymd(), '2012-12-24', > 'Negative call to addDate (Calendar)' ); > >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -10 ), 'hours' ),'eq', >+ '2012-07-23T10:00:00', >+ 'Subtract 10 hours (Calendar)' ); >+ >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 10 ), 'hours' ),'eq', >+ '2012-07-23T19:00:00', >+ 'Add 10 hours (Calendar)' ); >+ >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => -1 ), 'hours' ),'eq', >+ '2012-07-23T10:53:00', >+ 'Subtract 1 hours (Calendar)' ); >+ >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 1 ), 'hours' ),'eq', >+ '2012-07-23T12:53:00', >+ 'Add 1 hours (Calendar)' ); >+ > cmp_ok( $cal->days_between( $test_dt, $later_dt )->in_units('days'), > '==', 40, 'days_between calculates correctly (Calendar)' ); > > cmp_ok( $cal->days_between( $later_dt, $test_dt )->in_units('days'), > '==', 40, 'Test parameter order not relevant (Calendar)' ); >+ >+ cmp_ok( $cal->hours_between( $test_dt, $later_dt )->in_units('hours'), >+ '==', 725, 'hours_between calculates correctly (Calendar)' ); >+ >+ cmp_ok( $cal->hours_between( $later_dt, $test_dt )->in_units('hours'), >+ '==', 725, 'hours_between parameter order not relevant (Calendar)' ); > } > > >@@ -315,6 +396,10 @@ my $day_after_christmas = DateTime->new( > is( $cal->addDate($day_after_christmas, -1, 'days')->ymd(), '2012-12-25', > 'Negative call to addDate (Days)' ); > >+ cmp_ok($cal->addDate( $test_dt, DateTime::Duration->new( hours => 10 ), 'hours' ),'eq', >+ '2012-07-23T21:53:00', >+ 'Add 10 hours (Days)' ); >+ > ## Note that the days_between API says closed days are not considered. > ## This tests are here as an API test. > cmp_ok( $cal->days_between( $test_dt, $later_dt )->in_units('days'), >@@ -323,6 +408,12 @@ my $day_after_christmas = DateTime->new( > cmp_ok( $cal->days_between( $later_dt, $test_dt )->in_units('days'), > '==', 40, 'Test parameter order not relevant (Days)' ); > >+ cmp_ok( $cal->hours_between( $test_dt, $later_dt )->in_units('hours'), >+ '==', 725, 'hours_between calculates correctly (Days)' ); >+ >+ cmp_ok( $cal->hours_between( $later_dt, $test_dt )->in_units('hours'), >+ '==', 725, 'hours_between parameter order not relevant (Days)' ); >+ > } > > } # End SKIP block >diff --git a/t/db_dependent/Calendar.t b/t/db_dependent/Calendar.t >new file mode 100644 >index 0000000..a55bb1d >--- /dev/null >+++ b/t/db_dependent/Calendar.t >@@ -0,0 +1,78 @@ >+use Modern::Perl; >+ >+use Test::More tests => 18; >+ >+use C4::Calendar; >+ >+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( 'MPL', 1, undef, undef, $new_holiday ); >+ >+my $weekly_events = GetWeeklyEvents( 'MPL' ); >+is( $weekly_events->[0]->{'title'}, $new_holiday->{'title'}, 'weekly title' ); >+is( $weekly_events->[0]->{'description'}, $new_holiday->{'description'}, 'weekly description' ); >+is( $weekly_events->[0]->{'open_hour'}, 0, 'weekly open_hour' ); >+ >+$new_holiday->{open_hour} = 7; >+ >+ModRepeatingEvent( 'MPL', 1, undef, undef, $new_holiday ); >+$weekly_events = GetWeeklyEvents( 'MPL' ); >+is( scalar @$weekly_events, 1, 'weekly modification, not insertion' ); >+is( $weekly_events->[0]->{'open_hour'}, 7, 'weekly open_hour modified' ); >+ >+ >+# Yearly events >+ >+$new_holiday->{open_hour} = 0; >+ModRepeatingEvent( 'MPL', undef, 6, 26, $new_holiday ); >+ >+my $yearly_events = GetYearlyEvents( 'MPL' ); >+is( $yearly_events->[0]->{'title'}, $new_holiday->{'title'}, 'yearly title' ); >+is( $yearly_events->[0]->{'description'}, $new_holiday->{'description'}, 'yearly description' ); >+is( $yearly_events->[0]->{'open_hour'}, 0, 'yearly open_hour' ); >+ >+$new_holiday->{open_hour} = 8; >+ >+ModRepeatingEvent( 'MPL', undef, 6, 26, $new_holiday ); >+$yearly_events = GetYearlyEvents( 'MPL' ); >+is( scalar @$yearly_events, 1, 'yearly modification, not insertion' ); >+is( $yearly_events->[0]->{'open_hour'}, 8, 'yearly open_hour' ); >+ >+# Single events >+ >+$new_holiday->{open_hour} = 0; >+ModSingleEvent( 'MPL', '2013-03-17', $new_holiday ); >+ >+my $single_events = GetSingleEvents( 'MPL' ); >+is( $single_events->[0]->{'title'}, $new_holiday->{'title'}, 'single title' ); >+is( $single_events->[0]->{'description'}, $new_holiday->{'description'}, 'single description' ); >+is( $single_events->[0]->{'open_hour'}, 0, 'single open_hour' ); >+ >+$new_holiday->{open_hour} = 11; >+ >+ModSingleEvent( 'MPL', '2013-03-17', $new_holiday ); >+$single_events = GetSingleEvents( 'MPL' ); >+is( scalar @$single_events, 1, 'single modification, not insertion' ); >+is( $single_events->[0]->{'open_hour'}, 11, 'single open_hour' ); >+ >+ >+# delete >+ >+DelRepeatingEvent( 'MPL', 1, undef, undef ); >+$weekly_events = GetWeeklyEvents( 'MPL' ); >+is( scalar @$weekly_events, 0, 'weekly deleted' ); >+ >+DelRepeatingEvent( 'MPL', undef, 6, 26 ); >+$yearly_events = GetYearlyEvents( 'MPL' ); >+is( scalar @$yearly_events, 0, 'yearly deleted' ); >+ >+DelSingleEvent( 'MPL', '2013-03-17' ); >+ >+$single_events = GetSingleEvents( 'MPL' ); >+is( scalar @$single_events, 0, 'single deleted' ); >diff --git a/t/db_dependent/lib/KohaTest/Calendar/New.pm b/t/db_dependent/lib/KohaTest/Calendar/New.pm >deleted file mode 100644 >index 745366b..0000000 >--- a/t/db_dependent/lib/KohaTest/Calendar/New.pm >+++ /dev/null >@@ -1,186 +0,0 @@ >-package KohaTest::Calendar::New; >-use base qw( KohaTest ); >- >-use strict; >-use warnings; >- >-use Test::More; >- >-use C4::Calendar; >-sub testing_class { 'C4::Calendar' }; >- >- >-=head2 STARTUP METHODS >- >-These get run once, before the main test methods in this module >- >-=cut >- >-=head2 TEST METHODS >- >-standard test methods >- >-=head3 instantiation >- >- just test to see if I can instantiate an object >- >-=cut >- >-sub instantiation : Test( 14 ) { >- my $self = shift; >- >- my $calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- >- ok( exists $calendar->{'day_month_holidays'}, 'day_month_holidays' ); >- ok( exists $calendar->{'single_holidays'}, 'single_holidays' ); >- ok( exists $calendar->{'week_days_holidays'}, 'week_days_holidays' ); >- ok( exists $calendar->{'exception_holidays'}, 'exception_holidays' ); >- >- # sample data has Sundays as a holiday >- ok( exists $calendar->{'week_days_holidays'}->{'0'} ); >- is( $calendar->{'week_days_holidays'}->{'0'}->{'title'}, '', 'Sunday title' ); >- is( $calendar->{'week_days_holidays'}->{'0'}->{'description'}, 'Sundays', 'Sunday description' ); >- >- # sample data has Christmas as a holiday >- ok( exists $calendar->{'day_month_holidays'}->{'12/25'} ); >- is( $calendar->{'day_month_holidays'}->{'12/25'}->{'title'}, '', 'Christmas title' ); >- is( $calendar->{'day_month_holidays'}->{'12/25'}->{'description'}, 'Christmas', 'Christmas description' ); >- >- # sample data has New Year's Day as a holiday >- ok( exists $calendar->{'day_month_holidays'}->{'1/1'} ); >- is( $calendar->{'day_month_holidays'}->{'1/1'}->{'title'}, '', 'New Year title' ); >- is( $calendar->{'day_month_holidays'}->{'1/1'}->{'description'}, q(New Year's Day), 'New Year description' ); >- >-} >- >-sub week_day_holidays : Test( 8 ) { >- my $self = shift; >- >- my $calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- >- ok( exists $calendar->{'week_days_holidays'}, 'week_days_holidays' ); >- >- my %new_holiday = ( weekday => 1, >- title => 'example week_day_holiday', >- description => 'This is an example week_day_holiday used for testing' ); >- my $new_calendar = $calendar->insert_week_day_holiday( %new_holiday ); >- >- # the calendar object returned from insert_week_day_holiday should be updated >- isa_ok( $new_calendar, 'C4::Calendar' ); >- is( $new_calendar->{'week_days_holidays'}->{ $new_holiday{'weekday'} }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'week_days_holidays'}->{ $new_holiday{'weekday'} }->{'description'}, $new_holiday{'description'}, 'description' ); >- >- # new calendar objects should have the newly inserted holiday. >- my $refreshed_calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $refreshed_calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- is( $new_calendar->{'week_days_holidays'}->{ $new_holiday{'weekday'} }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'week_days_holidays'}->{ $new_holiday{'weekday'} }->{'description'}, $new_holiday{'description'}, 'description' ); >- >-} >- >- >-sub day_month_holidays : Test( 8 ) { >- my $self = shift; >- >- my $calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- >- ok( exists $calendar->{'day_month_holidays'}, 'day_month_holidays' ); >- >- my %new_holiday = ( day => 4, >- month => 5, >- title => 'example day_month_holiday', >- description => 'This is an example day_month_holiday used for testing' ); >- my $new_calendar = $calendar->insert_day_month_holiday( %new_holiday ); >- >- # the calendar object returned from insert_week_day_holiday should be updated >- isa_ok( $new_calendar, 'C4::Calendar' ); >- my $mmdd = sprintf('%s/%s', $new_holiday{'month'}, $new_holiday{'day'} ) ; >- is( $new_calendar->{'day_month_holidays'}->{ $mmdd }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'day_month_holidays'}->{ $mmdd }->{'description'}, $new_holiday{'description'}, 'description' ); >- >- # new calendar objects should have the newly inserted holiday. >- my $refreshed_calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $refreshed_calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- is( $new_calendar->{'day_month_holidays'}->{ $mmdd }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'day_month_holidays'}->{ $mmdd }->{'description'}, $new_holiday{'description'}, 'description' ); >- >-} >- >- >- >-sub exception_holidays : Test( 8 ) { >- my $self = shift; >- >- my $calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- >- ok( exists $calendar->{'exception_holidays'}, 'exception_holidays' ); >- >- my %new_holiday = ( day => 4, >- month => 5, >- year => 2010, >- title => 'example exception_holiday', >- description => 'This is an example exception_holiday used for testing' ); >- my $new_calendar = $calendar->insert_exception_holiday( %new_holiday ); >- # diag( Data::Dumper->Dump( [ $new_calendar ], [ 'newcalendar' ] ) ); >- >- # the calendar object returned from insert_week_day_holiday should be updated >- isa_ok( $new_calendar, 'C4::Calendar' ); >- my $yyyymmdd = sprintf('%s/%s/%s', $new_holiday{'year'}, $new_holiday{'month'}, $new_holiday{'day'} ) ; >- is( $new_calendar->{'exception_holidays'}->{ $yyyymmdd }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'exception_holidays'}->{ $yyyymmdd }->{'description'}, $new_holiday{'description'}, 'description' ); >- >- # new calendar objects should have the newly inserted holiday. >- my $refreshed_calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $refreshed_calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- is( $new_calendar->{'exception_holidays'}->{ $yyyymmdd }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'exception_holidays'}->{ $yyyymmdd }->{'description'}, $new_holiday{'description'}, 'description' ); >- >-} >- >- >-sub single_holidays : Test( 8 ) { >- my $self = shift; >- >- my $calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- >- ok( exists $calendar->{'single_holidays'}, 'single_holidays' ); >- >- my %new_holiday = ( day => 4, >- month => 5, >- year => 2011, >- title => 'example single_holiday', >- description => 'This is an example single_holiday used for testing' ); >- my $new_calendar = $calendar->insert_single_holiday( %new_holiday ); >- # diag( Data::Dumper->Dump( [ $new_calendar ], [ 'newcalendar' ] ) ); >- >- # the calendar object returned from insert_week_day_holiday should be updated >- isa_ok( $new_calendar, 'C4::Calendar' ); >- my $yyyymmdd = sprintf('%s/%s/%s', $new_holiday{'year'}, $new_holiday{'month'}, $new_holiday{'day'} ) ; >- is( $new_calendar->{'single_holidays'}->{ $yyyymmdd }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'single_holidays'}->{ $yyyymmdd }->{'description'}, $new_holiday{'description'}, 'description' ); >- >- # new calendar objects should have the newly inserted holiday. >- my $refreshed_calendar = C4::Calendar->new( branchcode => '' ); >- isa_ok( $refreshed_calendar, 'C4::Calendar' ); >- # diag( Data::Dumper->Dump( [ $calendar ], [ 'calendar' ] ) ); >- is( $new_calendar->{'single_holidays'}->{ $yyyymmdd }->{'title'}, $new_holiday{'title'}, 'title' ); >- is( $new_calendar->{'single_holidays'}->{ $yyyymmdd }->{'description'}, $new_holiday{'description'}, 'description' ); >- >-} >- >- >-1; >- >diff --git a/t/db_dependent/lib/KohaTest/Circulation.pm b/t/db_dependent/lib/KohaTest/Circulation.pm >index 2ec90b2..b24ba5a 100644 >--- a/t/db_dependent/lib/KohaTest/Circulation.pm >+++ b/t/db_dependent/lib/KohaTest/Circulation.pm >@@ -43,9 +43,6 @@ sub methods : Test( 1 ) { > UpdateHoldingbranch > CalcDateDue > CheckValidDatedue >- CheckRepeatableHolidays >- CheckSpecialHolidays >- CheckRepeatableSpecialHolidays > CheckValidBarcode > ReturnLostItem > ProcessOfflinePayment >diff --git a/t/db_dependent/lib/KohaTest/Overdues.pm b/t/db_dependent/lib/KohaTest/Overdues.pm >index 5890d2b..a3b96e4 100644 >--- a/t/db_dependent/lib/KohaTest/Overdues.pm >+++ b/t/db_dependent/lib/KohaTest/Overdues.pm >@@ -15,9 +15,6 @@ sub methods : Test( 1 ) { > my @methods = qw( Getoverdues > checkoverdues > CalcFine >- GetSpecialHolidays >- GetRepeatableHolidays >- GetWdayFromItemnumber > GetIssuesIteminfo > UpdateFine > BorType >diff --git a/tools/calendar.pl b/tools/calendar.pl >new file mode 100755 >index 0000000..638a336 >--- /dev/null >+++ b/tools/calendar.pl >@@ -0,0 +1,255 @@ >+#!/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 Modern::Perl '2009'; >+ >+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.tmpl", >+ 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->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' ); >+ >+ my ( $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 ) { >+ given ( $input->param( 'eventType' ) ) { >+ when ( 'single' ) { >+ ModSingleEvent( $branchcode, $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 >+ } ); >+ } >+ >+ when ( 'weekly' ) { >+ ModRepeatingEvent( $branchcode, $input->param( 'weekday' ), undef, undef, { >+ title => $input->param( 'title' ), >+ description => $input->param( 'description' ), >+ open_hour => $open_hour, >+ open_minute => $open_minute, >+ close_hour => $close_hour, >+ close_minute => $close_minute >+ } ); >+ } >+ >+ when ( 'yearly' ) { >+ ModRepeatingEvent( $branchcode, undef, $input->param( 'month' ), $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 >+ } ); >+ } >+ >+ when ( 'singlerange' ) { >+ foreach my $dt ( @ranged_dates ) { >+ ModSingleEvent( $branchcode, $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 >+ } ); >+ } >+ } >+ >+ when ( 'yearlyrange' ) { >+ foreach my $dt ( @ranged_dates ) { >+ ModRepeatingEvent( $branchcode, undef, $dt->month, $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 >+ } ); >+ } >+ } >+ } >+ } >+} elsif ( $op eq 'delete' ) { >+ my $date = $input->param( 'year' ) . '-' . $input->param( 'month' ) . '-' . $input->param( 'day' ); >+ >+ foreach my $branchcode ( @branches ) { >+ given ( $input->param( 'eventType' ) ) { >+ when ( 'single' ) { >+ DelSingleEvent( $branchcode, $date ); >+ } >+ >+ when ( 'weekly' ) { >+ DelRepeatingEvent( $branchcode, $input->param( 'weekday' ), undef, undef ); >+ } >+ >+ when ( 'yearly' ) { >+ DelRepeatingEvent( $branchcode, undef, $input->param( 'month' ), $input->param( 'day' ) ); >+ } >+ } >+ } >+} elsif ( $op eq 'deleterange' ) { >+ foreach my $branchcode ( @branches ) { >+ foreach my $dt ( @ranged_dates ) { >+ DelSingleEvent( $branchcode, $dt->ymd ); >+ } >+ } >+} elsif ( $op eq 'deleterangerepeat' ) { >+ foreach my $branchcode ( @branches ) { >+ foreach my $dt ( @ranged_dates ) { >+ DelRepeatingEvent( $branchcode, undef, $dt->month, $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 38c889d..0000000 >--- a/tools/holidays.pl >+++ /dev/null >@@ -1,163 +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.tmpl", >- 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->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}; >- >-# 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.10.4
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 8133
:
19326
|
19494
|
19740
|
29336
|
31973
|
32176
|
32327
|
32985
|
32986
|
32990
|
32991