1 package SL::Controller::Helper::ReportGenerator;
6 use List::Util qw(max);
10 use SL::ReportGenerator;
12 use Exporter 'import';
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
19 sub _setup_action_bar {
20 my ($self, $type) = @_;
22 my $key = $::form->{CONTROLLER_DISPATCH} ? 'action' : 'report_generator_form.report_generator_dispatch_to';
23 my $value = $::form->{CONTROLLER_DISPATCH} ? $::form->{CONTROLLER_DISPATCH} . "/" : '';
25 for my $bar ($::request->layout->get('actionbar')) {
28 $type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
29 submit => [ '#report_generator_form', { $key => "${value}report_generator_export_as_${type}" } ],
32 $::locale->text('Back'),
33 submit => [ '#report_generator_form', { $key => "${value}report_generator_back" } ],
39 sub action_report_generator_export_as_pdf {
42 delete $::form->{action_report_generator_export_as_pdf};
44 if ($::form->{report_generator_pdf_options_set}) {
45 my $saved_form = save_form();
47 $self->report_generator_do('PDF');
49 if ($::form->{report_generator_printed}) {
50 restore_form($saved_form);
51 $::form->{MESSAGE} = $::locale->text('The list has been printed.');
52 $self->report_generator_do('HTML');
58 my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
60 $::form->get_lists('printers' => 'ALL_PRINTERS');
61 map { $_->{selected} = $::myconfig{default_printer_id} == $_->{id} } @{ $::form->{ALL_PRINTERS} };
63 $::form->{copies} = max $::myconfig{copies} * 1, 1;
64 $::form->{title} = $::locale->text('PDF export -- options');
66 _setup_action_bar($self, 'pdf'); # Sub not exported, therefore don't call via object.
69 print $::form->parse_html_template('report_generator/pdf_export_options', {
70 'HIDDEN' => \@form_values,
71 'ALLOW_FONT_SELECTION' => SL::ReportGenerator->check_for_pdf_api, });
74 sub action_report_generator_export_as_csv {
77 delete $::form->{action_report_generator_export_as_csv};
79 if ($::form->{report_generator_csv_options_set}) {
80 $self->report_generator_do('CSV');
84 my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
86 $::form->{title} = $::locale->text('CSV export -- options');
88 _setup_action_bar($self, 'csv'); # Sub not exported, therefore don't call via object.
91 print $::form->parse_html_template('report_generator/csv_export_options', { 'HIDDEN' => \@form_values });
94 sub action_report_generator_back {
95 $_[0]->report_generator_do('HTML');
98 sub report_generator_do {
99 my ($self, $format) = @_;
101 my $nextsub = $::form->{report_generator_nextsub};
103 $::form->error($::locale->text('report_generator_nextsub is not defined.'));
106 foreach my $key (split m/ +/, $::form->{report_generator_variable_list}) {
107 $::form->{$key} = $::form->{"report_generator_hidden_${key}"};
110 $::form->{report_generator_output_format} = $format;
112 delete @{$::form}{map { "report_generator_$_" } qw(nextsub variable_list)};
114 $self->_run_action($nextsub);
117 sub report_generator_list_objects {
118 my ($self, %params) = @_;
120 croak "Parameter 'objects' must exist and be an array reference" if ref($params{objects}) ne 'ARRAY';
121 croak "Parameter 'report' must exist and be an instance of SL::ReportGenerator" if ref($params{report}) ne 'SL::ReportGenerator';
122 croak "Parameter 'options', if exists, must be a hash reference" if $params{options} && (ref($params{options}) ne 'HASH');
123 $params{layout} //= 1;
125 my $column_defs = $params{report}->{columns};
126 my @columns = $params{report}->get_visible_columns('HTML');
128 for my $obj (@{ $params{objects} || [] }) {
130 my $def = $column_defs->{$_};
132 raw_data => $def->{raw_data} ? $def->{raw_data}->($obj) : '',
133 data => $def->{sub} ? $def->{sub}->($obj)
134 : $obj->can($_) ? $obj->$_
136 link => $def->{obj_link} ? $def->{obj_link}->($obj) : '',
140 $params{data_callback}->(\%data) if $params{data_callback};
142 $params{report}->add_data(\%data);
145 my %options = %{ $params{options} || {} };
146 $options{action_bar} //= $params{action_bar} // 1;
148 if ($params{layout}) {
149 return $params{report}->generate_with_headers(%options);
151 my $html = $params{report}->generate_html_content(action_bar => 0, %options);
152 $self->render(\$html , { layout => 0, process => 0 });
165 SL::Controller::Helper::ReportGenerator - Mixin for controllers that
166 use the L<SL::ReportGenerator> class
170 package SL::Controller::Unicorn;
172 use SL::Controller::Helper::ReportGenerator;
177 # Set up the report generator instance. In this example this is
178 # hidden in "prepare_report".
179 my $report = $self->prepare_report;
181 # Get objects from database.
182 my $orders = SL::DB::Manager::Order->get_all(...);
184 # Let report generator create the output.
185 $self->report_generator_list_objects(
195 =item C<action_report_generator_back>
197 This is the controller action that's called from the one of the report
198 generator's 'export options' pages when the user clicks on the 'back'
201 It is never called from a controller manually and should just work
204 =item C<action_report_generator_export_as_csv>
206 This is the controller action that's called from the generated report
207 when the user wants to export as CSV. First the CSV export options are
208 shown and afterwards the CSV file is generated and offered for
211 It is never called from a controller manually and should just work
214 =item C<action_report_generator_export_as_pdf>
216 This is the controller action that's called from the generated report
217 when the user wants to export as PDF. First the PDF export options are
218 shown and afterwards the PDF file is generated and offered for
221 It is never called from a controller manually and should just work
224 =item C<report_generator_do>
226 This is a common function that's called from
227 L<action_report_generator_back>,
228 L<action_report_generator_export_as_csv> and
229 L<action_report_generator_export_as_pdf>. It handles common options
230 and report generation after options have been set.
232 It is never called from a controller manually and should just work
235 =item C<report_generator_list_objects %params>
237 Iterates over all objects, creates the actual rows of data, hands them
238 over to the report generator and lets the report generator create the
241 C<%params> can contain the following values:
247 Mandatory. An instance of L<SL::ReportGenerator> that has been set up
248 already (column definitions, title, sort handling etc).
252 Mandatory. An array reference of RDBO models to output.
254 =item C<data_callback>
256 Optional. A callback handler (code reference) that gets called for
257 each row before it is passed to the report generator. The row passed
258 will be the handler's first and only argument (a hash reference). It's
259 the same hash reference that's passed to
260 L<SL::ReportGenrator/add_data>.
264 An optional hash reference that's passed verbatim to the function
265 L<SL::ReportGenerator/generate_with_headers>.
269 If the buttons for exporting PDF and/or CSV variants are included in
270 the action bar. Otherwise they're rendered at the bottom of the page.
272 The value can be either a specific action bar instance or simply 1 in
273 which case the default action bar is used:
274 C<$::request-E<gt>layout-E<gt>get('actionbar')>.
286 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>