Refactoring: list_objects() aus Controllern in ReportGenerator-Helfer verschieben
authorMoritz Bunkus <m.bunkus@linet-services.de>
Tue, 5 Feb 2013 08:39:16 +0000 (09:39 +0100)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Tue, 5 Feb 2013 08:54:17 +0000 (09:54 +0100)
SL/Controller/DeliveryPlan.pm
SL/Controller/Helper/ReportGenerator.pm
SL/Controller/Project.pm
SL/Controller/SellPriceInformation.pm

index 83081f4..33bede6 100644 (file)
@@ -51,9 +51,9 @@ sub action_list {
 
   $self->prepare_report;
 
-  $self->{orderitems} = $self->get_models(%{ $self->db_args });
+  my $orderitems = $self->get_models(%{ $self->db_args });
 
-  $self->list_objects;
+  $self->report_generator_list_objects(report => $self->{report}, objects => $orderitems);
 }
 
 # private functions
@@ -190,30 +190,6 @@ sub prepare_report {
   $self->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
 
   $self->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
-
-  $self->{report_data} = {
-    column_defs        => \%column_defs,
-    columns            => \@columns,
-  };
-}
-
-sub list_objects {
-  my ($self) = @_;
-  my $column_defs = $self->{report_data}{column_defs};
-  for my $obj (@{ $self->{orderitems} || [] }) {
-    $self->{report}->add_data({
-      map {
-        $_ => {
-          data => $column_defs->{$_}{sub} ? $column_defs->{$_}{sub}->($obj)
-                : $obj->can($_)           ? $obj->$_
-                :                           $obj->{$_},
-          link => $column_defs->{$_}{obj_link} ? $column_defs->{$_}{obj_link}->($obj) : '',
-        },
-      } @{ $self->{report_data}{columns} || {} }
-    });
-  }
-
-  return $self->{report}->generate_with_headers;
 }
 
 sub make_filter_summary {
index 3455375..3cf2622 100644 (file)
@@ -1,16 +1,8 @@
-#=====================================================================
-# LX-Office ERP
-# Copyright (C) 2004
-# Based on SQL-Ledger Version 2.1.9
-# Web http://www.lx-office.org
-######################################################################
-#
-# Mixin for controllers to use ReportGenerator things
-#
-######################################################################
+package SL::Controller::Helper::ReportGenerator;
 
 use strict;
 
+use Carp;
 use List::Util qw(max);
 
 use SL::Form;
@@ -22,6 +14,7 @@ use Exporter 'import';
 our @EXPORT = qw(
   action_report_generator_export_as_pdf action_report_generator_export_as_csv
   action_report_generator_back report_generator_do
+  report_generator_list_objects
 );
 
 sub action_report_generator_export_as_pdf {
@@ -71,14 +64,6 @@ sub action_report_generator_back {
   $_[0]->report_generator_do('HTML');
 }
 
-sub report_generator_set_default_sort {
-  my ($default_sortorder, $default_sortdir) = @_;
-
-  $::form->{sort}         ||= $default_sortorder;
-  $::form->{sortdir}        = $default_sortdir unless (defined $::form->{sortdir});
-  $::form->{sortdir}        = $::form->{sortdir} ? 1 : 0;
-}
-
 sub report_generator_do {
   my ($self, $format)  = @_;
 
@@ -98,4 +83,157 @@ sub report_generator_do {
   $self->_run_action($nextsub);
 }
 
+sub report_generator_list_objects {
+  my ($self, %params) = @_;
+
+  croak "Parameter 'objects' must exist and be an array reference"                if                      ref($params{objects}) ne 'ARRAY';
+  croak "Parameter 'report' must exist and be an instance of SL::ReportGenerator" if                      ref($params{report})  ne 'SL::ReportGenerator';
+  croak "Parameter 'options', if exists, must be a hash reference"                if $params{options} && (ref($params{options}) ne 'HASH');
+
+  my $column_defs = $params{report}->{columns};
+  my @columns     = $params{report}->get_visible_columns;
+
+  for my $obj (@{ $params{objects} || [] }) {
+    my %data = map {
+      my $def = $column_defs->{$_};
+      $_ => {
+        raw_data => $def->{raw_data} ? $def->{raw_data}->($obj) : '',
+        data     => $def->{sub}      ? $def->{sub}->($obj)
+                  : $obj->can($_)    ? $obj->$_
+                  :                    $obj->{$_},
+        link     => $def->{obj_link} ? $def->{obj_link}->($obj) : '',
+      },
+    } @columns;
+
+    $params{data_callback}->(\%data) if $params{data_callback};
+
+    $params{report}->add_data(\%data);
+  }
+
+  return $params{report}->generate_with_headers(%{ $params{options} || {}});
+}
+
 1;
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+SL::Controller::Helper::ReportGenerator - Mixin for controllers that
+use the L<SL::ReportGenerator> class
+
+=head1 SYNOPSIS
+
+  package SL::Controller::Unicorn;
+
+  use SL::Controller::Helper::ReportGenerator;
+
+  sub action_list {
+    my ($self) = @_;
+
+    # Set up the report generator instance. In this example this is
+    # hidden in "prepare_report".
+    my $report = $self->prepare_report;
+
+    # Get objects from database.
+    my $orders = SL::DB::Manager::Order->get_all(...);
+
+    # Let report generator create the output.
+    $self->report_generator_list_objects(
+      report  => $report,
+      objects => $orders,
+    );
+  }
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item C<action_report_generator_back>
+
+This is the controller action that's called from the one of the report
+generator's 'export options' pages when the user clicks on the 'back'
+button.
+
+It is never called from a controller manually and should just work
+as-is.
+
+=item C<action_report_generator_export_as_csv>
+
+This is the controller action that's called from the generated report
+when the user wants to export as CSV. First the CSV export options are
+shown and afterwards the CSV file is generated and offered for
+download.
+
+It is never called from a controller manually and should just work
+as-is.
+
+=item C<action_report_generator_export_as_pdf>
+
+This is the controller action that's called from the generated report
+when the user wants to export as PDF. First the PDF export options are
+shown and afterwards the PDF file is generated and offered for
+download.
+
+It is never called from a controller manually and should just work
+as-is.
+
+=item C<report_generator_do>
+
+This is a common function that's called from
+L<action_report_generator_back>,
+L<action_report_generator_export_as_csv> and
+L<action_report_generator_export_as_pdf>. It handles common options
+and report generation after options have been set.
+
+It is never called from a controller manually and should just work
+as-is.
+
+=item C<report_generator_list_objects %params>
+
+Iterates over all objects, creates the actual rows of data, hands them
+over to the report generator and lets the report generator create the
+output.
+
+C<%params> can contain the following values:
+
+=over 2
+
+=item C<report>
+
+Mandatory. An instance of L<SL::ReportGenerator> that has been set up
+already (column definitions, title, sort handling etc).
+
+=item C<objects>
+
+Mandatory. An array reference of RDBO models to output.
+
+=item C<data_callback>
+
+Optional. A callback handler (code reference) that gets called for
+each row before it is passed to the report generator. The row passed
+will be the handler's first and only argument (a hash reference). It's
+the same hash reference that's passed to
+L<SL::ReportGenrator/add_data>.
+
+=item C<options>
+
+An optional hash reference that's passed verbatim to the function
+L<SL::ReportGenerator/generate_with_headers>.
+
+=back
+
+=back
+
+=head1 BUGS
+
+Nothing here yet.
+
+=head1 AUTHOR
+
+Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
+
+=cut
index 386d755..46a8c59 100644 (file)
@@ -77,9 +77,9 @@ sub action_list {
 
   $self->prepare_report;
 
-  $self->{projects} = $self->get_models(%{ $self->db_args });
+  my $projects = $self->get_models(%{ $self->db_args });
 
-  $self->list_objects;
+  $self->report_generator_list_objects(report => $self->{report}, objects => $projects);
 }
 
 sub action_new {
@@ -274,31 +274,6 @@ sub prepare_report {
   $self->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
 
   $self->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
-
-  $self->{report_data} = {
-    column_defs        => \%column_defs,
-    columns            => \@columns,
-  };
-}
-
-sub list_objects {
-  my ($self)      = @_;
-  my $column_defs = $self->{report_data}->{column_defs};
-
-  for my $obj (@{ $self->{projects} || [] }) {
-    my %data = map {
-      $_ => {
-        data => $column_defs->{$_}{sub} ? $column_defs->{$_}{sub}->($obj)
-              : $obj->can($_)           ? $obj->$_
-              :                           $obj->{$_},
-        link => $column_defs->{$_}{obj_link} ? $column_defs->{$_}{obj_link}->($obj) : '',
-      },
-    } @{ $self->{report_data}{columns} || {} };
-
-    $self->{report}->add_data(\%data);
-  }
-
-  return $self->{report}->generate_with_headers;
 }
 
 1;
index e44478a..f31f53e 100644 (file)
@@ -32,9 +32,9 @@ sub action_list {
     db_args => $db_args,
   );
 
-  $self->{orderitems} = SL::DB::Manager::OrderItem->get_all(%$db_args);
+  my $orderitems = SL::DB::Manager::OrderItem->get_all(%$db_args);
 
-  $self->list_objects;
+  $self->report_generator_list_objects(report => $self->{report}, objects => $orderitems, options => { no_layout => 1 });
 }
 
 # private functions
@@ -124,32 +124,6 @@ sub prepare_report {
     title                => $::locale->text('Sales Price information'),
   );
   $report->set_options_from_form;
-
-  $self->{report_data} = {
-    column_defs => $column_defs,
-    columns     => \@columns,
-    visible     => \@visible,
-    sortable    => \@sortable,
-  };
-}
-
-sub list_objects {
-  my ($self) = @_;
-  my $column_defs = $self->{report_data}{column_defs};
-  for my $obj (@{ $self->{orderitems} || [] }) {
-    $self->{report}->add_data({
-      map {
-        $_ => {
-          data => $column_defs->{$_}{sub} ? $column_defs->{$_}{sub}->($obj)
-                : $obj->can($_)           ? $obj->$_
-                :                           $obj->{$_},
-          link => $column_defs->{$_}{obj_link} ? $column_defs->{$_}{obj_link}->($obj) : '',
-        },
-      } @{ $self->{report_data}{columns} || {} }
-    });
-  }
-
-  return $self->{report}->generate_with_headers(no_layout => 1);
 }
 
 sub link_to {