Merge branch 'b-3.6.1' of ../kivitendo-erp_20220811
[kivitendo-erp.git] / SL / DB / Helper / Sorted.pm
index 00eedb9..c536ccd 100644 (file)
@@ -16,7 +16,7 @@ sub make_sort_string {
   my $sort_dir         = defined($params{sort_dir}) ? $params{sort_dir} * 1 : $sort_spec->{default}->[1];
   my $sort_dir_str     = $sort_dir ? 'ASC' : 'DESC';
 
-  my $sort_by          = $params{sort_by};
+  my $sort_by          = $params{sort_by} || { };
   $sort_by             = $sort_spec->{default}->[0] unless $sort_spec->{columns}->{$sort_by};
 
   my $nulls_str        = '';
@@ -27,6 +27,10 @@ sub make_sort_string {
 
   my $sort_by_str = $sort_spec->{columns}->{$sort_by};
   $sort_by_str    = [ $sort_by_str ] unless ref($sort_by_str) eq 'ARRAY';
+
+  # generate tiebreaker
+  push @$sort_by_str, @{ $sort_spec->{tiebreaker} };
+
   $sort_by_str    = join(', ', map { "${_} ${sort_dir_str}${nulls_str}" } @{ $sort_by_str });
 
   return wantarray ? ($sort_by, $sort_dir, $sort_by_str) : $sort_by_str;
@@ -50,6 +54,7 @@ sub _make_sort_spec {
   my %sort_spec = defined &{ "${class}::_sort_spec" } ? $class->_sort_spec : ();
 
   my $meta = $class->object_class->meta;
+  my $table = $meta->table;
 
   if (!$sort_spec{default}) {
     my @primary_keys = $meta->primary_key;
@@ -59,8 +64,6 @@ sub _make_sort_spec {
   $sort_spec{columns} ||= { SIMPLE => [ map { "$_" } $meta->columns ] };
 
   if ($sort_spec{columns}->{SIMPLE}) {
-    my $table = $meta->table;
-
     if (!ref($sort_spec{columns}->{SIMPLE}) && ($sort_spec{columns}->{SIMPLE} eq 'ALL')) {
       map { $sort_spec{columns}->{"$_"} ||= "${table}.${_}"} @{ $meta->columns };
       delete $sort_spec{columns}->{SIMPLE};
@@ -69,6 +72,8 @@ sub _make_sort_spec {
     }
   }
 
+  $sort_spec{tiebreaker} ||= [ map { "${table}.${_}" } $meta->primary_key ];
+
   return \%sort_spec;
 }
 
@@ -211,6 +216,15 @@ Example:
              default                 => 'LAST',
            },
 
+=item C<tiebreaker>
+
+Optional tiebreaker sorting that gets appended to any user requested sorting.
+Needed to make sorting by non unique columns deterministic.
+
+If present must be an arrayref of column sort specs (see C<column>).
+
+Defaults to primary keys.
+
 =back
 
 =back