commit 07df127795326eaf9234b3f524ddd49aa2a3dfd0
Author: Bernd Bleßmann <bernd@kivitendo-premium.de>
Date:   Fri Jan 25 12:45:27 2019 +0100

    DisplayableNamePrefs: DB-Helper als Mixin

diff --git a/SL/DB/Helper/DisplayableNamePreferences.pm b/SL/DB/Helper/DisplayableNamePreferences.pm
new file mode 100644
index 000000000..5080ea245
--- /dev/null
+++ b/SL/DB/Helper/DisplayableNamePreferences.pm
@@ -0,0 +1,162 @@
+package SL::DB::Helper::DisplayableNamePreferences;
+
+use strict;
+
+use parent qw(Exporter);
+our @EXPORT = qw(displayable_name displayable_name_prefs displayable_name_specs specify_displayable_name_prefs);
+
+use Carp;
+use List::MoreUtils qw(none);
+
+use SL::Helper::UserPreferences::DisplayableName;
+
+
+my %prefs_specs;
+my %prefs;
+
+sub import {
+  my ($class, %params) = @_;
+  my $importing = caller();
+
+  $params{title} && $params{options}  or croak 'need params title and options';
+
+  $prefs_specs{$importing} = \%params;
+  $prefs{$importing}       = SL::Helper::UserPreferences::DisplayableName->new(
+    module => $importing
+  );
+
+  # Don't 'goto' to Exporters import, it would try to parse @params
+  __PACKAGE__->export_to_level(1, $class, @EXPORT);
+}
+
+sub displayable_name {
+  my ($self) = @_;
+
+  my $specs = $self->displayable_name_specs;
+  my $prefs = $self->displayable_name_prefs;
+
+  my @names = $prefs->get =~ m{<\%(.+?)\%>}g;
+  my $display_string = $prefs->get;
+  foreach my $name (@names) {
+    next if none {$name eq $_->{name}} @{$specs->{options}};
+    my $val         = $self->can($name) ? $self->$name // '' : '';
+    $display_string =~ s{<\%$name\%>}{$val}g;
+  }
+
+  return $display_string;
+}
+
+sub displayable_name_prefs {
+  my $class_or_self = shift;
+  my $class         = ref($class_or_self) || $class_or_self;
+
+  return $prefs{$class};
+}
+
+sub displayable_name_specs {
+  my $class_or_self = shift;
+  my $class         = ref($class_or_self) || $class_or_self;
+
+  return $prefs_specs{$class};
+}
+
+1;
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+SL::DB::Helper::DisplayableNamePreferences - Mixin for managing displayable
+names configured via user preferences
+
+=head1 SYNOPSIS
+
+  # DB object
+  package SL::DB::SomeObject;
+  use SL::DB::Helper::DisplayableNamePreferences(
+    title   => t8('Some Object'),
+    options => [ {name => 'some_attribute_1', title => t8('Some Attribute One') },
+                 {name => 'some_attribute_2,  title => t8('Some Attribute Two') },
+
+  );
+
+  # Controller using displayable_name
+  package SL::Controller::SomeController;
+  $obj       = SL::DB::SomeObject->get_first;
+  my $output = $obj->displayable_name;
+
+  # Controller configuring a displayable name
+  # can get specs to display title and options
+  # and the user prefs to read and set them
+  my specs => SL::DB::SomeObject->displayable_name_specs;
+  my prefs => SL::DB::SomeObject->displayable_name_prefs;
+
+
+This mixin provides a method C<displayable_name> for the calling module
+which returns the a string depending on the settings of the
+C<UserPreferences> (see also L<SL::Helper::UserPrefernces::DisplayableName>.
+The value in the user preferences is scanned for a pattern like E<lt>%name%E<gt>, which
+will be replaced by the value of C<$object-E<gt>name>.
+
+=head1 CONFIGURATION
+
+The mixin must be configured on import giving a hash with the following keys
+in the C<use> statement. This is stored in the specs an can be used
+in a controller setting the preferences to display them.
+
+=over 4
+
+=item C<title>
+
+The (translated) title of the object.
+
+=item C<options>
+
+The C<options> are an array ref of hash refs with the keys C<name> and C<title>.
+The C<name> is the method called to get the needed information from the object
+for which the displayable name is configured. The C<title> can be used to
+display a (translated) text in a controller setting the preferences.
+
+=back
+
+=head1 CLASS FUNCTIONS
+
+=over 4
+
+=item C<displayable_name_specs>
+
+Returns the specification given on importing this helper. This can be used
+in a controller setting the preferences to display the information to the
+user.
+
+=item C<displayable_name_prefs>
+
+This returns an instance of the L<SL::Helper::UserPrefernces::DisplayableName>
+(see there) for the calling class. This can be used to read and set the
+preferences.
+
+=back
+
+=head1 INSTANCE FUNCTIONS
+
+=over 4
+
+=item C<displayable_name>
+
+Displays the name of the object depending on the settings in the
+user preferences.
+
+=back
+
+=head1 BUGS
+
+Nothing here yet.
+
+=head1 AUTHOR
+
+Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
+
+=cut
