Initial release
[manu/RT-Extension-SearchResults-ODS.git] / html / Search / Results.ods
1 %# BEGIN BPS TAGGED BLOCK {{{
2 %# 
3 %# COPYRIGHT:
4 %# 
5 %# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
6 %#                                          <jesse@bestpractical.com>
7 %# 
8 %# (Except where explicitly superseded by other copyright notices)
9 %# 
10 %# 
11 %# LICENSE:
12 %# 
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
16 %# from www.gnu.org.
17 %# 
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 %# General Public License for more details.
22 %# 
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 %# 02110-1301 or visit their web page on the internet at
27 %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 %# 
29 %# 
30 %# CONTRIBUTION SUBMISSION POLICY:
31 %# 
32 %# (The following paragraph is not intended to limit the rights granted
33 %# to you to modify and distribute this software under the terms of
34 %# the GNU General Public License and is only of importance to you if
35 %# you choose to contribute your changes and enhancements to the
36 %# community by submitting them to Best Practical Solutions, LLC.)
37 %# 
38 %# By intentionally submitting any modifications, corrections or
39 %# derivatives to this work, or any other work intended for use with
40 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 %# you are the copyright holder for those contributions and you grant
42 %# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 %# royalty-free, perpetual, license to use, copy, create derivative
44 %# works based on those contributions, and sublicense and distribute
45 %# those contributions and any derivatives thereof.
46 %# 
47 %# END BPS TAGGED BLOCK }}}
48 <%ARGS>
49 $OrderBy => 'id'
50 $Order => 'ASC'
51 </%ARGS>
52 <%INIT>
53
54 use OpenOffice::OODoc;
55 my $tmpdir;
56 if ( -w $RT::VarPath ) {
57     $tmpdir = File::Temp::tempdir( DIR => $RT::VarPath, CLEANUP => 1 );
58 } elsif (-w File::Spec->tmpdir) {
59     $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
60 } else {
61     $RT::Logger->crit("Neither the RT var directory ($RT::VarPath) nor the system tmpdir (@{[File::Spec->tmpdir]}) are writable!");
62 }
63 my $tmpfile = File::Spec->catfile( $tmpdir, 'Results.ods' );
64 odfWorkingDirectory($tmpdir);
65 my $workbook = odfDocument(file => $tmpfile, create => 'spreadsheet') or die $!;
66
67 my $Tickets = RT::Tickets->new( $session{'CurrentUser'} );
68 $Tickets->FromSQL( $ARGS{'Query'} );
69 if ( $OrderBy =~ /\|/ ) {
70
71   # Multiple Sorts
72   my @OrderBy = split /\|/, $OrderBy;
73   my @Order   = split /\|/, $Order;
74   $Tickets->OrderByCols(
75     map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } }
76       ( 0 .. $#OrderBy ) );
77 }
78 else {
79   $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order );
80 }
81
82 my @rows;
83 my %known_cfs;
84
85 my @attrs = qw( id QueueObj->Name Subject Status TimeEstimated TimeWorked TimeLeft Priority FinalPriority OwnerObj->Name 
86                 Requestors->MemberEmailAddressesAsString Cc->MemberEmailAddressesAsString AdminCc->MemberEmailAddressesAsString
87                 DueObj->ISO ToldObj->ISO CreatedObj->ISO ResolvedObj->ISO LastUpdatedObj->ISO);
88
89 $r->content_type('application/vnd.oasis.opendocument.spreadsheet');
90 while ( my $Ticket = $Tickets->Next()) {
91     my $row;
92     foreach my $attr (@attrs) {
93         if ($attr =~ /(.*)->ISO$/ and $Ticket->$1->Unix <= 0) {
94             $row->{$attr} = "";
95         } else {
96             my $method = '$Ticket->'.$attr.'()';
97             $method =~ s/->ISO\(\)$/->ISO( Timezone => 'user' )/;
98             $row->{$attr} = eval $method;
99             if ($@) {die "Failed to find $attr - ". $@}; 
100         }
101     }
102
103     my $cfs = $Ticket->QueueObj->TicketCustomFields();
104     while (my $cf = $cfs->Next) {
105         $known_cfs{$cf->Id} = $cf->Name;
106         my @content;
107         my $values = $Ticket->CustomFieldValues($cf->Id);
108         while (my $value = $values->Next) {
109             push @content, $value->Content;
110         }
111         $row->{'CustomField-'.$cf->Id} = join(', ',@content);
112     }
113     push @rows, $row;
114 }
115
116 my $rows_count = scalar(@rows) + 1;
117 my $cols_count = scalar(@attrs) + scalar( keys %known_cfs );
118
119 $workbook->expandTable(0, $rows_count, $cols_count );
120
121 sub int_to_alpha {
122     my $int = shift;
123     $int++;
124
125     my $dividend = $int;
126     my $alpha = '';
127     my $modulo;
128
129     while ($dividend > 0 ) {
130         $modulo = ($dividend - 1) % 26;
131         $alpha = chr(65 + $modulo).$alpha;
132         $dividend = int(($dividend - $modulo) / 26);
133     }
134
135     return $alpha;
136 }
137
138
139 my $xml = '<table:database-ranges><table:database-range table:name="AllRTTickets" table:target-range-address="Sheet1.A1:Sheet1.'.int_to_alpha($cols_count - 1).$rows_count.'"/></table:database-ranges>';
140 my $xmlpos = $workbook->getElement('//table:table', 0);
141 $workbook->insertElement ( $xmlpos, $xml, position => 'after'); 
142
143
144     my @header;
145     my $ws_col = 0;
146     foreach my $attr (@attrs) {
147         my $label = $attr;
148         $label =~ s'Obj-.(?:AsString|Name|ISO)''g;
149         $label =~ s'-\>MemberEmailAddressesAsString''g;
150         Encode::_utf8_off($label);
151         $workbook->updateCell(0, 0, $ws_col, $label);
152         $ws_col++;
153     }
154     foreach my $id (sort keys %known_cfs) {
155         Encode::_utf8_off($known_cfs{$id});
156         $workbook->updateCell(0, 0, $ws_col, "CF-".$known_cfs{$id});
157         $ws_col++;
158     }
159 }
160
161 my $ws_row = 1;
162 foreach my $row (@rows) {
163     my $ws_col = 0;
164     my @row;
165     foreach my $attr(@attrs) {
166         Encode::_utf8_off($row->{"$attr"});
167         $workbook->updateCell(0, $ws_row, $ws_col, $row->{"$attr"});
168         $ws_col++;
169     }
170     foreach my $id (sort keys %known_cfs) {
171         my $val = $row->{'CustomField-'.$id};
172         #$val =~ s/(\n|\r)//g;
173         Encode::_utf8_off($val);
174         $workbook->updateCell(0, $ws_row, $ws_col, $val);
175         $ws_col++;
176     }
177     $ws_row++;
178 }
179 $workbook->save();
180 open (ODT, $tmpfile);
181 while (<ODT>) {
182     $m->print($_);
183 }
184 close (ODT);
185 unlink ($tmpfile);
186 $m->abort();
187 </%INIT>
188