1package RTx::Calendar; 2 3use strict; 4use DateTime; 5use DateTime::Set; 6 7our $VERSION = "1.03"; 8 9RT->AddStyleSheets('calendar.css'); 10 11sub FirstDay { 12 my ($year, $month, $matchday) = @_; 13 my $set = DateTime::Set->from_recurrence( 14 next => sub { $_[0]->truncate( to => 'day' )->subtract( days => 1 ) } 15 ); 16 17 my $day = DateTime->new( year => $year, month => $month ); 18 19 $day = $set->next($day) while $day->day_of_week != $matchday; 20 $day; 21 22} 23 24sub LastDay { 25 my ($year, $month, $matchday) = @_; 26 my $set = DateTime::Set->from_recurrence( 27 next => sub { $_[0]->truncate( to => 'day' )->add( days => 1 ) } 28 ); 29 30 my $day = DateTime->last_day_of_month( year => $year, month => $month ); 31 32 $day = $set->next($day) while $day->day_of_week != $matchday; 33 $day; 34} 35 36# we can't use RT::Date::Date because it uses gmtime 37# and we need localtime 38sub LocalDate { 39 my $ts = shift; 40 my ($d,$m,$y) = (localtime($ts))[3..5]; 41 sprintf "%4d-%02d-%02d", ($y + 1900), ++$m, $d; 42} 43 44sub DatesClauses { 45 my ($Dates, $begin, $end) = @_; 46 47 my $clauses = ""; 48 49 my @DateClauses = map { 50 "($_ >= '" . $begin . " 00:00:00' AND $_ <= '" . $end . " 23:59:59')" 51 } @$Dates; 52 $clauses .= " AND " . " ( " . join(" OR ", @DateClauses) . " ) " 53 if @DateClauses; 54 55 return $clauses 56} 57 58sub FindTickets { 59 my ($CurrentUser, $Query, $Dates, $begin, $end) = @_; 60 61 $Query .= DatesClauses($Dates, $begin, $end) 62 if $begin and $end; 63 64 my $Tickets = RT::Tickets->new($CurrentUser); 65 $Tickets->FromSQL($Query); 66 67 my %Tickets; 68 my %AlreadySeen; 69 70 while ( my $Ticket = $Tickets->Next()) { 71 72 # How to find the LastContacted date ? 73 for my $Date (@$Dates) { 74 my $DateObj = $Date . "Obj"; 75 push @{ $Tickets{ LocalDate($Ticket->$DateObj->Unix) } }, $Ticket 76 # if reminder, check it's refering to a ticket 77 unless ($Ticket->Type eq 'reminder' and not $Ticket->RefersTo->First) 78 or $AlreadySeen{ LocalDate($Ticket->$DateObj->Unix) }{ $Ticket }++; 79 } 80 } 81 return %Tickets; 82} 83 84# 85# Take a user object and return the search with Description "calendar" if it exists 86# 87sub SearchDefaultCalendar { 88 my $CurrentUser = shift; 89 my $Description = "calendar"; 90 91 # I'm quite sure the loop isn't usefull but... 92 my @Objects = $CurrentUser->UserObj; 93 for my $object (@Objects) { 94 next unless ref($object) eq 'RT::User' && $object->id == $CurrentUser->Id; 95 my @searches = $object->Attributes->Named('SavedSearch'); 96 for my $search (@searches) { 97 next if ($search->SubValue('SearchType') 98 && $search->SubValue('SearchType') ne 'Ticket'); 99 100 return $search 101 if "calendar" eq $search->Description; 102 } 103 } 104} 105 1061; 107 108__END__ 109 110=head1 NAME 111 112RTx::Calendar - Calendar for RT due dates 113 114=head1 DESCRIPTION 115 116This RT extension provides a calendar view for your tickets and your 117reminders so you see when is your next due ticket. You can find it in 118ticket search sub navigation menu. 119 120Date fields in the search results are displayed/used in the calendar, 121for example if you have a ticket with a due date, it won't be displayed on 122that date unless the Due field is included in the search result format. 123 124There's a portlet to put on your home page (see Prefs/MyRT.html), see the 125CONFIGURATION section below for details on adding it. 126 127=head1 RT VERSION 128 129Works with RT 4.2, 4.4, 5.0 130 131=head1 INSTALLATION 132 133=over 134 135=item C<perl Makefile.PL> 136 137=item C<make> 138 139=item C<make install> 140 141May need root permissions 142 143=item patch RT 144 145Apply for versions prior to 4.4.2: 146 147 patch -p1 -d /path/to/rt < etc/tabs_privileged_callback.patch 148 149=item Edit your F</opt/rt5/etc/RT_SiteConfig.pm> 150 151Add this line: 152 153 Plugin('RTx::Calendar'); 154 155=item Clear your mason cache 156 157 rm -rf /opt/rt5/var/mason_data/obj 158 159=item Restart your webserver 160 161=back 162 163=head1 CONFIGURATION 164 165=head2 Base configuration 166 167To use the C<MyCalendar> portlet, you must add C<MyCalendar> to 168C<$HomepageComponents> in F<etc/RT_SiteConfig.pm>: 169 170 Set($HomepageComponents, [qw(QuickCreate Quicksearch MyCalendar 171 MyAdminQueues MySupportQueues MyReminders RefreshHomepage)]); 172 173=head2 Display configuration 174 175You can show the owner in each day box by adding this line to your 176F<etc/RT_SiteConfig.pm>: 177 178 Set($CalendarDisplayOwner, 1); 179 180You can change which fields show up in the popup display when you 181mouse over a date in F<etc/RT_SiteConfig.pm>: 182 183 Set(@CalendarPopupFields, ('Status', 'OwnerObj->Name', 'DueObj->ISO')); 184 185=head1 USAGE 186 187A small help section is available in /Search/Calendar.html 188 189=head1 AUTHOR 190 191Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt> 192 193Originally written by Nicolas Chuche E<lt>nchuche@barna.beE<gt> 194 195=head1 BUGS 196 197All bugs should be reported via email to 198 199 L<bug-RTx-Calendar@rt.cpan.org|mailto:bug-RTx-Calendar@rt.cpan.org> 200 201or via the web at 202 203 L<rt.cpan.org|http://rt.cpan.org/Public/Dist/Display.html?Name=RTx-Calendar>. 204 205=head1 LICENSE AND COPYRIGHT 206 207This software is Copyright (c) 2010-2020 by Best Practical Solutions 208 209Copyright 2007-2009 by Nicolas Chuche 210 211This is free software, licensed under: 212 213 The GNU General Public License, Version 2, June 1991 214 215=cut 216