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>