From 05e86e433d96964509aab2bf905814b0767500bc Mon Sep 17 00:00:00 2001 From: Maryse Simard Date: Thu, 18 May 2023 16:22:20 -0400 Subject: [PATCH] Bug 17015: Miscellaneous corrections --- Koha/DiscreteCalendar.pm | 69 +- .../intranet-tmpl/prog/css/src/calendar.scss | 13 + .../en/modules/tools/discrete_calendar.tt | 646 +++++++++--------- tools/discrete_calendar.pl | 32 +- 4 files changed, 399 insertions(+), 361 deletions(-) diff --git a/Koha/DiscreteCalendar.pm b/Koha/DiscreteCalendar.pm index 6b5ef2c0f5..80161d991b 100644 --- a/Koha/DiscreteCalendar.pm +++ b/Koha/DiscreteCalendar.pm @@ -1049,22 +1049,25 @@ Returns a string representing the next day the library is open, starting from C< =cut sub next_open_day { - my ( $self, $date ) = @_; + my ( $self, $date, $dayweek ) = @_; my $branchcode = $self->{branchcode}; my $schema = Koha::Database->new->schema; my $dtf = $schema->storage->datetime_parser; my $formatted_date = $dtf->format_datetime($date); + my $options = { + order_by => { -asc => 'date' }, + rows => 1, + }; + $options->{where} = \['DAYOFWEEK(date) = DAYOFWEEK(?)', $formatted_date] if $dayweek; + my $rs = $schema->resultset('DiscreteCalendar')->search( { branchcode => $branchcode, is_opened => 1, + date => { '>' => \['DATE(?)', $formatted_date] }, }, - { - where => \['date > date(?)', $formatted_date], - order_by => { -asc => 'date' }, - rows => 1 - } + $options ); my $next = $rs->next(); @@ -1084,22 +1087,25 @@ Returns a string representing the closest previous day the library was open, sta =cut sub prev_open_day { - my ( $self, $date ) = @_; + my ( $self, $date, $dayweek ) = @_; my $branchcode = $self->{branchcode}; my $schema = Koha::Database->new->schema; my $dtf = $schema->storage->datetime_parser; my $formatted_date = $dtf->format_datetime($date); + my $options = { + order_by => { -desc => 'date' }, + rows => 1, + }; + $options->{where} = \['DAYOFWEEK(date) = DAYOFWEEK(?)', $formatted_date] if $dayweek; + my $rs = $schema->resultset('DiscreteCalendar')->search( { branchcode => $branchcode, is_opened => 1, + date => { '<' => \['DATE(?)', $formatted_date] }, }, - { - where => \['date < date(?)', $formatted_date], - order_by => { -desc => 'date' }, - rows => 1 - } + $options ); my $prev = $rs->next(); @@ -1165,11 +1171,12 @@ sub hours_between { my $hours_between = $schema->resultset('DiscreteCalendar')->search( { branchcode => $branchcode, - is_opened => 0 + is_opened => 0, + date => { + '>=' => $start_date, + '<' => $end_date, + }, }, - { - where => {date => {-between => [$start_date, $end_date]}}, - } ); if ($skipped_days = $hours_between->count()) { @@ -1351,18 +1358,36 @@ sub addDays { } else { # Days or Datedue # use straight days, then use calendar to push - # the date to the next open day if Datedue + # the date to the next open day as appropriate + # if Datedue or Dayweek $base_date->add_duration($days_duration); - if ( $self->{days_mode} eq 'Datedue' ) { - # Datedue, then use the calendar to push + if ( $self->{days_mode} eq 'Datedue' || + $self->{days_mode} eq 'Dayweek') { + # Datedue or Dayweek, then use the calendar to push # the date to the next open day if holiday - if (!$self->is_opened($base_date) ) { + if ( $self->is_holiday($base_date) ) { + my $days = $days_duration->in_units('days'); + + my $dayweek = 0; + if ( + $self->{days_mode} eq 'Dayweek' && + $days % 7 == 0 # Is it a period based on weeks + ) { + my $dow = $base_date->day_of_week; + # Representation fix + # DateTime object dow (1-7) where Monday is 1 + # in Koha::DiscreteCalendar 1 = Sunday, not 7. + $dow = ( $dow == 7 ) ? 1 : $dow + 1; + + my @weekly_holidays = $self->get_week_days_holidays(); + $dayweek = !(@weekly_holidays && grep $_->{weekday} == $dow, @weekly_holidays); + } if ( $days_duration->is_negative() ) { - $base_date = $self->prev_open_day($base_date); + $base_date = $self->prev_open_day($base_date, $dayweek); } else { - $base_date = $self->next_open_day($base_date); + $base_date = $self->next_open_day($base_date, $dayweek); } } } diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/calendar.scss b/koha-tmpl/intranet-tmpl/prog/css/src/calendar.scss index aaaa0adb6d..988b2ddc94 100644 --- a/koha-tmpl/intranet-tmpl/prog/css/src/calendar.scss +++ b/koha-tmpl/intranet-tmpl/prog/css/src/calendar.scss @@ -177,3 +177,16 @@ fieldset.brief li.radio { .dayContainer { gap: 3px; } + +.calendar { + display: flex; + align-items: start; + gap: 10px; + flex-wrap: wrap; +} + +#newHoliday { + flex-grow: 1; + margin-top: 2px; + border-radius: 0; +} diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/discrete_calendar.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/discrete_calendar.tt index 3b89bd13ff..56aff70001 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/discrete_calendar.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/discrete_calendar.tt @@ -9,24 +9,20 @@ -[% INCLUDE 'header.inc' %] -[% INCLUDE 'cat-search.inc' %] - - + [% END %] + [% WRAPPER breadcrumb_item bc_active= 1 %] + [% Branches.GetName( branch ) | html %] calendar + [% END %] + [% END #/ WRAPPER breadcrumbs %] +[% END #/ WRAPPER sub-header.inc %]
@@ -59,310 +55,320 @@

[% Branches.GetName( branch ) | html %] calendar

-
- -
- - Copy calendar to - + [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %] + + Copy calendar to + - - -
- -

Calendar information

- - - - -
-
-
-

Edit date details

- -
    -
  1. - Library: - - -
  2. -
  3. - From date: - , - - [% IF ( dateformat == "us" ) %]// - [% ELSIF ( dateformat == "metric" ) %]// - [% ELSIF ( dateformat == "dmydot" ) %].. - [% ELSE %]//[% END %] - - - - - -
  4. -
  5. - To date: - -
  6. -
  7. - - -
  8. -
  9. - - -
  10. -
  11. - - - [?] -
    -
      -
    1. Working day: the library is open on that day.
    2. -
    3. Unique holiday: make a single holiday. For example, selecting August 1, 2012 will make it a holiday, but will not affect August 1 in other years.
    4. -
    5. Weekly holiday: 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.
    6. -
    7. Repeatable holiday: this will take this day and month as a reference to make it a holiday. Through this option, you can repeat this rule for every year. For example, selecting August 1 will make August 1 a holiday every year.
    8. -
    9. Floating holiday: this will take this day and month as a reference to make it a floating holiday. Through this option, you can add a holiday that repeats every year but not necessarily on the exact same day. On subsequent years the date will need validation.
    10. -
    11. Need validation: this holiday has been added automatically, but needs to be validated.
    12. -
    -
    -
  12. -
  13. - - -
  14. -
  15. - - [?] -
    Remove all repeated or weekly holidays of the selected date or week day
    if working day is selected.
    -
  16. -
  17. - -
  18. -
  19. - -
  20. -
  21. - - -
  22. -
  23. - - -
  24. -
  25. - - - - -
  26. -
  27. - - . - [?] -
    If checked, this holiday will be copied to all libraries.
    -
  28. -
- - - - - - - - - -
- - Cancel -
-
+ + +
-
-
- -
-
-

Hints

-
    -
  • Search in the calendar the day you want to set as holiday.
  • -
  • Click the date to add or edit a holiday.
  • -
  • Enter a title and description for the holiday.
  • -
  • Specify how the holiday should repeat.
  • -
  • Click Save to finish.
  • -
  • PS: -
      -
    • Past dates cannot be changed
    • -
    • Weekly holidays change open/close hours for all the days affected unless inputs are empty
    • -
    -
  • -
-

Key

-

- Working day - Unique holiday - Holiday repeating weekly - Holiday repeating yearly - Floating holiday - Need validation -

-
- -
- [% IF ( NEED_VALIDATION_HOLIDAYS ) %] -

Need validation holidays

- - - - - - - - - - [% FOREACH need_validation_holiday IN NEED_VALIDATION_HOLIDAYS %] - - - - - - [% END %] - - - [% END %] - - [% IF ( WEEKLY_HOLIDAYS ) %] -

Weekly - Repeatable holidays

- - - - - - - - - - [% FOREACH WEEK_DAYS_LOO IN WEEKLY_HOLIDAYS %] - - - - - - [% END %] - - - [% END %] - - [% IF ( REPEATABLE_HOLIDAYS ) %] -

Yearly - Repeatable holidays

- - - - [% IF ( dateformat == "metric" ) %] - - [% ELSE %] - + +

Calendar information

+ +
+ + + +
+
+
+

Edit date details

+ +
    +
  1. + Library: + + +
  2. +
  3. + From date: + , + + [% IF ( dateformat == "us" ) %] + // + [% ELSIF ( dateformat == "metric" ) %] + // + [% ELSIF ( dateformat == "dmydot" ) %] + .. + [% ELSE %] + // + [% END %] + + + + + +
  4. +
  5. + To date: + +
  6. +
  7. + + +
  8. +
  9. + + +
  10. +
  11. + + + [?] +
    +
      +
    1. Working day: the library is open on that day.
    2. +
    3. Unique holiday: make a single holiday. For example, selecting August 1, 2012 will make it a holiday, but will not affect August 1 in other years.
    4. +
    5. Weekly holiday: 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.
    6. +
    7. Repeatable holiday: this will take this day and month as a reference to make it a holiday. Through this option, you can repeat this rule for every year. For example, selecting August 1 will make August 1 a holiday every year.
    8. +
    9. Floating holiday: this will take this day and month as a reference to make it a floating holiday. Through this option, you can add a holiday that repeats every year but not necessarily on the exact same day. On subsequent years the date will need validation.
    10. +
    11. Need validation: this holiday has been added automatically, but needs to be validated.
    12. +
    +
    +
  12. +
  13. + + +
  14. +
  15. + + [?] +
    Remove all repeated or weekly holidays of the selected date or week day
    if working day is selected.
    +
  16. +
  17. + +
  18. +
  19. + +
  20. +
  21. + + +
  22. +
  23. + + +
  24. +
  25. + + + + +
  26. +
  27. + + . + [?] +
    If checked, this holiday will be copied to all libraries.
    +
  28. +
+ + + + + + + + + +
+ + Cancel +
+
+ +
+
+ + + +
+
+
+

Hints

+
    +
  • Search in the calendar the day you want to set as holiday.
  • +
  • Click the date to add or edit a holiday.
  • +
  • Enter a title and description for the holiday.
  • +
  • Specify how the holiday should repeat.
  • +
  • Click Save to finish.
  • +
  • PS: +
      +
    • Past dates cannot be changed
    • +
    • Weekly holidays change open/close hours for all the days affected unless inputs are empty
    • +
    +
  • +
+

Key

+

+ Working day + Unique holiday + Holiday repeating weekly + Holiday repeating yearly + Floating holiday + Need validation +

+
+ +
+ [% IF ( NEED_VALIDATION_HOLIDAYS ) %] +

Need validation holidays

+
+ + + + + + + + + [% FOREACH need_validation_holiday IN NEED_VALIDATION_HOLIDAYS %] + + + + + [% END %] - - - - - - [% FOREACH DAY_MONTH_HOLIDAYS_LOO IN REPEATABLE_HOLIDAYS %] - - [% IF ( dateformat == "metric" ) %] - - [% ELSE %] - + + + [% END # /IF ( EXCEPTION_HOLIDAYS_LOOP ) %] + + [% IF ( WEEKLY_HOLIDAYS ) %] +

Weekly - Repeatable holidays

+ + + + + + + + + + [% FOREACH WEEK_DAYS_LOO IN WEEKLY_HOLIDAYS %] + + + + + [% END %] - - - - [% END %] - - - [% END %] - - [% IF ( UNIQUE_HOLIDAYS ) %] -

Unique holidays

- - - - - - - - - - - [% FOREACH HOLIDAYS_LOO IN UNIQUE_HOLIDAYS %] - - - - - - [% END %] - - - [% END %] - - [% IF ( FLOAT_HOLIDAYS ) %] -

Floating holidays

- - - - - - - - - - - [% FOREACH float_holiday IN FLOAT_HOLIDAYS %] - - - - - - [% END %] - - - [% END %] -
-
-
- + + + [% END # / IF ( WEEKLY_HOLIDAYS ) %] + + [% IF ( REPEATABLE_HOLIDAYS ) %] +

Yearly - Repeatable holidays

+ + + + [% IF ( dateformat == "metric" ) %] + + [% ELSE %] + + [% END %] + + + + + + [% FOREACH DAY_MONTH_HOLIDAYS_LOO IN REPEATABLE_HOLIDAYS %] + + [% IF ( dateformat == "metric" ) %] + + [% ELSE %] + + [% END %] + + + + [% END %] + + + [% END # /IF ( REPEATABLE_HOLIDAYS ) %] + + [% IF ( UNIQUE_HOLIDAYS ) %] +

Unique holidays

+ + + + + + + + + + + [% FOREACH HOLIDAYS_LOO IN UNIQUE_HOLIDAYS %] + + + + + + [% END %] + + + [% END # /IF ( UNIQUE_HOLIDAYS ) %] + + [% IF ( FLOAT_HOLIDAYS ) %] +

Floating holidays

+ + + + + + + + + + + [% FOREACH float_holiday IN FLOAT_HOLIDAYS %] + + + + + + [% END %] + + + [% END # /IF ( FLOAT_HOLIDAYS ) %] +
+
+ + @@ -460,6 +466,7 @@ $(".CopyDatePanel").toggle(value); } $("#title").prop('disabled', value); + $("#description").prop('disabled', value); $("#holidayType select").prop('disabled', value); $("#openHour").prop('disabled', value); $("#closeHour").prop('disabled', value); @@ -681,7 +688,9 @@ }); $("a.helptext").click(function () { - $(this).parent().find(".hint").toggle(); + $(this).parent().find(".hint") + .css("max-width", ($(this).closest("#newHoliday").width() - 20)+"px") + .toggle(); return false; }); @@ -796,5 +805,4 @@ [% END %] - [% INCLUDE 'intranet-bottom.inc' %] diff --git a/tools/discrete_calendar.pl b/tools/discrete_calendar.pl index 96dd7daa31..71c46a9e8d 100755 --- a/tools/discrete_calendar.pl +++ b/tools/discrete_calendar.pl @@ -20,8 +20,8 @@ use Modern::Perl; use CGI qw ( -utf8 ); -use C4::Auth qw ( get_template_and_user ); -use C4::Output qw ( output_html_with_http_headers ); +use C4::Auth qw( get_template_and_user ); +use C4::Output qw( output_html_with_http_headers ); use Koha::DateUtils qw ( dt_from_string output_pref ); use Koha::DiscreteCalendar; @@ -35,7 +35,6 @@ my ($template, $loggedinuser, $cookie) = get_template_and_user( type => "intranet", query => $input, flagsrequired => {tools => 'edit_calendar'}, - debug => 1, } ); @@ -56,11 +55,13 @@ my $action = $input->param('action') || ''; # calendardate - date passed in url for human readability (syspref) # if the url has an invalid date default to 'now.' -my $calendarinput_dt = eval { dt_from_string( scalar $input->param('calendardate')); } || dt_from_string; +# FIXME There is something to improve in the date handling here +my $calendarinput_dt = eval { dt_from_string( scalar $input->param('calendardate') ); } || dt_from_string; my $calendardate = output_pref( { dt => $calendarinput_dt, dateonly => 1 } ); if ($action eq 'copyBranch') { - $calendar->copy_to_branch(scalar $input->param('newBranch')); + my $new_branch = scalar $input->param('newBranch'); + $calendar->copy_to_branch($new_branch) if $new_branch; } elsif($action eq 'copyDates') { my $from_startDate = $input->param('from_date') ||''; my $from_endDate = $input->param('to_date') || ''; @@ -139,33 +140,24 @@ if ( C4::Context->only_my_library ) { # Get all the holidays -#discrete_calendar weekly holidays my @week_days = $calendar->get_week_days_holidays(); - -#discrete_calendar repeatable holidays my @repeatable_holidays = $calendar->get_repeatable_holidays(); +my @unique_holidays = $calendar->get_unique_holidays(0); +my @float_holidays = $calendar->get_float_holidays(0); +my @need_validation_holidays = $calendar->get_need_validation_holidays(); -#discrete_calendar unique holidays -my @unique_holidays =$calendar->get_unique_holidays(0); -#discrete_calendar floating holidays -my @float_holidays =$calendar->get_float_holidays(0); -#discrete_caledar need validation holidays -my @need_validation_holidays =$calendar->get_need_validation_holidays(); - -#Calendar maximum date +#Calendar minimum & maximum dates my $minDate = $calendar->get_min_date(); - -#Calendar minimum date my $maxDate = $calendar->get_max_date(); my @datesInfos = $calendar->get_dates_info(); $template->param( + WEEKLY_HOLIDAYS => \@week_days, + REPEATABLE_HOLIDAYS => \@repeatable_holidays, UNIQUE_HOLIDAYS => \@unique_holidays, FLOAT_HOLIDAYS => \@float_holidays, NEED_VALIDATION_HOLIDAYS => \@need_validation_holidays, - REPEATABLE_HOLIDAYS => \@repeatable_holidays, - WEEKLY_HOLIDAYS => \@week_days, calendardate => $calendardate, keydate => $keydate, branch => $branch, -- 2.34.1