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