[Bps-public-commit] rtx-calendar branch multiple-days-events created. 1.05-19-g9bc3c34

BPS Git Server git at git.bestpractical.com
Fri Sep 8 00:46:58 UTC 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rtx-calendar".

The branch, multiple-days-events has been created
        at  9bc3c341436fd0ca5de3b584cd2beccea5fab6bb (commit)

- Log -----------------------------------------------------------------
commit 9bc3c341436fd0ca5de3b584cd2beccea5fab6bb
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date:   Thu Sep 7 18:26:10 2023 -0300

    Add Multiple Days Events to Calendar
    
    Add Multiple Days Events to Calendar where an event can span multiple
    based on customizable start and end time fields.

diff --git a/html/Elements/MyCalendar b/html/Elements/MyCalendar
index 5220934..f95cc9d 100644
--- a/html/Elements/MyCalendar
+++ b/html/Elements/MyCalendar
@@ -23,7 +23,7 @@
     <td class="<% @classes %>"><div class="inside-day">
       <div class="calendardate"><%$date->day%></div>
 
-%     for my $t ( $SortCalendarEvents->( @{ $Tickets{ $date->strftime("%F") } || [] } )) {
+%     for my $t ( $SortCalendarEvents->( @{ $Tickets->{ $date->strftime("%F") } || [] } )) {
         <& /Elements/CalendarEvent, Object => $t, Date => $date, DateTypes => \%DateTypes &>
 %     }
 
@@ -95,7 +95,7 @@ $Query .= RTx::Calendar::DatesClauses(\@Dates, $begin->strftime("%F"), $end->str
 
 $m->callback( CallbackName => 'BeforeFindTickets', ARGSRef => \%ARGS, QueryRef => \$Query, FormatRef => \$Format );
 
-my %Tickets = RTx::Calendar::FindTickets($session{'CurrentUser'}, $Query, \@Dates);
+my $Tickets = RTx::Calendar::FindTickets($session{'CurrentUser'}, $Query, \@Dates);
 
 my $SortCalendarEvents = RT->Config->Get("CalendarSortEvents");
 
diff --git a/html/Search/Calendar.html b/html/Search/Calendar.html
index 5ba02af..d827a68 100644
--- a/html/Search/Calendar.html
+++ b/html/Search/Calendar.html
@@ -163,7 +163,7 @@ foreach my $TranslatedLegend (sort keys %CalendarIconsTranslated) {
     <td class="<% @classes %>"><div class="inside-day">
       <div class="calendardate"><%$date->day%></div>
 
-%     for my $t ( $SortCalendarEvents->( @{ $Tickets{ $date->strftime("%F") } || [] } )) {
+%     for my $t ( $SortCalendarEvents->( @{ $Tickets->{ $date->strftime("%F") } || [] } )) {
         <& /Elements/CalendarEvent, Object => $t, Date => $date, DateTypes => \%DateTypes &>
 %     }
 
@@ -357,7 +357,7 @@ $TempQuery .= RTx::Calendar::DatesClauses(\@Dates, $date->strftime("%F"), $end->
 
 $m->callback( CallbackName => 'BeforeFindTickets', ARGSRef => \%ARGS, QueryRef => \$TempQuery, FormatRef => \$TempFormat );
 
-my %Tickets = RTx::Calendar::FindTickets($session{'CurrentUser'}, $TempQuery, \@Dates, $date->strftime("%F"), $end->strftime("%F"));
+my $Tickets = RTx::Calendar::FindTickets($session{'CurrentUser'}, $TempQuery, \@Dates, $date->strftime("%F"), $end->strftime("%F"));
 
 my $DownloadQueryString =
       $m->comp(
diff --git a/lib/RTx/Calendar.pm b/lib/RTx/Calendar.pm
index 8120ece..79121ea 100644
--- a/lib/RTx/Calendar.pm
+++ b/lib/RTx/Calendar.pm
@@ -58,6 +58,15 @@ sub DatesClauses {
 sub FindTickets {
     my ( $CurrentUser, $Query, $Dates, $begin, $end ) = @_;
 
+    my $multiple_days_events = RT->Config->Get('CalendarMultipleDaysEvents');
+    my @multiple_days_fields;
+    for my $event ( keys %$multiple_days_events ) {
+        for my $type ( keys %{ $multiple_days_events->{$event} } ) {
+            push @multiple_days_fields,
+                $multiple_days_events->{$event}{$type};
+        }
+    }
+
     $Query .= DatesClauses( $Dates, $begin, $end )
         if $begin and $end;
 
@@ -66,40 +75,17 @@ sub FindTickets {
 
     my %Tickets;
     my %AlreadySeen;
+    my %TicketsSpanningDays;
+    my %TicketsSpanningDaysAlreadySeen;
 
     while ( my $Ticket = $Tickets->Next() ) {
-
         # How to find the LastContacted date ?
+        # Find single day events fields
         for my $Date (@$Dates) {
-
             # $dateindex is the date to use as key in the Tickets Hash
             # in the YYYY-MM-DD format
             # Tickets are then groupd by date in the %Tickets hash
-            my $dateindex;
-            if ($Date =~ /^CF\./){
-                my $cf = $Date;
-                $cf =~ s/^CF\.\{(.*)\}/$1/;
-
-                my $CFDateValue = $Ticket->FirstCustomFieldValue($cf);
-                next unless $CFDateValue;
-                my $CustomFieldObj = RT::CustomField->new($CurrentUser);
-                $CustomFieldObj->LoadByName( Name => $cf );
-                my $CustomFieldObjType = $CustomFieldObj->Type;
-                my $DateObj            = RT::Date->new($CurrentUser);
-                if ( $CustomFieldObjType eq 'Date' ) {
-                    $DateObj->Set(
-                        Format   => 'unknown',
-                        Value    => $CFDateValue,
-                        Timezone => 'utc'
-                    );
-                } else {
-                    $DateObj->Set( Format => 'ISO', Value => $CFDateValue );
-                }
-                $dateindex = LocalDate( $DateObj->Unix );
-            } else {
-                my $DateObj = $Date . "Obj";
-                $dateindex = LocalDate( $Ticket->$DateObj->Unix );
-            }
+            my $dateindex = _GetDate( $Date, $Ticket, $CurrentUser );
 
             push @{ $Tickets{$dateindex } },
                 $Ticket
@@ -110,8 +96,84 @@ sub FindTickets {
                 or $AlreadySeen{ $dateindex }
                 {$Ticket}++;
         }
+
+        # Find spanning days of multiple days events
+        for my $event (sort keys %$multiple_days_events) {
+            my $starts_field = $multiple_days_events->{$event}{'Starts'};
+            my $ends_field   = $multiple_days_events->{$event}{'Ends'};
+            my $starts_date  = _GetDate( $starts_field, $Ticket, $CurrentUser );
+            my $ends_date    = _GetDate( $ends_field,   $Ticket, $CurrentUser );
+
+            # Loop through all days between start and end and add the ticket
+            # to it
+            my $current_date = RT::Date->new($CurrentUser);
+            $current_date->Set(
+                Format => 'unknown',
+                Value => $starts_date,
+                Timezone => 'utc'
+            );
+            my $end_date_unix = RT::Date->new($CurrentUser);
+            $end_date_unix->Set(
+                Format => 'unknown',
+                Value => $ends_date,
+                Timezone => 'utc'
+            );
+            $end_date_unix = $end_date_unix->Unix;
+            while ( $current_date->Unix <= $end_date_unix )
+            {
+                my $dateindex = LocalDate( $current_date->Unix );
+
+                push @{ $TicketsSpanningDays{$dateindex} }, $Ticket->id
+                    unless $TicketsSpanningDaysAlreadySeen{$dateindex}
+                    {$Ticket}++;
+                push @{ $Tickets{$dateindex } },
+                    $Ticket
+                    # if reminder, check it's refering to a ticket
+                    unless ( $Ticket->Type eq 'reminder'
+                    and not $Ticket->RefersTo->First )
+                    or $AlreadySeen{ $dateindex }
+                    {$Ticket}++;
+
+                $current_date->AddDay();
+            }
+        }
+    }
+    if ( wantarray ) {
+        return ( \%Tickets, \%TicketsSpanningDays );
+    } else {
+        return \%Tickets;
+    }
+}
+
+sub _GetDate {
+    my $date_field = shift;
+    my $Ticket = shift;
+    my $CurrentUser = shift;
+
+    if ($date_field =~ /^CF\./){
+        my $cf = $date_field;
+        $cf =~ s/^CF\.\{(.*)\}/$1/;
+
+        my $CFDateValue = $Ticket->FirstCustomFieldValue($cf);
+        next unless $CFDateValue;
+        my $CustomFieldObj = RT::CustomField->new($CurrentUser);
+        $CustomFieldObj->LoadByName( Name => $cf );
+        my $CustomFieldObjType = $CustomFieldObj->Type;
+        my $DateObj            = RT::Date->new($CurrentUser);
+        if ( $CustomFieldObjType eq 'Date' ) {
+            $DateObj->Set(
+                Format   => 'unknown',
+                Value    => $CFDateValue,
+                Timezone => 'utc'
+            );
+        } else {
+            $DateObj->Set( Format => 'ISO', Value => $CFDateValue );
+        }
+        return LocalDate( $DateObj->Unix );
+    } else {
+        my $DateObj = $date_field . "Obj";
+        return LocalDate( $Ticket->$DateObj->Unix );
     }
-    return %Tickets;
 }
 
 #
@@ -355,6 +417,19 @@ C<$CalendarIcons> setting to your F<etc/RT_SiteConfig.pm>:
 
 The images should be placed on F<local/static/images>.
 
+=head3 Multiple days events
+
+You can define multiple days events by adding the C<%CalendarMultipleDaysEvents>
+setting to your F<etc/RT_SiteConfig.pm>:
+
+    Set( %CalendarMultipleDaysEvents, (
+            'Maintenance' => {
+                'Starts' => 'Starts',
+                'Ends'   => 'Due',
+            },
+        )
+    );
+
 =head1 USAGE
 
 A small help section is available in /Search/Calendar.html

-----------------------------------------------------------------------


hooks/post-receive
-- 
rtx-calendar


More information about the Bps-public-commit mailing list