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 $::request->layout->get('actionbar')->add(
27 $type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
28 submit => [ '#report_generator_form', { $key => "${value}report_generator_export_as_${type}" } ],
31 $::locale->text('Back'),
32 submit => [ '#report_generator_form', { $key => "${value}report_generator_back" } ],
37 sub action_report_generator_export_as_pdf {
40 delete $::form->{action_report_generator_export_as_pdf};
42 if ($::form->{report_generator_pdf_options_set}) {
43 my $saved_form = save_form();
45 $self->report_generator_do('PDF');
47 if ($::form->{report_generator_printed}) {
48 restore_form($saved_form);
49 $::form->{MESSAGE} = $::locale->text('The list has been printed.');
50 $self->report_generator_do('HTML');
56 my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
58 $::form->get_lists('printers' => 'ALL_PRINTERS');
59 map { $_->{selected} = $::myconfig{default_printer_id} == $_->{id} } @{ $::form->{ALL_PRINTERS} };
61 $::form->{copies} = max $::myconfig{copies} * 1, 1;
62 $::form->{title} = $::locale->text('PDF export -- options');
64 _setup_action_bar($self, 'pdf'); # Sub not exported, therefore don't call via object.
67 print $::form->parse_html_template('report_generator/pdf_export_options', {
68 'HIDDEN' => \@form_values,
69 'ALLOW_FONT_SELECTION' => SL::ReportGenerator->check_for_pdf_api, });
72 sub action_report_generator_export_as_csv {
75 delete $::form->{action_report_generator_export_as_csv};
77 if ($::form->{report_generator_csv_options_set}) {
78 $self->report_generator_do('CSV');
82 my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
84 $::form->{title} = $::locale->text('CSV export -- options');
86 _setup_action_bar($self, 'csv'); # Sub not exported, therefore don't call via object.
89 print $::form->parse_html_template('report_generator/csv_export_options', { 'HIDDEN' => \@form_values });
92 sub action_report_generator_back {
93 $_[0]->report_generator_do('HTML');
96 sub report_generator_do {
97 my ($self, $format) = @_;
99 my $nextsub = $::form->{report_generator_nextsub};
101 $::form->error($::locale->text('report_generator_nextsub is not defined.'));
104 foreach my $key (split m/ +/, $::form->{report_generator_variable_list}) {
105 $::form->{$key} = $::form->{"report_generator_hidden_${key}"};
108 $::form->{report_generator_output_format} = $format;
110 delete @{$::form}{map { "report_generator_$_" } qw(nextsub variable_list)};
112 $self->_run_action($nextsub);
115 sub report_generator_list_objects {
116 my ($self, %params) = @_;
118 croak "Parameter 'objects' must exist and be an array reference" if ref($params{objects}) ne 'ARRAY';
119 croak "Parameter 'report' must exist and be an instance of SL::ReportGenerator" if ref($params{report}) ne 'SL::ReportGenerator';
120 croak "Parameter 'options', if exists, must be a hash reference" if $params{options} && (ref($params{options}) ne 'HASH');
121 $params{layout} //= 1;
123 my $column_defs = $params{report}->{columns};
124 my @columns = $params{report}->get_visible_columns('HTML');
126 for my $obj (@{ $params{objects} || [] }) {
128 my $def = $column_defs->{$_};
130 raw_data => $def->{raw_data} ? $def->{raw_data}->($obj) : '',
131 data => $def->{sub} ? $def->{sub}->($obj)
132 : $obj->can($_) ? $obj->$_
134 link => $def->{obj_link} ? $def->{obj_link}->($obj) : '',
138 $params{data_callback}->(\%data) if $params{data_callback};
140 $params{report}->add_data(\%data);
143 my %options = %{ $params{options} || {} };
144 $options{action_bar} //= $params{action_bar} // 1;
146 if ($params{layout}) {
147 return $params{report}->generate_with_headers(%options);
149 my $html = $params{report}->generate_html_content(action_bar => 0, %options);
150 $self->render(\$html , { layout => 0, process => 0 });
163 SL::Controller::Helper::ReportGenerator - Mixin for controllers that
164 use the L<SL::ReportGenerator> class
168 package SL::Controller::Unicorn;
170 use SL::Controller::Helper::ReportGenerator;
175 # Set up the report generator instance. In this example this is
176 # hidden in "prepare_report".
177 my $report = $self->prepare_report;
179 # Get objects from database.
180 my $orders = SL::DB::Manager::Order->get_all(...);
182 # Let report generator create the output.
183 $self->report_generator_list_objects(
193 =item C<action_report_generator_back>
195 This is the controller action that's called from the one of the report
196 generator's 'export options' pages when the user clicks on the 'back'
199 It is never called from a controller manually and should just work
202 =item C<action_report_generator_export_as_csv>
204 This is the controller action that's called from the generated report
205 when the user wants to export as CSV. First the CSV export options are
206 shown and afterwards the CSV file is generated and offered for
209 It is never called from a controller manually and should just work
212 =item C<action_report_generator_export_as_pdf>
214 This is the controller action that's called from the generated report
215 when the user wants to export as PDF. First the PDF export options are
216 shown and afterwards the PDF file is generated and offered for
219 It is never called from a controller manually and should just work
222 =item C<report_generator_do>
224 This is a common function that's called from
225 L<action_report_generator_back>,
226 L<action_report_generator_export_as_csv> and
227 L<action_report_generator_export_as_pdf>. It handles common options
228 and report generation after options have been set.
230 It is never called from a controller manually and should just work
233 =item C<report_generator_list_objects %params>
235 Iterates over all objects, creates the actual rows of data, hands them
236 over to the report generator and lets the report generator create the
239 C<%params> can contain the following values:
245 Mandatory. An instance of L<SL::ReportGenerator> that has been set up
246 already (column definitions, title, sort handling etc).
250 Mandatory. An array reference of RDBO models to output.
252 =item C<data_callback>
254 Optional. A callback handler (code reference) that gets called for
255 each row before it is passed to the report generator. The row passed
256 will be the handler's first and only argument (a hash reference). It's
257 the same hash reference that's passed to
258 L<SL::ReportGenrator/add_data>.
262 An optional hash reference that's passed verbatim to the function
263 L<SL::ReportGenerator/generate_with_headers>.
267 If the buttons for exporting PDF and/or CSV variants are included in
268 the action bar. Otherwise they're rendered at the bottom of the page.
270 The value can be either a specific action bar instance or simply 1 in
271 which case the default action bar is used:
272 C<$::request-E<gt>layout-E<gt>get('actionbar')>.
284 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>