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