1 package SL::Controller::Helper::ReportGenerator;
6 use List::Util qw(max);
7 use Scalar::Util qw(blessed);
11 use SL::ReportGenerator;
13 use Exporter 'import';
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
20 sub _setup_action_bar {
21 my ($self, $type) = @_;
23 my $key = $::form->{CONTROLLER_DISPATCH} ? 'action' : 'report_generator_form.report_generator_dispatch_to';
24 my $value = $::form->{CONTROLLER_DISPATCH} ? $::form->{CONTROLLER_DISPATCH} . "/" : '';
26 for my $bar ($::request->layout->get('actionbar')) {
29 $type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
30 submit => [ '#report_generator_form', { $key => "${value}report_generator_export_as_${type}" } ],
33 $::locale->text('Back'),
34 submit => [ '#report_generator_form', { $key => "${value}report_generator_back" } ],
40 sub action_report_generator_export_as_pdf {
43 delete $::form->{action_report_generator_export_as_pdf};
45 if ($::form->{report_generator_pdf_options_set}) {
46 my $saved_form = save_form();
48 $self->report_generator_do('PDF');
50 if ($::form->{report_generator_printed}) {
51 restore_form($saved_form);
52 $::form->{MESSAGE} = $::locale->text('The list has been printed.');
53 $self->report_generator_do('HTML');
59 my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
61 $::form->get_lists('printers' => 'ALL_PRINTERS');
62 map { $_->{selected} = $::myconfig{default_printer_id} == $_->{id} } @{ $::form->{ALL_PRINTERS} };
64 $::form->{copies} = max $::myconfig{copies} * 1, 1;
65 $::form->{title} = $::locale->text('PDF export -- options');
67 _setup_action_bar($self, 'pdf'); # Sub not exported, therefore don't call via object.
70 print $::form->parse_html_template('report_generator/pdf_export_options', {
71 'HIDDEN' => \@form_values,
72 'ALLOW_FONT_SELECTION' => SL::ReportGenerator->check_for_pdf_api, });
75 sub action_report_generator_export_as_csv {
78 delete $::form->{action_report_generator_export_as_csv};
80 if ($::form->{report_generator_csv_options_set}) {
81 $self->report_generator_do('CSV');
85 my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
87 $::form->{title} = $::locale->text('CSV export -- options');
89 _setup_action_bar($self, 'csv'); # Sub not exported, therefore don't call via object.
92 print $::form->parse_html_template('report_generator/csv_export_options', { 'HIDDEN' => \@form_values });
95 sub action_report_generator_back {
96 $_[0]->report_generator_do('HTML');
99 sub report_generator_do {
100 my ($self, $format) = @_;
102 my $nextsub = $::form->{report_generator_nextsub};
104 $::form->error($::locale->text('report_generator_nextsub is not defined.'));
107 foreach my $key (split m/ +/, $::form->{report_generator_variable_list}) {
108 $::form->{$key} = $::form->{"report_generator_hidden_${key}"};
111 $::form->{report_generator_output_format} = $format;
113 delete @{$::form}{map { "report_generator_$_" } qw(nextsub variable_list)};
115 $self->_run_action($nextsub);
118 sub report_generator_list_objects {
119 my ($self, %params) = @_;
121 croak "Parameter 'objects' must exist and be an array reference" if ref($params{objects}) ne 'ARRAY';
122 croak "Parameter 'report' must exist and be an instance of SL::ReportGenerator" if ref($params{report}) ne 'SL::ReportGenerator';
123 croak "Parameter 'options', if exists, must be a hash reference" if $params{options} && (ref($params{options}) ne 'HASH');
124 $params{layout} //= 1;
126 my $column_defs = $params{report}->{columns};
127 my @columns = $params{report}->get_visible_columns('HTML');
129 for my $obj (@{ $params{objects} || [] }) {
132 if (blessed($obj) && $obj->isa('SL::Controller::Helper::ReportGenerator::ControlRow::Base')) {
133 $obj->set_data($params{report});
138 my $def = $column_defs->{$_};
140 $tmp->{raw_data} = $def->{raw_data} ? $def->{raw_data}->($obj) : '';
141 $tmp->{data} = $def->{sub} ? $def->{sub}->($obj)
142 : $obj->can($_) ? $obj->$_
144 $tmp->{link} = $def->{obj_link} ? $def->{obj_link}->($obj) : '';
149 $params{data_callback}->(\%data) if $params{data_callback};
151 $params{report}->add_data(\%data);
154 my %options = %{ $params{options} || {} };
155 $options{action_bar} //= $params{action_bar} // 1;
157 if ($params{layout}) {
158 return $params{report}->generate_with_headers(%options);
160 my $html = $params{report}->generate_html_content(action_bar => 0, %options);
161 $self->render(\$html , { layout => 0, process => 0 });
174 SL::Controller::Helper::ReportGenerator - Mixin for controllers that
175 use the L<SL::ReportGenerator> class
179 package SL::Controller::Unicorn;
181 use SL::Controller::Helper::ReportGenerator;
186 # Set up the report generator instance. In this example this is
187 # hidden in "prepare_report".
188 my $report = $self->prepare_report;
190 # Get objects from database.
191 my $orders = SL::DB::Manager::Order->get_all(...);
193 # Let report generator create the output.
194 $self->report_generator_list_objects(
204 =item C<action_report_generator_back>
206 This is the controller action that's called from the one of the report
207 generator's 'export options' pages when the user clicks on the 'back'
210 It is never called from a controller manually and should just work
213 =item C<action_report_generator_export_as_csv>
215 This is the controller action that's called from the generated report
216 when the user wants to export as CSV. First the CSV export options are
217 shown and afterwards the CSV file is generated and offered for
220 It is never called from a controller manually and should just work
223 =item C<action_report_generator_export_as_pdf>
225 This is the controller action that's called from the generated report
226 when the user wants to export as PDF. First the PDF export options are
227 shown and afterwards the PDF file is generated and offered for
230 It is never called from a controller manually and should just work
233 =item C<report_generator_do>
235 This is a common function that's called from
236 L<action_report_generator_back>,
237 L<action_report_generator_export_as_csv> and
238 L<action_report_generator_export_as_pdf>. It handles common options
239 and report generation after options have been set.
241 It is never called from a controller manually and should just work
244 =item C<report_generator_list_objects %params>
246 Iterates over all objects, creates the actual rows of data, hands them
247 over to the report generator and lets the report generator create the
250 C<%params> can contain the following values:
256 Mandatory. An instance of L<SL::ReportGenerator> that has been set up
257 already (column definitions, title, sort handling etc).
261 Mandatory. An array reference of RDBO models to output.
263 An element of the array can also be an instance of a control row, i.e.
264 an instance of a class derived from
265 C<SL::Controller::Helper::ReportGenerator::ControlRow::Base>.
268 L<SL::Controller::Helper::ReportGenerator::ControlRow>
269 L<SL::Controller::Helper::ReportGenerator::ControlRow::*>
271 =item C<data_callback>
273 Optional. A callback handler (code reference) that gets called for
274 each row before it is passed to the report generator. The row passed
275 will be the handler's first and only argument (a hash reference). It's
276 the same hash reference that's passed to
277 L<SL::ReportGenrator/add_data>.
281 An optional hash reference that's passed verbatim to the function
282 L<SL::ReportGenerator/generate_with_headers>.
286 If the buttons for exporting PDF and/or CSV variants are included in
287 the action bar. Otherwise they're rendered at the bottom of the page.
289 The value can be either a specific action bar instance or simply 1 in
290 which case the default action bar is used:
291 C<$::request-E<gt>layout-E<gt>get('actionbar')>.
303 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>