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