Suche nach Ansprechpartnern
authorSven Schöling <s.schoeling@linet-services.de>
Fri, 20 Apr 2012 14:03:07 +0000 (16:03 +0200)
committerSven Schöling <s.schoeling@linet-services.de>
Fri, 20 Apr 2012 14:03:07 +0000 (16:03 +0200)
Merge aus zwei verschiedenen Implementierungen der gleichen Funktionalität

Features:
- behandelt Ansprechparter als direkte Suchziele wie Kunden und Lieferanten (1)
- Suche ähnlich den bekannten Suchmasken (1)
- Suche nach direktem Suchwort (2)
- Verlinkung einer Schnellsuche in der menunew header Leiste (2)

SL/CT.pm
bin/mozilla/ct.pl
locale/de/all
menu.ini
templates/webpages/ct/search_contact.html [new file with mode: 0644]
templates/webpages/menu/menuv3.html

index 6dbbec5..2e8a017 100644 (file)
--- a/SL/CT.pm
+++ b/SL/CT.pm
@@ -1207,4 +1207,82 @@ sub parse_excel_file {
   $main::lxdebug->leave_sub();
 }
 
+sub search_contacts {
+  $::lxdebug->enter_sub;
+
+  my $self      = shift;
+  my %params    = @_;
+
+  my $dbh       = $params{dbh} || $::form->get_standard_dbh;
+  my $vc        = $params{db} eq 'customer' ? 'customer' : 'vendor';
+
+  my %sortspecs = (
+    'cp_name'   => 'cp_name, cp_givenname',
+    'vcname'    => 'vcname, cp_name, cp_givenname',
+    'vcnumber'  => 'vcnumber, cp_name, cp_givenname',
+    );
+
+  my %sortcols  = map { $_ => 1 } qw(cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email vcname vcnumber);
+
+  my $order_by  = $sortcols{$::form->{sort}} ? $::form->{sort} : 'cp_name';
+  $::form->{sort} = $order_by;
+  $order_by     = $sortspecs{$order_by} if ($sortspecs{$order_by});
+
+  my $sortdir   = $::form->{sortdir} ? 'ASC' : 'DESC';
+  $order_by     =~ s/,/ ${sortdir},/g;
+  $order_by    .= " $sortdir";
+
+  my @where_tokens = ();
+  my @values;
+
+  if ($params{search_term}) {
+    my @tokens;
+    push @tokens,
+      'cp.cp_name      ILIKE ?',
+      'cp.cp_givenname ILIKE ?',
+      'cp.cp_email     ILIKE ?';
+    push @values, ('%' . $params{search_term} . '%') x 3;
+
+    if (($params{search_term} =~ m/\d/) && ($params{search_term} !~ m/[^\d \(\)+\-]/)) {
+      my $number =  $params{search_term};
+      $number    =~ s/[^\d]//g;
+      $number    =  join '[ /\(\)+\-]*', split(m//, $number);
+
+      push @tokens, map { "($_ ~ '$number')" } qw(cp_phone1 cp_phone2 cp_mobile1 cp_mobile2);
+    }
+
+    push @where_tokens, map { "($_)" } join ' OR ', @tokens;
+  }
+
+  if (my $filter = $params{filter}) {
+    for (qw(name title givenname email project abteilung)) {
+      next unless $filter->{"cp_$_"};
+      add_token(\@where_tokens, \@values, col =>  "cp.cp_$_", val => $filter->{"cp_$_"}, method => 'ILIKE', esc => 'substr');
+    }
+
+    push @where_tokens, 'cp.cp_cv_id IS NOT NULL' if $filter->{status} eq 'active';
+    push @where_tokens, 'cp.cp_cv_id IS NULL'     if $filter->{status} eq 'orphaned';
+  }
+
+  my $where = @where_tokens ? 'WHERE ' . join ' AND ', @where_tokens : '';
+
+  my $query     = qq|SELECT cp.*,
+                       COALESCE(c.id,             v.id)           AS vcid,
+                       COALESCE(c.name,           v.name)         AS vcname,
+                       COALESCE(c.customernumber, v.vendornumber) AS vcnumber,
+                       CASE WHEN c.name IS NULL THEN 'vendor' ELSE 'customer' END AS db
+                     FROM contacts cp
+                     LEFT JOIN customer c ON (cp.cp_cv_id = c.id)
+                     LEFT JOIN vendor v   ON (cp.cp_cv_id = v.id)
+                     $where
+                     ORDER BY $order_by|;
+
+  my $contacts  = selectall_hashref_query($::form, $dbh, $query, @values);
+
+  $::lxdebug->leave_sub;
+
+  return @{ $contacts };
+}
+
+
 1;
index dbf8cdd..32fe324 100644 (file)
@@ -49,6 +49,7 @@ use POSIX qw(strftime);
 
 use SL::CT;
 use SL::CVar;
+use SL::Request qw(flatten);
 use SL::DB::Business;
 use SL::DB::Default;
 use SL::Helper::Flash;
@@ -110,6 +111,18 @@ sub search {
   $main::lxdebug->leave_sub();
 }
 
+sub search_contact {
+  $::lxdebug->enter_sub;
+  $::auth->assert('customer_vendor_edit');
+
+  $::form->{fokus}    = 'Form.name';
+
+  $::form->header;
+  print $::form->parse_html_template('ct/search_contact');
+
+  $::lxdebug->leave_sub;
+}
+
 sub list_names {
   $main::lxdebug->enter_sub();
 
@@ -268,6 +281,93 @@ sub list_names {
   $main::lxdebug->leave_sub();
 }
 
+sub list_contacts {
+  $::lxdebug->enter_sub;
+  $::auth->assert('customer_vendor_edit');
+
+  $::form->{sortdir} = 1 unless defined $::form->{sortdir};
+
+  my @contacts     = CT->search_contacts(
+    search_term => $::form->{search_term},
+    filter      => $::form->{filter},
+  );
+
+  my @columns      = qw(
+    cp_id vcname vcnumber cp_name cp_givenname cp_street cp_phone1 cp_phone2
+    cp_mobile1 cp_mobile2 cp_email cp_abteilung cp_birthday cp_gender
+  );
+
+  my @visible_columns;
+  if ($::form->{l}) {
+    @visible_columns = grep { $::form->{l}{$_} } @columns;
+    push @visible_columns, qw(cp_phone1 cp_phone2)   if $::form->{l}{cp_phone};
+    push @visible_columns, qw(cp_mobile1 cp_mobile2) if $::form->{l}{cp_mobile};
+  } else {
+   @visible_columns = qw(vcname vcnumber cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email);
+  }
+
+  my %column_defs  = (
+    'cp_id'        => { 'text' => $::locale->text('ID'), },
+    'vcname'       => { 'text' => $::locale->text('Customer/Vendor'), },
+    'vcnumber'     => { 'text' => $::locale->text('Customer/Vendor Number'), },
+    'cp_name'      => { 'text' => $::locale->text('Name'), },
+    'cp_givenname' => { 'text' => $::locale->text('Given Name'), },
+    'cp_street'    => { 'text' => $::locale->text('Street'), },
+    'cp_phone1'    => { 'text' => $::locale->text('Phone1'), },
+    'cp_phone2'    => { 'text' => $::locale->text('Phone2'), },
+    'cp_mobile1'   => { 'text' => $::locale->text('Mobile 1'), },
+    'cp_mobile2'   => { 'text' => $::locale->text('Mobile 2'), },
+    'cp_email'     => { 'text' => $::locale->text('E-mail'), },
+    'cp_abteilung' => { 'text' => $::locale->text('Department'), },
+    'cp_birthday'  => { 'text' => $::locale->text('Birthday'), },
+    'cp_gender'    => { 'text' => $::locale->text('Gender'), },
+  );
+
+  map { $column_defs{$_}->{visible} = 1 } @visible_columns;
+
+  my @hidden_variables  = (qw(search_term filter l));
+  my $hide_vars         = { map { $_ => $::form->{$_} } @hidden_variables };
+  my @hidden_nondefault = grep({ $::form->{$_} } @hidden_variables);
+  my $callback          = build_std_url('action=list_contacts', join '&', map { E($_->[0]) . '=' . E($_->[1]) } @{ flatten($hide_vars) });
+  $::form->{callback}     = "$callback&sort=" . E($::form->{sort});
+
+  map { $column_defs{$_}->{link} = "${callback}&sort=${_}&sortdir=" . ($::form->{sort} eq $_ ? 1 - $::form->{sortdir} : $::form->{sortdir}) } @columns;
+
+  $::form->{title} = $::locale->text('Contacts');
+
+  my $report     = SL::ReportGenerator->new(\%::myconfig, $::form);
+
+  my @options    = $::locale->text('Search term') . ': ' . $::form->{search_term};
+
+  $report->set_options('top_info_text'       => join("\n", @options),
+                       'output_format'       => 'HTML',
+                       'title'               => $::form->{title},
+                       'attachment_basename' => $::locale->text('contact_list') . strftime('_%Y%m%d', localtime time),
+    );
+  $report->set_options_from_form;
+
+  $report->set_columns(%column_defs);
+  $report->set_column_order(@columns);
+
+  $report->set_export_options('list_contacts', @hidden_variables);
+
+  $report->set_sort_indicator($::form->{sort}, $::form->{sortdir});
+
+  foreach my $ref (@contacts) {
+    my $row = { map { $_ => { 'data' => $ref->{$_} } } @columns };
+
+    $row->{vcname}->{link}   = build_std_url('action=edit', 'id=' . E($ref->{vcid}), 'db=' . E($ref->{db}), 'callback', @hidden_nondefault);
+    $row->{vcnumber}->{link} = $row->{vcname}->{link};
+    $row->{cp_email}->{link} = 'mailto:' . E($ref->{cp_email});
+
+    $report->add_data($row);
+  }
+
+  $report->generate_with_headers;
+
+  $::lxdebug->leave_sub;
+}
+
 sub edit {
   $main::lxdebug->enter_sub();
 
index 1e9b423..9e59551 100644 (file)
@@ -512,6 +512,8 @@ $self->{texts} = {
   'Customer type'               => 'Kundentyp',
   'Customer/Vendor'             => 'Kunde/Lieferant',
   'Customer/Vendor (database ID)' => 'Kunde/Lieferant (Datenbank-ID)',
+  'Customer/Vendor Name'        => 'Kunde/Lieferant',
+  'Customer/Vendor Number'      => 'Kundennummer/Lieferantennummer',
   'Customername'                => 'Kundenname',
   'Customernumberinit'          => 'Kunden-/Lieferantennummernkreis',
   'Customers'                   => 'Kunden',
@@ -1091,7 +1093,6 @@ $self->{texts} = {
   'Logout now'                  => 'Lx-Office jetzt verlassen',
   'Long Dates'                  => 'Lange Monatsnamen',
   'Long Description'            => 'Langtext',
-  'Lx-Office'                   => 'Lx-Office',
   'MAILED'                      => 'Gesendet',
   'MSG_BROWSER_DOES_NOT_SUPPORT_IFRAMES' => 'Ihr Browser kann leider keine eingebetteten Frames anzeigen. Bitte w&auml;hlen Sie ein anderes Men&uuml; in der Benutzerkonfiguration im Administrationsmen&uuml; aus.',
   'Main Preferences'            => 'Grundeinstellungen',
@@ -1138,6 +1139,9 @@ $self->{texts} = {
   'Missing user id!'            => 'Benutzer ID fehlt!',
   'Mitarbeiter'                 => 'Mitarbeiter',
   'Mixed (requires column "type")' => 'Gemischt (erfordert Spalte "type")',
+  'Mobile'                      => 'Mobiltelefon',
+  'Mobile 1'                    => '',
+  'Mobile 2'                    => '',
   'Mobile1'                     => 'Mobile 1',
   'Mobile2'                     => 'Mobile 2',
   'Model'                       => 'Lieferanten-Art-Nr.',
@@ -1576,6 +1580,8 @@ $self->{texts} = {
   'Screen'                      => 'Bildschirm',
   'Search AP Aging'             => 'Offene Verbindlichkeiten',
   'Search AR Aging'             => 'Offene Forderungen',
+  'Search contacts'             => 'Ansprechpartnersuche',
+  'Search term'                 => 'Suchbegriff',
   'Searchable'                  => 'Durchsuchbar',
   'Select'                      => 'auswählen',
   'Select a Customer'           => 'Endkunde auswählen',
@@ -2185,6 +2191,7 @@ $self->{texts} = {
   'config/lx_office.conf: Key "authentication/ldap" is missing.' => 'config/lx_office.conf: Der Schlüssel "authentication/ldap" fehlt.',
   'config/lx_office.conf: Missing parameters in "authentication/database". Required parameters are "host", "db" and "user".' => 'config/lx_office.conf: Fehlende Parameter in "authentication/database". Ben&ouml;tigte Parameter sind "host", "db" und "user".',
   'config/lx_office.conf: Missing parameters in "authentication/ldap". Required parameters are "host", "attribute" and "base_dn".' => 'config/lx_office.conf: Fehlende Parameter in "authentication/ldap". Benötigt werden "host", "attribute" und "base_dn".',
+  'contact_list'                => 'ansprechpartner_liste',
   'continue'                    => 'weiter',
   'correction'                  => 'Korrektur',
   'cp_greeting to cp_gender migration' => 'Datenumwandlung von Titel nach Geschlecht (cp_greeting to cp_gender)',
index 5d39fd6..da54506 100644 (file)
--- a/menu.ini
+++ b/menu.ini
@@ -59,6 +59,12 @@ module=ct.pl
 action=search
 db=vendor
 
+[Master Data--Reports--Contacts]
+ACCESS=customer_vendor_edit
+module=ct.pl
+action=search_contact
+db=customer
+
 [Master Data--Reports--Parts]
 ACCESS=part_service_assembly_edit
 module=ic.pl
diff --git a/templates/webpages/ct/search_contact.html b/templates/webpages/ct/search_contact.html
new file mode 100644 (file)
index 0000000..2fe8bdc
--- /dev/null
@@ -0,0 +1,122 @@
+[%- USE HTML %]
+[%- USE T8 %]
+<body onload="fokus()">
+
+ <form method="post" action="ct.pl" name="Form">
+
+  <input type="hidden" name="db" value="[% db | html %]">
+
+  <div class="listtop">[% 'Contacts' | $T8 %]</div>
+
+  <table>
+   <tr>
+    <th align="right" nowrap>[% 'Name' | $T8 %]</th>
+    <td><input name="filter.cp_name" size="35"></td>
+   </tr>
+   <tr>
+    <th align="right" nowrap>[% 'Greeting' | $T8 %]</th>
+    <td><input name="filter.cp_greeting" size="35"></td>
+   </tr>
+   <tr>
+    <th align="right" nowrap>[% 'Title' | $T8 %]</th>
+    <td><input name="filter.cp_title" size="35"></td>
+   </tr>
+   <tr>
+    <th align="right" nowrap>[% 'E-mail' | $T8 %]</th>
+    <td><input name="filter.cp_email" size="35"></td>
+   </tr>
+   <tr>
+    <th align="right" nowrap>[% 'Department' | $T8 %]</th>
+    <td><input name="filter.cp_abteilung" size="35"></td>
+   </tr>
+   <tr>
+    <th align="right" nowrap>[% 'Project' | $T8 %]</th>
+    <td><input name="filter.cp_project" size="35"></td>
+   </tr>
+
+   <tr>
+    <td></td>
+    <td>
+     <input name="filter.status" class="radio" type="radio" value="active" checked> [% 'Active' | $T8 %]
+     <input name="filter.status" class="radio" type="radio" value="all"> [% 'All' | $T8 %]
+     <input name="filter.status" class="radio" type="radio" value="orphaned"> [% 'Orphaned' | $T8 %]
+    </td>
+   </tr>
+
+   <tr>
+    <th align="right" nowrap>[% 'Include in Report' | $T8 %]</th>
+    <td>
+     <table border="0">
+      <tr>
+       <td>
+        <input name="l.cp_id" id="l_cp_id" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_id">[% 'ID' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.vcnumber" id="l_vcnumber" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_vcnumber">[% 'Customer/Vendor Number' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.vcname" id="l_vcname" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_vcname">[% 'Customer/Vendor Name' | $T8 %]</label>
+       </td>
+      </tr>
+
+      <tr>
+       <td>
+        <input name="l.cp_name" id="l_cp_name" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_cp_name">[% 'Name' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_givenname" id="l_cp_givenname" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_cp_givenname">[% 'Given Name' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_street" id="l_cp_street" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_street">[% 'Street' | $T8 %]</label>
+       </td>
+      </tr>
+      <tr>
+       <td>
+        <input name="l.cp_phone" id="l_cp_phone" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_cp_phone">[% 'Phone' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_mobile" id="l_cp_mobile" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_cp_mobile">[% 'Mobile' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_email" id="l_cp_email" type="checkbox" class="checkbox" value="Y" checked>
+        <label for="l_cp_email">[% 'E-mail' | $T8 %]</label>
+       </td>
+      </tr>
+
+      <tr>
+       <td>
+        <input name="l.cp_birthday" id="l_cp_birthday" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_birthday">[% 'Birthday' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_abteilung" id="l_cp_abteilung" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_abteilung">[% 'Department' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_gender" id="l_cp_gender" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_gender">[% 'Gender' | $T8 %]</label>
+       </td>
+      </tr>
+
+      [% CUSTOM_VARIABLES_INCLUSION_CODE %]
+
+     </table>
+    </td>
+   </tr>
+  </table>
+
+  <input type="hidden" name="nextsub" value="list_contacts">
+
+  <input type="submit" class="submit" name="action" value="[% 'Continue' | $T8 %]">
+ </form>
+
+</body>
+</html>
index e02d273..6faa762 100644 (file)
@@ -1,8 +1,33 @@
 [%- USE T8 %]
 [% USE HTML %]<body style="padding:0px; margin:0px;">
 
+ <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript">
-<!--
+ <!--
+function on_keydown_quicksearch(e) {
+  var key;
+
+  if (window.event)
+    key = window.event.keyCode;   // IE
+  else
+    key = e.which;                // Firefox
+
+  if (key != 13)
+    return true;
+
+  var search_term = $("#search_term");
+  var value       = search_term.val();
+  if (!value)
+    return true;
+
+  var url = "ct.pl?action=list_contacts&INPUT_ENCODING=utf-8&filter.status=active&search_term=" + encodeURIComponent(value);
+
+  search_term.val('');
+  $("#win1").attr('src', url);
+
+  return false;
+}
+
 function clockon() {
   var now = new Date();
   var h = now.getHours();
@@ -16,11 +41,13 @@ window.onload=clockon
 
  <table border="0" width="100%" background="image/bg_titel.gif" cellpadding="0" cellspacing="0">
   <tr>
-   <td style="color:white; font-family:verdana,arial,sans-serif; font-size: 12px;">
+   <td style="color:white; font-family:verdana,arial,sans-serif; font-size: 12px;" nowrap>
     &nbsp;
     [<a href="menuv3.pl?action=display" target="_blank">[% 'new Window' | $T8 %]</a>]
     &nbsp;
     [<a href="JavaScript:top.main_window.print()">[% 'print' | $T8 %]</a>]
+    &nbsp;
+    [[% 'Search contacts' | $T8 %] <input size="15" name="search_term" id="search_term" onkeydown="return on_keydown_quicksearch(event)">]
    </td>
    <td align="right" style="vertical-align:middle; color:white; font-family:verdana,arial,sans-serif; font-size: 12px;" nowrap>
     [[% 'User' | $T8 %]: [% HTML.escape(login) %] -