Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
authorMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 5 Sep 2012 15:44:25 +0000 (17:44 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 5 Sep 2012 15:44:25 +0000 (17:44 +0200)
SL/Controller/BackgroundJob.pm
SL/Controller/BackgroundJobHistory.pm
SL/Controller/Base.pm
SL/Controller/DeliveryPlan.pm
SL/Controller/Helper/GetModels.pm
SL/Controller/Helper/Paginated.pm
SL/Controller/Helper/Sorted.pm
SL/Template/Plugin/L.pm
templates/webpages/delivery_plan/report_bottom.html

index f80f57a..bddb308 100644 (file)
@@ -26,12 +26,12 @@ __PACKAGE__->make_paginated(ONLY => [ qw(list) ]);
 __PACKAGE__->make_sorted(
   ONLY         => [ qw(list) ],
 
-  package_name => $::locale->text('Package name'),
-  type         => $::locale->text('Execution type'),
-  active       => $::locale->text('Active'),
-  cron_spec    => $::locale->text('Execution schedule'),
-  last_run_at  => $::locale->text('Last run at'),
-  next_run_at  => $::locale->text('Next run at'),
+  package_name => 'Package name',
+  type         => 'Execution type',
+  active       => 'Active',
+  cron_spec    => 'Execution schedule',
+  last_run_at  => 'Last run at',
+  next_run_at  => 'Next run at',
 );
 
 #
index 5992dc0..3e11106 100644 (file)
@@ -26,11 +26,11 @@ __PACKAGE__->make_paginated(ONLY => [ qw(list) ]);
 __PACKAGE__->make_sorted(
   ONLY         => [ qw(list) ],
 
-  package_name => $::locale->text('Package name'),
-  run_at       => $::locale->text('Run at'),
-  status       => $::locale->text('Execution status'),
-  result       => $::locale->text('Result'),
-  error        => $::locale->text('Error'),
+  package_name => 'Package name',
+  run_at       => 'Run at',
+  status       => 'Execution status',
+  result       => 'Result',
+  error        => 'Error',
 );
 
 #
index 1188ffe..ac2f32d 100644 (file)
@@ -10,6 +10,11 @@ use List::Util qw(first);
 use SL::Request qw(flatten);
 use SL::MoreCommon qw(uri_encode);
 
+use Rose::Object::MakeMethods::Generic
+(
+  scalar => [ qw(action_name) ],
+);
+
 #
 # public/helper functions
 #
@@ -20,7 +25,7 @@ sub url_for {
   return $_[0] if (scalar(@_) == 1) && !ref($_[0]);
 
   my %params      = ref($_[0]) eq 'HASH' ? %{ $_[0] } : @_;
-  my $controller  = delete($params{controller}) || $self->_controller_name;
+  my $controller  = delete($params{controller}) || $self->controller_name;
   my $action      = $params{action}             || 'dispatch';
 
   my $script;
@@ -124,6 +129,12 @@ sub send_file {
   $file->close;
 }
 
+sub controller_name {
+  my $class = ref($_[0]) || $_[0];
+  $class    =~ s/^SL::Controller:://;
+  return $class;
+}
+
 #
 # Before/after run hooks
 #
@@ -198,17 +209,12 @@ sub _run_action {
 
   $::form->error("Invalid action '${action}' for controller " . ref($self)) if !$self->can($sub);
 
+  $self->action_name($action);
   $self->_run_hooks('before', $action);
   $self->$sub(@_);
   $self->_run_hooks('after', $action);
 }
 
-sub _controller_name {
-  my $class = ref($_[0]) || $_[0];
-  $class    =~ s/^SL::Controller:://;
-  return $class;
-}
-
 sub _dispatch {
   my $self    = shift;
 
@@ -218,6 +224,7 @@ sub _dispatch {
   my $sub     = "action_${action}";
 
   if ($self->can($sub)) {
+    $self->action_name($action);
     $self->_run_hooks('before', $action);
     $self->$sub(@_);
     $self->_run_hooks('after', $action);
@@ -470,7 +477,7 @@ parameter or as a normal hash.
 
 The controller to call is given by C<$params{controller}>. It defaults
 to the current controller as returned by
-L</_controller_name>.
+L</controller_name>.
 
 The action to call is given by C<$params{action}>. It defaults to
 C<dispatch>.
@@ -543,6 +550,18 @@ variables whose name starts with C<{AUTH}> are removed before the
 request is routed. Only controllers that handle login requests
 themselves should return trueish for this function.
 
+=item C<controller_name>
+
+Returns the name of the curernt controller package without the
+C<SL::Controller::> prefix. This method can be called both as a class
+method and an instance method.
+
+=item C<action_name>
+
+Returns the name of the currently executing action. If the dispatcher
+mechanism was used then this is not C<dispatch> but the actual method
+name the dispatching resolved to.
+
 =back
 
 =head2 PRIVATE FUNCTIONS
@@ -551,11 +570,6 @@ These functions are supposed to be used from this base class only.
 
 =over 4
 
-=item C<_controller_name>
-
-Returns the name of the curernt controller package without the
-C<SL::Controller::> prefix.
-
 =item C<_dispatch>
 
 Implements the method lookup for indirect dispatching mentioned in the
index e280a1b..975e89c 100644 (file)
@@ -5,23 +5,50 @@ use parent qw(SL::Controller::Base);
 
 use Clone qw(clone);
 use SL::DB::OrderItem;
+use SL::Controller::Helper::GetModels;
+use SL::Controller::Helper::Paginated;
+use SL::Controller::Helper::Sorted;
 use SL::Controller::Helper::ParseFilter;
 use SL::Controller::Helper::ReportGenerator;
 
+use Rose::Object::MakeMethods::Generic (
+  scalar => [ qw(db_args flat_filter) ],
+);
+
 __PACKAGE__->run_before(sub { $::auth->assert('sales_order_edit'); });
 
+__PACKAGE__->get_models_url_params('flat_filter');
+__PACKAGE__->make_paginated(
+  MODEL         => 'OrderItem',
+  PAGINATE_ARGS => 'db_args',
+  ONLY          => [ qw(list) ],
+);
+
+__PACKAGE__->make_sorted(
+  MODEL       => 'OrderItem',
+  ONLY        => [ qw(list) ],
+
+  DEFAULT_BY  => 'reqdate',
+  DEFAULT_DIR => 1,
+
+  reqdate     => 'Reqdate',
+  description => 'Description',
+  partnumber  => 'Part Number',
+  qty         => 'Qty',
+  missing     => 'Missing qty',
+  shipped_qty => 'shipped',
+  ordnumber   => 'Order',
+  customer    => 'Customer',
+);
+
 sub action_list {
   my ($self) = @_;
   my %list_params = (
-    sort_by  => $::form->{sort_by} || 'reqdate',
-    sort_dir => $::form->{sort_dir},
     filter   => $::form->{filter},
-    page     => $::form->{page},
   );
 
-  my $db_args = $self->setup_for_list(%list_params);
-  $self->{pages} = SL::DB::Manager::OrderItem->paginate(%list_params, args => $db_args);
-  $self->{flat_filter} = { map { $_->{key} => $_->{value} } $::form->flatten_variables('filter') };
+  $self->db_args($self->setup_for_list(%list_params));
+  $self->flat_filter({ map { $_->{key} => $_->{value} } $::form->flatten_variables('filter') });
   $self->make_filter_summary;
 
   my $top    = $::form->parse_html_template('delivery_plan/report_top', { FORM => $::form, SELF => $self });
@@ -33,13 +60,10 @@ sub action_list {
       raw_bottom_info_text => $bottom,
       controller_class     => 'DeliveryPlan',
     },
-    report_generator_export_options => [
-      'list', qw(filter sort_by sort_dir),
-    ],
-    db_args => $db_args,
+    report_generator_export_options => [ qw(list filter) ],
   );
 
-  $self->{orderitems} = SL::DB::Manager::OrderItem->get_all(%$db_args);
+  $self->{orderitems} = $self->get_models(%{ $self->db_args });
 
   $self->list_objects;
 }
@@ -55,8 +79,6 @@ sub setup_for_list {
       with_objects => [ 'order', 'order.customer', 'part' ],
       launder_to => $self->{filter},
     ),
-    sort_by => $self->set_sort_params(%params),
-    page    => $params{page},
   );
 
   $args{query} = [ @{ $args{query} || [] },
@@ -116,14 +138,6 @@ sub setup_for_list {
   return \%args;
 }
 
-sub set_sort_params {
-  my ($self, %params) = @_;
-  my $sort_str;
-  ($self->{sort_by}, $self->{sort_dir}, $sort_str) =
-    SL::DB::Manager::OrderItem->make_sort_string(%params);
-  return $sort_str;
-}
-
 sub prepare_report {
   my ($self, %params) = @_;
 
@@ -136,45 +150,27 @@ sub prepare_report {
   my @sortable = qw(reqdate partnumber description                 ordnumber customer);
 
   my %column_defs = (
-    reqdate                 => { text => $::locale->text('Reqdate'),
-                                  sub => sub { $_[0]->reqdate_as_date || $_[0]->order->reqdate_as_date }},
-    description             => { text => $::locale->text('Description'),
-                                  sub => sub { $_[0]->description },
-                             obj_link => sub { $self->link_to($_[0]->part) }},
-    partnumber              => { text => $::locale->text('Part Number'),
-                                  sub => sub { $_[0]->part->partnumber },
-                             obj_link => sub { $self->link_to($_[0]->part) }},
-    qty                     => { text => $::locale->text('Qty'),
-                                  sub => sub { $_[0]->qty_as_number . ' ' . $_[0]->unit }},
-    missing                 => { text => $::locale->text('Missing qty'),
-                                  sub => sub { $::form->format_amount(\%::myconfig, $_[0]->qty - $_[0]->shipped_qty, 2) . ' ' . $_[0]->unit }},
-    shipped_qty             => { text => $::locale->text('shipped'),
-                                  sub => sub { $::form->format_amount(\%::myconfig, $_[0]->shipped_qty, 2) . ' ' . $_[0]->unit }},
-    ordnumber               => { text => $::locale->text('Order'),
-                                  sub => sub { $_[0]->order->ordnumber },
-                             obj_link => sub { $self->link_to($_[0]->order) }},
-    customer                => { text => $::locale->text('Customer'),
-                                  sub => sub { $_[0]->order->customer->name },
-                             obj_link => sub { $self->link_to($_[0]->order->customer) }},
+    reqdate                 => {      sub => sub { $_[0]->reqdate_as_date || $_[0]->order->reqdate_as_date }},
+    description             => {      sub => sub { $_[0]->description },
+                                 obj_link => sub { $self->link_to($_[0]->part) }},
+    partnumber              => {      sub => sub { $_[0]->part->partnumber },
+                                 obj_link => sub { $self->link_to($_[0]->part) }},
+    qty                     => {      sub => sub { $_[0]->qty_as_number . ' ' . $_[0]->unit }},
+    missing                 => {      sub => sub { $::form->format_amount(\%::myconfig, $_[0]->qty - $_[0]->shipped_qty, 2) . ' ' . $_[0]->unit }},
+    shipped_qty             => {      sub => sub { $::form->format_amount(\%::myconfig, $_[0]->shipped_qty, 2) . ' ' . $_[0]->unit }},
+    ordnumber               => {      sub => sub { $_[0]->order->ordnumber },
+                                 obj_link => sub { $self->link_to($_[0]->order) }},
+    customer                => {      sub => sub { $_[0]->order->customer->name },
+                                 obj_link => sub { $self->link_to($_[0]->order->customer) }},
   );
 
-
-  for my $col (@sortable) {
-    $column_defs{$col}{link} = $self->url_for(
-      action   => 'list',
-      sort_by  => $col,
-      sort_dir => ($self->{sort_by} eq $col ? 1 - $self->{sort_dir} : $self->{sort_dir}),
-      page     => $self->{pages}{cur},
-      %{ $self->{flat_filter} },
-    );
-  }
+  map { $column_defs{$_}->{text} = $::locale->text( $self->get_sort_spec->{$_}->{title} ) } keys %column_defs;
 
   map { $column_defs{$_}->{visible} = 1 } @visible;
 
   $report->set_columns(%column_defs);
   $report->set_column_order(@columns);
   $report->set_options(allow_pdf_export => 1, allow_csv_export => 1);
-  $report->set_sort_indicator(%params);
   $report->set_export_options(@{ $params{report_generator_export_options} || [] });
   $report->set_options(
     %{ $params{report_generator_options} || {} },
@@ -183,8 +179,9 @@ sub prepare_report {
     title                => $::locale->text('Delivery Plan'),
   );
   $report->set_options_from_form;
+  $self->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
 
-  SL::DB::Manager::OrderItem->disable_paginating(args => $params{db_args}) if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
+  $self->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
 
   $self->{report_data} = {
     column_defs => \%column_defs,
index 00ef310..e353657 100644 (file)
@@ -3,7 +3,7 @@ package SL::Controller::Helper::GetModels;
 use strict;
 
 use Exporter qw(import);
-our @EXPORT = qw(get_callback get_models);
+our @EXPORT = qw(get_models_url_params get_callback get_models);
 
 use constant PRIV => '__getmodelshelperpriv';
 
@@ -21,6 +21,22 @@ sub register_get_models_handlers {
   map { push @{ $registered_handlers{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %registered_handlers;
 }
 
+sub get_models_url_params {
+  my ($class, $sub_name_or_code) = @_;
+
+  my $code     = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->$sub_name_or_code(@_) };
+  my $callback = sub {
+    my ($self, %params)   = @_;
+    my @additional_params = $code->($self);
+    return (
+      %params,
+      (scalar(@additional_params) == 1) && (ref($additional_params[0]) eq 'HASH') ? %{ $additional_params[0] } : @additional_params,
+    );
+  };
+
+  push @{ $registered_handlers{callback} }, $callback;
+}
+
 sub get_callback {
   my ($self, %override_params) = @_;
 
@@ -102,6 +118,19 @@ in L<get_callback>.
 
 =over 4
 
+=item C<get_models_url_params $class, $sub>
+
+Register one of the controller's subs to be called whenever an URL has
+to be generated (e.g. for sort and pagination links). This is a way
+for the controller to add additional parameters to the URL (e.g. for
+filter parameters).
+
+The C<$sub> parameter can be either a code reference or the name of
+one of the controller's functions.
+
+The value returned by this C<$sub> must be either a single hash
+reference or a hash of key/value pairs to add to the URL.
+
 =item C<register_get_models_handlers $class, %handlers>
 
 This function should only be called from other controller helpers like
index f4a319d..d3da20d 100644 (file)
@@ -3,7 +3,7 @@ package SL::Controller::Helper::Paginated;
 use strict;
 
 use Exporter qw(import);
-our @EXPORT = qw(make_paginated get_paginate_spec get_current_paginate_params _save_current_paginate_params _get_models_handler_for_paginated _callback_handler_for_paginated);
+our @EXPORT = qw(make_paginated get_paginate_spec get_current_paginate_params _save_current_paginate_params _get_models_handler_for_paginated _callback_handler_for_paginated disable_pagination);
 
 use constant PRIV => '__paginatedhelper_priv';
 
@@ -12,12 +12,13 @@ my $controller_paginate_spec;
 sub make_paginated {
   my ($class, %specs)       = @_;
 
-  $specs{MODEL}           ||=  $class->_controller_name;
+  $specs{MODEL}           ||=  $class->controller_name;
   $specs{MODEL}             =~ s{ ^ SL::DB:: (?: .* :: )? }{}x;
   $specs{PER_PAGE}        ||= "SL::DB::Manager::$specs{MODEL}"->default_objects_per_page;
   $specs{FORM_PARAMS}     ||= [ qw(page per_page) ];
   $specs{ONLY}            ||= [];
   $specs{ONLY}              = [ $specs{ONLY} ] if !ref $specs{ONLY};
+  $specs{ONLY_MAP}          = @{ $specs{ONLY} } ? { map { ($_ => 1) } @{ $specs{ONLY} } } : { '__ALL__' => 1 };
 
   $controller_paginate_spec = \%specs;
 
@@ -45,7 +46,7 @@ sub get_current_paginate_params {
 
   my $spec              = $self->get_paginate_spec;
 
-  my $priv              = $self->{PRIV()} || {};
+  my $priv              = _priv($self);
   $params{page}         = $priv->{page}     unless defined $params{page};
   $params{per_page}     = $priv->{per_page} unless defined $params{per_page};
 
@@ -54,7 +55,10 @@ sub get_current_paginate_params {
     per_page            => ($params{per_page} * 1) || $spec->{PER_PAGE},
   );
 
-  my $calculated_params = "SL::DB::Manager::$spec->{MODEL}"->paginate(%paginate_params, args => {});
+  my %paginate_args     = ref($spec->{PAGINATE_ARGS}) eq 'CODE' ? %{ $spec->{PAGINATE_ARGS}->($self) }
+                        :     $spec->{PAGINATE_ARGS}            ? do { my $sub = $spec->{PAGINATE_ARGS}; %{ $self->$sub() } }
+                        :                                         ();
+  my $calculated_params = "SL::DB::Manager::$spec->{MODEL}"->paginate(%paginate_params, args => \%paginate_args);
   %paginate_params      = (
     %paginate_params,
     num_pages    => $calculated_params->{max},
@@ -66,6 +70,11 @@ sub get_current_paginate_params {
   return %paginate_params;
 }
 
+sub disable_pagination {
+  my ($self)               = @_;
+  _priv($self)->{disabled} = 1;
+}
+
 #
 # private functions
 #
@@ -73,6 +82,8 @@ sub get_current_paginate_params {
 sub _save_current_paginate_params {
   my ($self)        = @_;
 
+  return if !_is_enabled($self);
+
   my $paginate_spec = $self->get_paginate_spec;
   $self->{PRIV()}   = {
     page            => $::form->{ $paginate_spec->{FORM_PARAMS}->[0] } || 1,
@@ -84,9 +95,9 @@ sub _save_current_paginate_params {
 
 sub _callback_handler_for_paginated {
   my ($self, %params) = @_;
-  my $priv            = $self->{PRIV()} || {};
+  my $priv            = _priv($self);
 
-  if ($priv->{page}) {
+  if (_is_enabled($self) && $priv->{page}) {
     my $paginate_spec                             = $self->get_paginate_spec;
     $params{ $paginate_spec->{FORM_PARAMS}->[0] } = $priv->{page};
     $params{ $paginate_spec->{FORM_PARAMS}->[1] } = $priv->{per_page} if $priv->{per_page};
@@ -99,15 +110,27 @@ sub _callback_handler_for_paginated {
 
 sub _get_models_handler_for_paginated {
   my ($self, %params)    = @_;
-  $params{model}       ||= $self->get_paginate_spec->{MODEL};
+  my $spec               = $self->get_paginate_spec;
+  $params{model}       ||= $spec->{MODEL};
 
-  "SL::DB::Manager::$params{model}"->paginate($self->get_current_paginate_params, args => \%params);
+  "SL::DB::Manager::$params{model}"->paginate($self->get_current_paginate_params, args => \%params) if _is_enabled($self);
 
-  # $::lxdebug->dump(0, "GM handler for paginated; params nach modif:", \%params);
+  # $::lxdebug->dump(0, "GM handler for paginated; params nach modif (is_enabled? " . _is_enabled($self) . ")", \%params);
 
   return %params;
 }
 
+sub _priv {
+  my ($self)        = @_;
+  $self->{PRIV()} ||= {};
+  return $self->{PRIV()};
+}
+
+sub _is_enabled {
+  my ($self) = @_;
+  return !_priv($self)->{disabled} && ($self->get_paginate_spec->{ONLY_MAP}->{$self->action_name} || $self->get_paginate_spec->{ONLY_MAP}->{'__ALL__'});
+}
+
 1;
 __END__
 
@@ -211,6 +234,19 @@ derived from the controller's package (e.g. for the controller
 C<SL::Controller::BackgroundJobHistory> the C<MODEL> would default to
 C<BackgroundJobHistory>).
 
+=item * C<PAGINATE_ARGS>
+
+Optional. Either a code reference or the name of function to be called
+on the controller importing this helper.
+
+If this funciton is given then the paginate helper calls it whenever
+it has to count the total number of models for calculating the number
+of pages to display. The function must return a hash reference with
+elements suitable for passing to a Rose model manager's C<get_all>
+function.
+
+This can be used e.g. when filtering is used.
+
 =item * C<PER_PAGE>
 
 Optional. An integer: the number of models to return per page.
@@ -278,6 +314,12 @@ Returns a hash reference to the paginate spec structure given in the call
 to L<make_paginated> after normalization (hash reference construction,
 applying default parameters etc).
 
+=item C<disable_pagination>
+
+Disable pagination for the duration of the current action. Can be used
+when using the attribute C<ONLY> to L<make_paginated> does not
+cover all cases.
+
 =back
 
 =head1 BUGS
index 4afae9d..8699f00 100644 (file)
@@ -2,8 +2,12 @@ package SL::Controller::Helper::Sorted;
 
 use strict;
 
+use Carp;
+use List::MoreUtils qw(uniq);
+
 use Exporter qw(import);
-our @EXPORT = qw(make_sorted get_sort_spec get_current_sort_params _save_current_sort_params _get_models_handler_for_sorted _callback_handler_for_sorted);
+our @EXPORT = qw(make_sorted get_sort_spec get_current_sort_params set_report_generator_sort_options
+                 _save_current_sort_params _get_models_handler_for_sorted _callback_handler_for_sorted);
 
 use constant PRIV => '__sortedhelperpriv';
 
@@ -12,7 +16,7 @@ my $controller_sort_spec;
 sub make_sorted {
   my ($class, %specs) = @_;
 
-  $specs{MODEL} ||=  $class->_controller_name;
+  $specs{MODEL} ||=  $class->controller_name;
   $specs{MODEL}   =~ s{ ^ SL::DB:: (?: .* :: )? }{}x;
 
   while (my ($column, $spec) = each %specs) {
@@ -72,6 +76,30 @@ sub get_current_sort_params {
   return %sort_params;
 }
 
+sub set_report_generator_sort_options {
+  my ($self, %params) = @_;
+
+  $params{$_} or croak("Missing parameter '$_'") for qw(report sortable_columns);
+
+  my %current_sort_params = $self->get_current_sort_params;
+
+  foreach my $col (@{ $params{sortable_columns} }) {
+    $params{report}->{columns}->{$col}->{link} = $self->get_callback(
+      sort_by  => $col,
+      sort_dir => ($current_sort_params{by} eq $col ? 1 - $current_sort_params{dir} : $current_sort_params{dir}),
+    );
+  }
+
+  $params{report}->set_sort_indicator($current_sort_params{by}, 1 - $current_sort_params{dir});
+
+  if ($params{report}->{export}) {
+    $params{report}->{export}->{variable_list} = [ uniq(
+      @{ $params{report}->{export}->{variable_list} },
+      @{ $self->get_sort_spec->{FORM_PARAMS} }
+    )];
+  }
+}
+
 #
 # private functions
 #
@@ -277,6 +305,9 @@ Required. A user-displayable title to be used by functions like the
 layout helper's C<sortable_table_header>. Does not have a default
 value.
 
+Note that this string must be the untranslated English version of the
+string. The titles will be translated whenever they're requested.
+
 =item * C<model>
 
 Optional. The name of a Rose database model this sort index refers
@@ -317,6 +348,31 @@ Returns a hash reference to the sort spec structure given in the call
 to L<make_sorted> after normalization (hash reference construction,
 applying default parameters etc).
 
+=item C<set_report_generator_sort_options %params>
+
+This function does three things with an instance of
+L<SL::ReportGenerator>:
+
+=over 4
+
+=item 1. it sets the sort indicator,
+
+=item 2. it sets the the links for those column headers that are
+sortable and
+
+=item 3. it adds the C<FORM_PARAMS> fields to the list of variables in
+the report generator's export options.
+
+=back
+
+The report generator instance must be passed as the parameter
+C<report>. The parameter C<sortable_columns> must be an array
+reference of column names that are sortable.
+
+The report generator instance must already have its columns and export
+options set via calls to its L<SL::ReportGenerator::set_columns> and
+L<SL::ReportGenerator::set_export_options> functions.
+
 =back
 
 =head1 BUGS
index c341130..c5ac88a 100644 (file)
@@ -600,7 +600,7 @@ sub sortable_table_header {
   my $by_spec             = $sort_spec->{$by};
   my %current_sort_params = $controller->get_current_sort_params;
   my ($image, $new_dir)   = ('', $current_sort_params{dir});
-  my $title               = delete($params{title}) || $by_spec->{title};
+  my $title               = delete($params{title}) || $::locale->text($by_spec->{title});
 
   if ($current_sort_params{by} eq $by) {
     my $current_dir = $current_sort_params{dir} ? 'up' : 'down';
index 1843c05..79e1523 100644 (file)
@@ -1,4 +1,2 @@
-[% SET report_bottom_url_args = {} %]
-[%     report_bottom_url_args.import(SELF.flat_filter) %]
-[%     report_bottom_url_args.import({action='list', sort_dir=SELF.sort_dir, sort_by=SELF.sort_by}) %]
-[% PROCESS 'common/paginate.html' pages=SELF.pages, base_url=SELF.url_for(report_bottom_url_args) %]
+[% USE L %]
+[%- L.paginate_controls %]