4 use base qw( Exporter );
10 our @EXPORT_OK = qw( FirstDay LastDay );
13 my ($year, $month, $matchday) = @_;
14 my $set = DateTime::Set->from_recurrence(
15 next => sub { $_[0]->truncate( to => 'day' )->subtract( days => 1 ) }
18 my $day = DateTime->new( year => $year, month => $month );
20 $day = $set->next($day) while $day->day_of_week != $matchday;
26 my ($year, $month, $matchday) = @_;
27 my $set = DateTime::Set->from_recurrence(
28 next => sub { $_[0]->truncate( to => 'day' )->add( days => 1 ) }
31 my $day = DateTime->last_day_of_month( year => $year, month => $month );
33 $day = $set->next($day) while $day->day_of_week != $matchday;
37 # we can't use RT::Date::Date because it uses gmtime
38 # and we need localtime
41 my ($d,$m,$y) = (localtime($ts))[3..5];
42 sprintf "%4d-%02d-%02d", ($y + 1900), ++$m, $d;
46 my ($Dates, $begin, $end) = @_;
50 my @DateClauses = map {
51 "($_ >= '" . $begin . "' AND $_ <= '" . $end . "')"
53 $clauses .= " AND " . " ( " . join(" OR ", @DateClauses) . " ) "
60 my ($CurrentUser, $Query, $Dates, $begin, $end) = @_;
62 $Query .= DatesClauses($Dates, $begin, $end)
65 my $Tickets = RT::Tickets->new($CurrentUser);
66 $Tickets->FromSQL($Query);
71 while ( my $Ticket = $Tickets->Next()) {
73 # How to find the LastContacted date ?
74 for my $Date (@$Dates) {
75 my $DateObj = $Date . "Obj";
76 push @{ $Tickets{ LocalDate($Ticket->$DateObj->Unix) } }, $Ticket
77 # if reminder, check it's refering to a ticket
78 unless ($Ticket->Type eq 'reminder' and not $Ticket->RefersTo->First)
79 or $AlreadySeen{ LocalDate($Ticket->$DateObj->Unix) }{ $Ticket }++;
86 # Take a user object and return the search with Description "calendar" if it exists
88 sub SearchDefaultCalendar {
89 my $CurrentUser = shift;
90 my $Description = "calendar";
92 # I'm quite sure the loop isn't usefull but...
93 my @Objects = $CurrentUser->UserObj;
94 for my $object (@Objects) {
95 next unless ref($object) eq 'RT::User' && $object->id == $CurrentUser->Id;
96 my @searches = $object->Attributes->Named('SavedSearch');
97 for my $search (@searches) {
98 next if ($search->SubValue('SearchType')
99 && $search->SubValue('SearchType') ne 'Ticket');
102 if "calendar" eq $search->Description;
114 RTx::Calendar - Calendar for RT due tasks
118 This document describes version 0.07 of RTx::Calendar
122 This RT extension provides a calendar view for your tickets and your
123 reminders so you see when is your next due ticket. You can find it in
124 the menu Search->Calendar.
126 There's a portlet to put on your home page (see Prefs/MyRT.html)
128 You can also enable ics (ICal) feeds for your default calendar and all
129 your private searches in Prefs/Calendar.html. Authentication is magic
130 number based so that you can give those feeds to other people.
132 You can find screenshots on
133 http://gaspard.mine.nu/dotclear/index.php?tag/rtx-calendar
137 If you upgrade from 0.02, see next part before.
139 You need to install those three modules :
145 Install it like a standard perl module
151 If your RT is not in the default path (/opt/rt3) you must set RTHOME
152 before doing the Makefile.PL
156 =head2 Base configuration
158 In RT 3.8 and later, to enable calendar plugin, you must add something
159 like that in your etc/RT_SiteConfig.pm :
161 Set(@Plugins,(qw(RTx::Calendar)));
163 To use MyCalendar portlet you must add MyCalendar to
164 $HomepageComponents in etc/RT_SiteConfig.pm like that :
166 Set($HomepageComponents, [qw(QuickCreate Quicksearch MyCalendar
167 MyAdminQueues MySupportQueues MyReminders RefreshHomepage)]);
169 To enable private searches ICal feeds, you need to give
170 CreateSavedSearch and LoadSavedSearch rights to your users.
172 =head2 Display configuration
174 You can show the owner in each day box by adding this line to your
175 etc/RT_SiteConfig.pm :
177 Set($CalendarDisplayOwner, 1);
179 You can change which fields show up in the popup display when you
180 mouse over a date in etc/RT_SiteConfig.pm :
182 @CalendarPopupFields = ('Status', 'OwnerObj->Name', 'DueObj->ISO');
184 =head2 ICAL feed configuration
186 By default, tickets are todo and reminders event. You can change this
187 by setting $RT::ICalTicketType and $RT::ICalReminderType in etc/RT_SiteConfig.pm :
189 Set($ICalTicketType, "Data::ICal::Entry::Event");
190 Set($ICalReminderType ,"Data::ICal::Entry::Todo");
194 A small help section is available in /Prefs/Calendar.html
196 =head1 UPGRADE FROM 0.02
198 As I've change directory structure, if you upgrade from 0.02 you need
199 to delete old files manually. Go in RTHOME/share/html (by default
200 /opt/rt3/share/html) and delete those files :
202 rm -rf Callbacks/RTx-Calendar
203 rm Tools/Calendar.html
205 RTx-Calendar may work without this but it's not very clean.
212 compatible only with RT 3.6 for the moment. If someone need
213 compatibility with 3.4 I can work on this. And I will work on 3.7
220 Nicolas Chuche E<lt>nchuche@barna.beE<gt>
222 Idea borrowed from redmine's calendar (Thanks Jean-Philippe).
226 Copyright 2007 by Nicolas Chuche E<lt>nchuche@barna.beE<gt>
228 This program is free software; you can redistribute it and/or
229 modify it under the same terms as Perl itself.
231 See L<http://www.perl.com/perl/misc/Artistic.html>