ActionBar: ReportGenerator nutzt per Default nun die ActionBar
[kivitendo-erp.git] / SL / Controller / Helper / ReportGenerator.pm
1 package SL::Controller::Helper::ReportGenerator;
2
3 use strict;
4
5 use Carp;
6 use List::Util qw(max);
7
8 use SL::Common;
9 use SL::MoreCommon;
10 use SL::ReportGenerator;
11
12 use Exporter 'import';
13 our @EXPORT = qw(
14   action_report_generator_export_as_pdf action_report_generator_export_as_csv
15   action_report_generator_back report_generator_do
16   report_generator_list_objects
17 );
18
19 sub _setup_action_bar {
20   my ($self, $type) = @_;
21
22   my $key   = $::form->{CONTROLLER_DISPATCH} ? 'action'                             : 'report_generator_form.report_generator_dispatch_to';
23   my $value = $::form->{CONTROLLER_DISPATCH} ? $::form->{CONTROLLER_DISPATCH} . "/" : '';
24
25   $::request->layout->get('actionbar')->add(
26     action => [
27       $type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
28       submit => [ '#report_generator_form', { $key => "${value}report_generator_export_as_${type}" } ],
29     ],
30     action => [
31       $::locale->text('Back'),
32       submit => [ '#report_generator_form', { $key => "${value}report_generator_back" } ],
33     ],
34   );
35 }
36
37 sub action_report_generator_export_as_pdf {
38   my ($self) = @_;
39
40   delete $::form->{action_report_generator_export_as_pdf};
41
42   if ($::form->{report_generator_pdf_options_set}) {
43     my $saved_form = save_form();
44
45     $self->report_generator_do('PDF');
46
47     if ($::form->{report_generator_printed}) {
48       restore_form($saved_form);
49       $::form->{MESSAGE} = $::locale->text('The list has been printed.');
50       $self->report_generator_do('HTML');
51     }
52
53     return;
54   }
55
56   my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
57
58   $::form->get_lists('printers' => 'ALL_PRINTERS');
59   map { $_->{selected} = $::myconfig{default_printer_id} == $_->{id} } @{ $::form->{ALL_PRINTERS} };
60
61   $::form->{copies} = max $::myconfig{copies} * 1, 1;
62   $::form->{title} = $::locale->text('PDF export -- options');
63
64   _setup_action_bar($self, 'pdf'); # Sub not exported, therefore don't call via object.
65
66   $::form->header;
67   print $::form->parse_html_template('report_generator/pdf_export_options', {
68     'HIDDEN'               => \@form_values,
69     'ALLOW_FONT_SELECTION' => SL::ReportGenerator->check_for_pdf_api, });
70 }
71
72 sub action_report_generator_export_as_csv {
73   my ($self) = @_;
74
75   delete $::form->{action_report_generator_export_as_csv};
76
77   if ($::form->{report_generator_csv_options_set}) {
78     $self->report_generator_do('CSV');
79     return;
80   }
81
82   my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
83
84   $::form->{title} = $::locale->text('CSV export -- options');
85
86   _setup_action_bar($self, 'csv'); # Sub not exported, therefore don't call via object.
87
88   $::form->header;
89   print $::form->parse_html_template('report_generator/csv_export_options', { 'HIDDEN' => \@form_values });
90 }
91
92 sub action_report_generator_back {
93   $_[0]->report_generator_do('HTML');
94 }
95
96 sub report_generator_do {
97   my ($self, $format)  = @_;
98
99   my $nextsub = $::form->{report_generator_nextsub};
100   if (!$nextsub) {
101     $::form->error($::locale->text('report_generator_nextsub is not defined.'));
102   }
103
104   foreach my $key (split m/ +/, $::form->{report_generator_variable_list}) {
105     $::form->{$key} = $::form->{"report_generator_hidden_${key}"};
106   }
107
108   $::form->{report_generator_output_format} = $format;
109
110   delete @{$::form}{map { "report_generator_$_" } qw(nextsub variable_list)};
111
112   $self->_run_action($nextsub);
113 }
114
115 sub report_generator_list_objects {
116   my ($self, %params) = @_;
117
118   croak "Parameter 'objects' must exist and be an array reference"                if                      ref($params{objects}) ne 'ARRAY';
119   croak "Parameter 'report' must exist and be an instance of SL::ReportGenerator" if                      ref($params{report})  ne 'SL::ReportGenerator';
120   croak "Parameter 'options', if exists, must be a hash reference"                if $params{options} && (ref($params{options}) ne 'HASH');
121   $params{layout} //= 1;
122
123   my $column_defs = $params{report}->{columns};
124   my @columns     = $params{report}->get_visible_columns('HTML');
125
126   for my $obj (@{ $params{objects} || [] }) {
127     my %data = map {
128       my $def = $column_defs->{$_};
129       $_ => {
130         raw_data => $def->{raw_data} ? $def->{raw_data}->($obj) : '',
131         data     => $def->{sub}      ? $def->{sub}->($obj)
132                   : $obj->can($_)    ? $obj->$_
133                   :                    $obj->{$_},
134         link     => $def->{obj_link} ? $def->{obj_link}->($obj) : '',
135       },
136     } @columns;
137
138     $params{data_callback}->(\%data) if $params{data_callback};
139
140     $params{report}->add_data(\%data);
141   }
142
143   my %options            = %{ $params{options} || {} };
144   $options{action_bar} //= $params{action_bar} // 1;
145
146   if ($params{layout}) {
147     return $params{report}->generate_with_headers(%options);
148   } else {
149     my $html = $params{report}->generate_html_content(action_bar => 0, %options);
150     $self->render(\$html , { layout => 0, process => 0 });
151   }
152 }
153
154 1;
155 __END__
156
157 =pod
158
159 =encoding utf8
160
161 =head1 NAME
162
163 SL::Controller::Helper::ReportGenerator - Mixin for controllers that
164 use the L<SL::ReportGenerator> class
165
166 =head1 SYNOPSIS
167
168   package SL::Controller::Unicorn;
169
170   use SL::Controller::Helper::ReportGenerator;
171
172   sub action_list {
173     my ($self) = @_;
174
175     # Set up the report generator instance. In this example this is
176     # hidden in "prepare_report".
177     my $report = $self->prepare_report;
178
179     # Get objects from database.
180     my $orders = SL::DB::Manager::Order->get_all(...);
181
182     # Let report generator create the output.
183     $self->report_generator_list_objects(
184       report  => $report,
185       objects => $orders,
186     );
187   }
188
189 =head1 FUNCTIONS
190
191 =over 4
192
193 =item C<action_report_generator_back>
194
195 This is the controller action that's called from the one of the report
196 generator's 'export options' pages when the user clicks on the 'back'
197 button.
198
199 It is never called from a controller manually and should just work
200 as-is.
201
202 =item C<action_report_generator_export_as_csv>
203
204 This is the controller action that's called from the generated report
205 when the user wants to export as CSV. First the CSV export options are
206 shown and afterwards the CSV file is generated and offered for
207 download.
208
209 It is never called from a controller manually and should just work
210 as-is.
211
212 =item C<action_report_generator_export_as_pdf>
213
214 This is the controller action that's called from the generated report
215 when the user wants to export as PDF. First the PDF export options are
216 shown and afterwards the PDF file is generated and offered for
217 download.
218
219 It is never called from a controller manually and should just work
220 as-is.
221
222 =item C<report_generator_do>
223
224 This is a common function that's called from
225 L<action_report_generator_back>,
226 L<action_report_generator_export_as_csv> and
227 L<action_report_generator_export_as_pdf>. It handles common options
228 and report generation after options have been set.
229
230 It is never called from a controller manually and should just work
231 as-is.
232
233 =item C<report_generator_list_objects %params>
234
235 Iterates over all objects, creates the actual rows of data, hands them
236 over to the report generator and lets the report generator create the
237 output.
238
239 C<%params> can contain the following values:
240
241 =over 2
242
243 =item C<report>
244
245 Mandatory. An instance of L<SL::ReportGenerator> that has been set up
246 already (column definitions, title, sort handling etc).
247
248 =item C<objects>
249
250 Mandatory. An array reference of RDBO models to output.
251
252 =item C<data_callback>
253
254 Optional. A callback handler (code reference) that gets called for
255 each row before it is passed to the report generator. The row passed
256 will be the handler's first and only argument (a hash reference). It's
257 the same hash reference that's passed to
258 L<SL::ReportGenrator/add_data>.
259
260 =item C<options>
261
262 An optional hash reference that's passed verbatim to the function
263 L<SL::ReportGenerator/generate_with_headers>.
264
265 =item C<action_bar>
266
267 If the buttons for exporting PDF and/or CSV variants are included in
268 the action bar. Otherwise they're rendered at the bottom of the page.
269
270 The value can be either a specific action bar instance or simply 1 in
271 which case the default action bar is used:
272 C<$::request-E<gt>layout-E<gt>get('actionbar')>.
273
274 =back
275
276 =back
277
278 =head1 BUGS
279
280 Nothing here yet.
281
282 =head1 AUTHOR
283
284 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
285
286 =cut