<chapter id="customer">
<title>Customer</title>
<para>
OTRS is able to deal with various pieces of customer information (i.e. login, email, phone).
This information can be shown in the Agent-Interface and can be used for the
Customer-Interface (users and auth).
</para>

<section id="customer-howto">
<title>How it works</title>
<para>
The used/shown customer information is freely configurable (see backend), 
but there are three required options: UserLogin, UserEmail and
UserCustomerID.
</para>
<section>
<title>Agent-Interface</title>
<para>
If you want to show the customer user information (e. g. company, 
name, email, ...) in your Agent-Interface use the following config 
options.
<programlisting>
    [Kernel/Config.pm]
    # ShowCustomerInfo*
    # (show customer user info on Compose (Phone and Email), Zoom and Queue view)
    $Self->{ShowCustomerInfoCompose} = 1;
    $Self->{ShowCustomerInfoZoom} = 1;
    $Self->{ShowCustomerInfoQueue} = 0;
    [...]
</programlisting>
</para>
</section>
<section>
<title>Admin-Interface</title>
<para>
Edit your customer user information via the Admin-Interface 
(http://yourhost/otrs/index.pl?Action=AdminCustomerUser).
</para>
</section>
<section>
<title>Customer-Interface</title>
<para>
The customer information for the Customer-Interface (http://yourhost/otrs/customer.pl) 
is used for the login and auth. 
</para>
</section>
</section>

<section id="customer-user-backend">
<title>Customer User Backend</title>
<para>
There are two existing customer user backends, DB and LDAP. Of course if 
you have an existing customer repository (e. g. SAP, ...) it's possible
to write an own backend.
</para>
<para>
Note: It's also possible to define more the one "CustomerUser" config option.
You just need to add a number between 1 and 10. For example "CustomerUser1".
</para>
<section>
<title>Database (default)</title>
<para>
This is an example for a database backend. 
</para>
<para>
<programlisting>
    [Kernel/Config.pm]
    # CustomerUser 
    # (customer user database backend and settings)
    $Self->{CustomerUser} = {
        Name => 'Database Source',
        Module => 'Kernel::System::CustomerUser::DB',
        Params => {
            # if you want to use an external database, add the
            # required settings 
#            DSN => 'DBI:odbc:yourdsn',
#            DSN => 'DBI:mysql:database=customerdb;host=customerdbhost',
#            User => '',
#            Password => '',
            Table => 'customer_user',
        },
        # customer uniq id
        CustomerKey => 'login',
        # customer #
        CustomerID => 'customer_id',
        CustomerValid => 'valid_id',
        CustomerUserListFields => ['login', 'first_name', 'last_name', 'email'],
        CustomerUserSearchFields => ['login', 'last_name', 'customer_id'],
        CustomerUserSearchPrefix => '',
        CustomerUserSearchSuffix => '*',
        CustomerUserPostMasterSearchFields => ['email'],
        CustomerUserNameFields => ['salutation', 'first_name', 'last_name'],
#        AdminSetPreferences => 1,
#        ReadOnly => 1,
        Map => [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserSalutation', 'Salutation', 'salutation', 1, 0, 'var' ],
            [ 'UserFirstname', 'Firstname', 'first_name', 1, 1, 'var' ],
            [ 'UserLastname', 'Lastname', 'last_name', 1, 1, 'var' ],
            [ 'UserLogin', 'Username', 'login', 1, 1, 'var' ],
            [ 'UserPassword', 'Password', 'pw', 0, 1, 'var' ],
            [ 'UserEmail', 'Email', 'email', 0, 1, 'var' ],
#            [ 'UserEmail', 'Email', 'email', 1, 1, 'var', '$Env{"CGIHandle"}?Action=\
AgentCompose&amp;ResponseID=1&amp;TicketID=$Data{"TicketID"}&amp;ArticleID=$Data{"ArticleID"}' ],
            [ 'UserCustomerID', 'CustomerID', 'customer_id', 0, 1, 'var' ],
            [ 'UserComment', 'Comment', 'comment', 1, 0, 'var' ],
            [ 'ValidID', 'Valid', 'valid_id', 0, 1, 'int' ],
        ],
    };
    [...]
</programlisting>
</para>
<para>
If you want to customize your customer user information, change (add) you table
columns e. g.
<programlisting>
ALTER TABLE customer_user ADD phone VARCHAR (250);
</programlisting>
And add your new column to your CustomerUser MAP array in Kernel/Config.pm like:
<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserPhone', 'Phone', 'phone', 1, 0, 'var' ],
</programlisting>
Of course you will be able to maintain all this customer user information via 
the Admin-Interface. 
</para>
<para>
MultiCustomerIDs: It's also possible to have more the one customer id for one customer.
E. g. one customer needs to see all ticket from other customers.
</para>
<para>
Add a new database row and put the customer ids in it (like "CustomerID1, CustomerID2, CustomerID3").
</para>
<para>
<programlisting>
ALTER TABLE customer_user ADD customer_ids VARCHAR (250);
</programlisting>
And add your new column to your CustomerUser MAP array in Kernel/Config.pm like:
<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserCustomerIDs', 'CustomerIDs', 'customer_ids', 1, 0, 'var' ],
</programlisting>
Of course you will be able to maintain all this customer user information via
the Admin-Interface.
</para>
</section>
<section>
<title>LDAP</title>
<para>
If you have an existing LDAP tree with your customer users then you will be
able to use this LDAP tree in your OTRS system.
</para>
<para>
This is an example for a LDAP backend. 
<programlisting>
    [Kernel/Config.pm]
    # CustomerUser 
    # (customer user ldap backend and settings)
    $Self->{CustomerUser} = {
        Name => 'LDAP Source',
        Module => 'Kernel::System::CustomerUser::LDAP',
        Params => {
            # ldap host
            Host => 'bay.csuhayward.edu',
            # ldap base dn
            BaseDN => 'ou=seas,o=csuh',
            # search scope (one|sub)
            SSCOPE => 'sub',
            # The following is valid but would only be necessary if the
            # anonymous user does NOT have permission to read from the LDAP tree 
            UserDN => '',
            UserPw => '',
            # in case you want to add always one filter to each ldap query, use
            # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
            AlwaysFilter => '',
            # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
            Params => {
                port => 389,
                version => 3,
            },
        }, 
        # customer uniq id
        CustomerKey => 'uid',
        # customer #
        CustomerID => 'mail',
        CustomerUserListFields => ['uid', 'cn', 'mail'],
        CustomerUserSearchFields => ['uid', 'cn', 'mail'],
        CustomerUserSearchPrefix => '',
        CustomerUserSearchSuffix => '*',
        CustomerUserPostMasterSearchFields => ['mail'],
        CustomerUserNameFields => ['givenname', 'sn'],
        AdminSetPreferences => 0,
        Map => [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown, required, storage-type
            [ 'UserSalutation', 'Title', 'title', 1, 0, 'var' ],
            [ 'UserFirstname', 'Firstname', 'givenname', 1, 1, 'var' ], 
            [ 'UserLastname', 'Lastname', 'sn', 1, 1, 'var' ],
            [ 'UserLogin', 'Username', 'uid', 1, 1, 'var' ],
            [ 'UserEmail', 'Email', 'mail', 1, 1, 'var' ],
            [ 'UserCustomerID', 'CustomerID', 'mail', 0, 1, 'var' ],
            [ 'UserPhone', 'Phone', 'telephonenumber', 1, 0, 'var' ],
            [ 'UserAddress', 'Address', 'postaladdress', 1, 0, 'var' ],
            [ 'UserComment', 'Comment', 'description', 1, 0, 'var' ],
        ],
    };
    [...]
</programlisting>
</para>
<para>
If you want to customize your customer user information, add
your new item (or remove it if not needed) to your CustomerUser MAP array in Kernel/Config.pm like:
<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserOrganisation', 'Organisation', 'ou', 1, 0, 'var' ],
</programlisting>
</para>
<para>
MultiCustomerIDs: It's also possible to have more the one customer id for one customer.
E. g. one customer needs to see all ticket from other customers.
</para>
<para>
Just find a field for the customer ids in your ldap tree and put the customer ids in it (like &quot;CustomerID1, CustomerID2, CustomerID3&quot;).
</para>
<para>
And add your new column to your CustomerUser MAP array in Kernel/Config.pm like:
<programlisting>
            # var, frontend, storage, shown, required, storage-type, http-link
            [ 'UserCustomerIDs', 'CustomerIDs', 'second_customer_ids', 1, 0, 'var' ],
</programlisting>
Of course you will need to put the customer ids in it by your ldap admin.
</para>
</section>
</section>

<section id="customer-auth-backend">
<title>Customer Auth Backend</title>
<section>
<title>Database (default)</title>
<para>
The default customer auth backend is the otrs database with your customer
user which are created via the Admin-Interface or Customer-Interface (Create Account).
<programlisting>
    [Kernel/Config.pm]
    # This is the auth. module againt the otrs db
    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::DB';
    [...]
</programlisting>
</para>
</section>
<section>
<title>LDAP</title>
<para>
If there is a LDAP tree available with your customer users then you can
use the customer LDAP auth backend. This module is just read only (
means it can't write to your LDAP tree - this should just be possibe for 
your tree manager) so you can't create customer user via the Admin- or Customer-Interface.
<programlisting>
    [Kernel/Config.pm]
    # This is an example configuration for an LDAP auth. backend.
    # (take care that Net::LDAP is installed!)
    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::LDAP';
    $Self->{'Customer::AuthModule::LDAP::Host'} = 'ldap.example.com';
    $Self->{'Customer::AuthModule::LDAP::BaseDN'} = 'dc=example,dc=com';
    $Self->{'Customer::AuthModule::LDAP::UID'} = 'uid';

    # Check if the user is allowed to auth in a posixGroup
    # (e. g. user needs to be in a group xyz to use otrs)
#    $Self->{'Customer::AuthModule::LDAP::GroupDN'} = 'cn=otrsallow,ou=posixGroups,dc=example,dc=com';
#    $Self->{'Customer::AuthModule::LDAP::AccessAttr'} = 'memberUid';

    # The following is valid but would only be necessary if the
    # anonymous user do NOT have permission to read from the LDAP tree 
    $Self->{'Customer::AuthModule::LDAP::SearchUserDN'} = '';
    $Self->{'Customer::AuthModule::LDAP::SearchUserPw'} = '';

    # in case you want to add always one filter to each ldap query, use
    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
#   $Self->{'Customer::AuthModule::LDAP::AlwaysFilter'} = '';

    # in case you want to add a suffix to each customer login name, then
    # you can use this option. e. g. user just want to use user but
    # in your ldap directory exists user@domain.
#    $Self->{'Customer::AuthModule::LDAP::UserSuffix'} = '@domain.com';

    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
#    $Self->{'Customer::AuthModule::LDAP::Params'} = {
#        port => 389,
#        version => 3,
#    };
    [...]
</programlisting>
</para>
</section>

<section>
<title>HTTPBasicAuth</title>
<para>
If you a "single sign on" solution for your customers, use http basic authentication (for all
your systems) and use the HTTPBasicAuth module (no otrs login is required!).
<programlisting>
    [Kernel/Config.pm]
    # This is the auth. module againt $ENV{REMOTE_USER} (apache
    # http-basic-auth)
    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::HTTPBasicAuth';
    # Note:
    # If you use this module, you should use as fallback the following
    # config settings if user isn't login through apache ($ENV{REMOTE_USER})
    $Self->{CustomerPanelLoginURL} = 'http://host/not-authorised-for-otrs.html';
    $Self->{CustomerPanelLogoutURL} = 'http://host/thanks-for-using-otrs.html';
    [...]
</programlisting>
</para>
</section>

<section>
<title>Radius</title>
<para>
Authentication against a radius server.
<programlisting>
    [Kernel/Config.pm]
    # This is example configuration to auth. agents against a radius server
    $Self->{'Customer::AuthModule'} = 'Kernel::System::Auth::Radius';
    $Self->{'Customer::AuthModule::Radius::Host'} = 'radiushost';
    $Self->{'Customer::AuthModule::Radius::Password'} = 'radiussecret';
    [...]
</programlisting>
</para>
</section>


</section>

<section id="customer-self-registration">
<title>Customize Customer Self Registration</title>
<para>
It's possible to customize the self registration of new customers 
via the customer.pl. So you can add more optional or required fields
(like address, location, ...).
</para>
<para>
In our example we want to add a required "address" field.
</para>
<section>
<title>Template</title>
<para>
Edit your "Kernel/Output/HTML/Standard/CustomerCreateAccount.dtl" and add
your wanted fields. We want an "address" field, so add:
<programlisting>
    [...]
    &lt;tr>
      &lt;td>$Text{"Address"}: &lt;/td>
      &lt;td> &lt;input type="text" name="Address" value="$Data{"UserAddress"}" size="35" maxlength="50">&lt;/td>
    &lt;/tr>
    [...]
</programlisting>
</para>
</section>
<section>
<title>Customer Map</title>
<para>
You need also to add an "address" entry to you customer source map so add to
your Kernel/Config.pm the "CustomerUser" (customer source map) from 
Kernel/Config/Defaults.pm and add the "address" option. Then the "CustomerUser" 
config option should look like that:
</para>
<programlisting>
    [Kernel/Config.pm]
    $Self->{CustomerUser} = {
        Name => 'Intenal Customers',
        Module => 'Kernel::System::CustomerUser::DB',
        Params => {
            Table => 'customer_user',
        },
        Map => [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown, required, storage-type, link
            [ 'UserSalutation', 'Salutation', 'salutation', 1, 0, 'var' ],
            [ 'UserFirstname', 'Firstname', 'first_name', 1, 1, 'var' ],
            [ 'UserLastname', 'Lastname', 'last_name', 1, 1, 'var' ],
            # our new option
            [ 'UserAddress', 'Address', 'address', 1, 1, 'var' ],
            [ 'UserLogin', 'Username', 'login', 1, 1, 'var' ],
            [ 'UserPassword', 'Password', 'pw', 0, 1, 'var' ],
            [ 'UserEmail', 'Email', 'email', 1, 1, 'var' ],
            [ 'UserCustomerID', 'CustomerID', 'customer_id', 1, 1, 'var' ],
            [ 'UserComment', 'Phone', 'comment', 1, 0, 'var' ],
            [ 'ValidID', 'Valid', 'valid_id', 0, 1, 'int' ],
        ],
        Key => 'login',
        CustomerID => 'customer_id',
    };
    [...]
</programlisting>
</section>
<section>
<title>Modify Customer Table</title>
<para>
We also need to add a new column to our "customer_user" table. 
<programlisting>
mysql> ALTER TABLE customer_user ADD address VARCHAR (200);
Query OK, 0 rows affected (0.21 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 
</programlisting>
That's all, restart your webserver (if you use mod_perl), go to your 
http://otrs.example.com/otrs/customer.pl page and test it.
</para>
</section>
</section>

</chapter>
