Refactoring: list_objects() aus Controllern in ReportGenerator-Helfer verschieben
[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
93   my $column_defs = $params{report}->{columns};
94   my @columns     = $params{report}->get_visible_columns;
95
96   for my $obj (@{ $params{objects} || [] }) {
97     my %data = map {
98       my $def = $column_defs->{$_};
99       $_ => {
100         raw_data => $def->{raw_data} ? $def->{raw_data}->($obj) : '',
101         data     => $def->{sub}      ? $def->{sub}->($obj)
102                   : $obj->can($_)    ? $obj->$_
103                   :                    $obj->{$_},
104         link     => $def->{obj_link} ? $def->{obj_link}->($obj) : '',
105       },
106     } @columns;
107
108     $params{data_callback}->(\%data) if $params{data_callback};
109
110     $params{report}->add_data(\%data);
111   }
112
113   return $params{report}->generate_with_headers(%{ $params{options} || {}});
114 }
115
116 1;
117 __END__
118
119 =pod
120
121 =encoding utf8
122
123 =head1 NAME
124
125 SL::Controller::Helper::ReportGenerator - Mixin for controllers that
126 use the L<SL::ReportGenerator> class
127
128 =head1 SYNOPSIS
129
130   package SL::Controller::Unicorn;
131
132   use SL::Controller::Helper::ReportGenerator;
133
134   sub action_list {
135     my ($self) = @_;
136
137     # Set up the report generator instance. In this example this is
138     # hidden in "prepare_report".
139     my $report = $self->prepare_report;
140
141     # Get objects from database.
142     my $orders = SL::DB::Manager::Order->get_all(...);
143
144     # Let report generator create the output.
145     $self->report_generator_list_objects(
146       report  => $report,
147       objects => $orders,
148     );
149   }
150
151 =head1 FUNCTIONS
152
153 =over 4
154
155 =item C<action_report_generator_back>
156
157 This is the controller action that's called from the one of the report
158 generator's 'export options' pages when the user clicks on the 'back'
159 button.
160
161 It is never called from a controller manually and should just work
162 as-is.
163
164 =item C<action_report_generator_export_as_csv>
165
166 This is the controller action that's called from the generated report
167 when the user wants to export as CSV. First the CSV export options are
168 shown and afterwards the CSV file is generated and offered for
169 download.
170
171 It is never called from a controller manually and should just work
172 as-is.
173
174 =item C<action_report_generator_export_as_pdf>
175
176 This is the controller action that's called from the generated report
177 when the user wants to export as PDF. First the PDF export options are
178 shown and afterwards the PDF file is generated and offered for
179 download.
180
181 It is never called from a controller manually and should just work
182 as-is.
183
184 =item C<report_generator_do>
185
186 This is a common function that's called from
187 L<action_report_generator_back>,
188 L<action_report_generator_export_as_csv> and
189 L<action_report_generator_export_as_pdf>. It handles common options
190 and report generation after options have been set.
191
192 It is never called from a controller manually and should just work
193 as-is.
194
195 =item C<report_generator_list_objects %params>
196
197 Iterates over all objects, creates the actual rows of data, hands them
198 over to the report generator and lets the report generator create the
199 output.
200
201 C<%params> can contain the following values:
202
203 =over 2
204
205 =item C<report>
206
207 Mandatory. An instance of L<SL::ReportGenerator> that has been set up
208 already (column definitions, title, sort handling etc).
209
210 =item C<objects>
211
212 Mandatory. An array reference of RDBO models to output.
213
214 =item C<data_callback>
215
216 Optional. A callback handler (code reference) that gets called for
217 each row before it is passed to the report generator. The row passed
218 will be the handler's first and only argument (a hash reference). It's
219 the same hash reference that's passed to
220 L<SL::ReportGenrator/add_data>.
221
222 =item C<options>
223
224 An optional hash reference that's passed verbatim to the function
225 L<SL::ReportGenerator/generate_with_headers>.
226
227 =back
228
229 =back
230
231 =head1 BUGS
232
233 Nothing here yet.
234
235 =head1 AUTHOR
236
237 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
238
239 =cut