improve customer field access in RT queries, #16490
authormark <mark>
Sun, 19 Feb 2012 00:34:44 +0000 (00:34 +0000)
committermark <mark>
Sun, 19 Feb 2012 00:34:44 +0000 (00:34 +0000)
15 files changed:
rt/FREESIDE_MODIFIED
rt/lib/RT/Tickets_Overlay.pm
rt/lib/RT/URI/freeside.pm
rt/lib/RT/URI/freeside/Internal.pm
rt/share/html/Callbacks/SearchCustomerFields/Search/Elements/PickBasics/Default [deleted file]
rt/share/html/Elements/CustomerFields [new file with mode: 0644]
rt/share/html/Elements/RT__Ticket/ColumnMap
rt/share/html/Elements/SelectCustomerAgent [deleted file]
rt/share/html/Elements/SelectCustomerClass [deleted file]
rt/share/html/Elements/SelectCustomerReferral [deleted file]
rt/share/html/Elements/SelectCustomerTag [deleted file]
rt/share/html/Search/Build.html
rt/share/html/Search/Elements/BuildFormatString
rt/share/html/Search/Elements/ConditionRow
rt/share/html/Search/Elements/PickBasics

index 13ba574..1cb17d6 100644 (file)
@@ -86,10 +86,10 @@ share/html/Elements/ShowCustomFieldTimeValue #timeworked custom fields
 share/html/Elements/ShowLink_Checklist
  share/html/Elements/ShowUserVerbose
  share/html/Elements/Footer
- share/html/Elements/SelectCustomerAgent #SearchCustomerFields
- share/html/Elements/SelectCustomerClass #SearchCustomerFields
- share/html/Elements/SelectCustomerTag #SearchCustomerFields
- share/html/Elements/SelectCustomerReferral #SearchCustomerFields
+# share/html/Elements/SelectCustomerAgent #SearchCustomerFields
+# share/html/Elements/SelectCustomerClass #SearchCustomerFields
+# share/html/Elements/SelectCustomerTag #SearchCustomerFields
+# share/html/Elements/SelectCustomerReferral #SearchCustomerFields
 share/html/Prefs/SavedSearches.html #saved searches
 share/html/Search/Bulk.html #bulk increment priority #mandatory fields
  share/html/Search/Build.html
@@ -134,7 +134,7 @@ share/html/Callbacks/CheckMandatoryFields/* #removed
 
 share/html/Callbacks/TimeToResolve/*
 
-share/html/Callbacks/SearchCustomerFields/*
+#share/html/Callbacks/SearchCustomerFields/*
 
 share/html/Callbacks/RTx-Statistics/*
 share/html/RTx/Statistics/*
@@ -155,3 +155,8 @@ lib/RT/Transaction_Vendor.pm
 share/html/Elements/SelectStatus 
 share/html/Ticket/Elements/EditDates
 share/html/Ticket/Elements/ShowDates
+
+#SearchCustomerFields improvements
+share/html/Elements/CustomerFields
+share/html/Search/Elements/ConditionRow # bugfix for select options list
+share/html/Search/Elements/PickBasics
index 76a57b8..a5d37a3 100644 (file)
@@ -146,10 +146,11 @@ our %FIELD_METADATA = (
     HasAttribute     => [ 'HASATTRIBUTE', 1 ],
     HasNoAttribute     => [ 'HASATTRIBUTE', 0 ],
     #freeside
-    Agentnum         => [ 'FREESIDEFIELD', ],
-    Classnum         => [ 'FREESIDEFIELD', ],
-    Refnum           => [ 'FREESIDEFIELD', ],
-    Tagnum           => [ 'FREESIDEFIELD', 'cust_tag' ],
+    Customer         => [ 'FREESIDEFIELD', ],
+#    Agentnum         => [ 'FREESIDEFIELD', ],
+#    Classnum         => [ 'FREESIDEFIELD', ],
+#    Refnum           => [ 'FREESIDEFIELD', ],
+#    Tagnum           => [ 'FREESIDEFIELD', 'cust_tag' ],
     WillResolve      => [ 'DATE'            => 'WillResolve', ], #loc_left_pair
 );
 
@@ -1804,36 +1805,23 @@ sub OrderByCols {
            push @res, { %$row, FIELD => "Priority", ORDER => $order } ;
 
        } elsif ( $field eq 'Customer' ) { #Freeside
-           if ( $subkey eq 'Number' ) {
-               my ($linkalias, $custnum_sql) = $self->JoinToCustLinks;
-               push @res, { %$row,
-                            ALIAS => '',
-                            FIELD => $custnum_sql,
-                        };
+           # OrderBy(FIELD => expression) doesn't work, it has to be 
+           # an actual field, so we have to do the join even if sorting
+           # by custnum
+           my $custalias = $self->JoinToCustomer;
+           my $cust_field = lc($subkey);
+           if ( !$cust_field or $cust_field eq 'number' ) {
+               $cust_field = 'custnum';
            }
-           else {
-               my $custalias = $self->JoinToCustomer;
-               my $field;
-               if ( $subkey eq 'Name' ) {
-                   $field = "COALESCE( $custalias.company,
-                   $custalias.last || ', ' || $custalias.first
-                   )";
-               }
-               elsif ( $subkey eq 'Class' ) {
-                   $field = "$custalias.classnum";
-               }
-               elsif ( $subkey eq 'Agent' ) {
-                   $field = "$custalias.agentnum";
-               }
-               elsif ( $subkey eq 'Referral' ) {
-                   $field = "$custalias.refnum";
-               }
-               else {
-                   # no other cases exist yet, but for obviousness:
-                   $field = $subkey;
-               }
-               push @res, { %$row, ALIAS => '', FIELD => $field };
+           elsif ( $cust_field eq 'name' ) {
+               $cust_field = "COALESCE( $custalias.company,
+               $custalias.last || ', ' || $custalias.first
+               )";
            }
+           else { # order by cust_main fields directly: 'Customer.agentnum'
+               $cust_field = $subkey;
+           }
+           push @res, { %$row, ALIAS => $custalias, FIELD => $cust_field };
 
        } #Freeside
 
@@ -1853,26 +1841,31 @@ sub JoinToCustLinks {
     # Return the linkalias for further join/limit action,
     # and an sql expression to retrieve the custnum.
     my $self = shift;
-    my $linkalias = $self->Join(
-        TYPE   => 'LEFT',
-        ALIAS1 => 'main',
-        FIELD1 => 'id',
-        TABLE2 => 'Links',
-        FIELD2 => 'LocalBase',
-    );
+    # only join once for each RT::Tickets object
+    my $linkalias = $self->{cust_linkalias};
+    if (!$linkalias) {
+        $linkalias = $self->Join(
+            TYPE   => 'LEFT',
+            ALIAS1 => 'main',
+            FIELD1 => 'id',
+            TABLE2 => 'Links',
+            FIELD2 => 'LocalBase',
+        );
 
-    $self->SUPER::Limit(
-        LEFTJOIN => $linkalias,
-        FIELD    => 'Type',
-        OPERATOR => '=',
-        VALUE    => 'MemberOf',
-    );
-    $self->SUPER::Limit(
-        LEFTJOIN => $linkalias,
-        FIELD    => 'Target',
-        OPERATOR => 'STARTSWITH',
-        VALUE    => 'freeside://freeside/cust_main/',
-    );
+        $self->SUPER::Limit(
+            LEFTJOIN => $linkalias,
+            FIELD    => 'Type',
+            OPERATOR => '=',
+            VALUE    => 'MemberOf',
+        );
+        $self->SUPER::Limit(
+            LEFTJOIN => $linkalias,
+            FIELD    => 'Target',
+            OPERATOR => 'STARTSWITH',
+            VALUE    => 'freeside://freeside/cust_main/',
+        );
+        $self->{cust_linkalias} = $linkalias;
+    }
     my $custnum_sql = "CAST(SUBSTR($linkalias.Target,31) AS ";
     if ( RT->Config->Get('DatabaseType') eq 'mysql' ) {
         $custnum_sql .= 'SIGNED INTEGER)';
@@ -1886,7 +1879,8 @@ sub JoinToCustLinks {
 sub JoinToCustomer {
     my $self = shift;
     my ($linkalias, $custnum_sql) = $self->JoinToCustLinks;
-
+    # don't reuse this join, though--negative queries need 
+    # independent joins
     my $custalias = $self->Join(
         TYPE       => 'LEFT',
         EXPRESSION => $custnum_sql,
@@ -1908,20 +1902,29 @@ sub _FreesideFieldLimit {
         $op = '=' if $op eq '!=';
         $op =~ s/\bNOT\b//;
     }
-    my $meta = $FIELD_METADATA{$field};
-    if ( $meta->[1] ) {
+
+    my $cust_field = $rest{SUBKEY} || 'custnum';
+    my $table2;
+    # compound subkey: separate into table name and field in that table
+    # (must be linked by custnum)
+    ($table2, $cust_field) = ($1, $2) if $cust_field =~ /^(\w+)?\.(\w+)$/;
+
+    $cust_field = lc($cust_field);
+    $cust_field = 'custnum' if !$cust_field or $cust_field eq 'number';
+
+    if ( $table2 ) {
         $alias = $self->Join(
             TYPE        => 'LEFT',
             ALIAS1      => $alias,
             FIELD1      => 'custnum',
-            TABLE2      => $meta->[1],
+            TABLE2      => $table2,
             FIELD2      => 'custnum',
         );
     }
 
     $self->SUPER::Limit(
         LEFTJOIN        => $alias,
-        FIELD           => lc($field),
+        FIELD           => $cust_field,
         OPERATOR        => $op,
         VALUE           => $value,
         ENTRYAGGREGATOR => 'AND',
@@ -1929,7 +1932,7 @@ sub _FreesideFieldLimit {
     $self->_SQLLimit(
         %rest,
         ALIAS           => $alias,
-        FIELD           => lc($field),
+        FIELD           => 'custnum',
         OPERATOR        => $is_negative ? 'IS' : 'IS NOT',
         VALUE           => 'NULL',
         QUOTEVALUE      => 0,
index 0e1834f..64fb377 100644 (file)
@@ -299,39 +299,19 @@ if ($@ &&
   die $@;
 };
 
-=item AgentName
+=item CustomerInfo
 
-Return the name of the customer's agent.
+Return a hashref of customer information, including all fields from 
+C<cust_main> as well as:
 
-=cut
-
-sub AgentName { undef }
-
-=item CustomerClass
-
-Return the name of the customer's class.
-
-=cut
-
-sub CustomerClass { undef }
-
-=item CustomerTags
-
-Return the list of tags attached to the customer.  Each tag is returned
-as a hashref with keys "name", "desc", and "color".
-
-=cut
-
-sub CustomerTags { ( ) }
-
-=back
-
-=item Referral
-
-Return the customer's advertising source, as a string.
+- AgentName: the name of the customer's agent
+- CustomerClass: the name of the customer's class
+- CustomerTags: an arrayref of tags attached to the customer, each
+  as a hashref with keys "name", "desc", and "color".
+- Referral: the name of the customer's advertising source.
 
 =cut
 
-sub Referral { undef }
+sub CustomerInfo { {} }
 
 1;
index 4069b87..5656a51 100644 (file)
@@ -38,6 +38,7 @@ use FS::Conf;
 use FS::Record qw(qsearchs qsearch dbdef);
 use FS::cust_main;
 use FS::cust_svc;
+use FS::payby;
 
 =head1 NAME
 
@@ -53,7 +54,7 @@ See L<RT::URI::freeside> for public/private interface documentation.
 
 
 
-sub _FreesideGetRecord { # cache this?
+sub _FreesideGetRecord {
 
   my $self = shift;
   my ($table, $pkey) = ($self->{'fstable'}, $self->{'fspkey'});
@@ -142,36 +143,31 @@ sub _FreesideURILabelLong {
 
 }
 
-sub AgentName {
+# no need to have a separate wrapper method for every one of these things
+sub CustomerInfo {
   my $self = shift;
   my $rec = $self->_FreesideGetRecord() or return;
-  my $agent = $rec->{'_object'}->agent or return;
-  return $agent->agentnum . ': ' . $agent->agent;
-}
-
-sub CustomerClass {
-  my $self = shift;
-  my $rec = $self->_FreesideGetRecord() or return;
-  my $cust_class = $rec->{'_object'}->cust_class or return;
-  return $cust_class->classname;
-}
-  
-sub CustomerTags {
-  my $self = shift;
-  my $rec = $self->_FreesideGetRecord() or return;
-  my @part_tag = $rec->{'_object'}->part_tag;
-  return map { 
-    { 'name'  => $_->tagname,
-      'desc'  => $_->tagdesc,
-      'color' => $_->tagcolor }
-  } @part_tag;
-}
-
-sub Referral {
-  my $self = shift;
-  my $rec = $self->_FreesideGetRecord() or return;
-  my $ref = qsearchs('part_referral', { refnum => $rec->{'_object'}->refnum });
-  $ref ? $ref->referral : ''
+  my $cust_main = $rec->{'_object'};
+  my $agent = $cust_main->agent;
+  my $class = $cust_main->cust_class;
+  my $referral = qsearchs('part_referral', { refnum => $cust_main->refnum });
+  my @part_tags = $cust_main->part_tag;
+
+  return $self->{CustomerInfo} ||= {
+    $cust_main->hash,
+
+    AgentName     => ($agent ? ($agent->agentnum.': '.$agent->agent) : ''),
+    CustomerClass => ($class ? $class->classname : ''),
+    CustomerTags  => [
+      sort { $a->{'name'} <=> $b->{'name'} }
+      map { 
+        { name => $_->tagname, desc => $_->tagdesc, color => $_->tagcolor }
+      } @part_tags
+    ],
+    Referral      => ($referral ? $referral->referral : ''),
+    InvoiceEmail  => $cust_main->invoicing_list_emailonly_scalar,
+    BillingType   => FS::payby->longname($cust_main->payby),
+  }
 }
 
 1;
diff --git a/rt/share/html/Callbacks/SearchCustomerFields/Search/Elements/PickBasics/Default b/rt/share/html/Callbacks/SearchCustomerFields/Search/Elements/PickBasics/Default
deleted file mode 100644 (file)
index 369912b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<%init>
-push @$Conditions, 
-    {
-        Name => 'Agentnum',
-        Field => 'Agent',
-        Op => {
-            Type => 'component',
-            Path => '/Elements/SelectBoolean',
-            Arguments => { TrueVal=> '=', FalseVal => '!=' },
-        },
-        Value => {
-            Type => 'component',
-            Path => '/Elements/SelectCustomerAgent',
-        },
-    },
-    {
-        Name => 'Classnum',
-        Field => 'Customer Class',
-        Op => {
-            Type => 'component',
-            Path => '/Elements/SelectBoolean',
-            Arguments => { TrueVal=> '=', FalseVal => '!=' },
-        },
-        Value => {
-            Type => 'component',
-            Path => '/Elements/SelectCustomerClass',
-        },
-    },
-    {
-        Name => 'Tagnum',
-        Field => 'Tag',
-        Op => {
-            Type => 'component',
-            Path => '/Elements/SelectBoolean',
-            Arguments => { TrueVal=> '=', FalseVal => '!=' },
-        },
-        Value => {
-            Type => 'component',
-            Path => '/Elements/SelectCustomerTag',
-        },
-    },
-    {
-        Name => 'Refnum',
-        Field => 'Advertising Source',
-        Op => {
-            Type => 'component',
-            Path => '/Elements/SelectBoolean',
-            Arguments => { TrueVal=> '=', FalseVal => '!=' },
-        },
-        Value => {
-            Type => 'component',
-            Path => '/Elements/SelectCustomerReferral',
-        },
-    },
-;
-</%init>
-<%ARGS>
-$Conditions => []
-</%ARGS>
diff --git a/rt/share/html/Elements/CustomerFields b/rt/share/html/Elements/CustomerFields
new file mode 100644 (file)
index 0000000..553a349
--- /dev/null
@@ -0,0 +1,215 @@
+<%doc>
+All accessible Freeside customer fields fields go in here.  Those of 
+them outside cust_main also need to go in RT::URI::freeside::Internal
+(where they should be pulled into CustomerInfo).  Nothing should need 
+to go in RT::Tickets_Overlay; it already resolves "Customer.foo" as 
+"cust_main.foo", and "Customer.cust_bar.foo" as "JOIN cust_bar using 
+(custnum) ... cust_bar.foo".
+
+About the keys:
+- 'Value' makes the field a search criterion.  This also requires 'Op'.
+  See Search/Elements/PickBasics.
+- 'Display' makes it an output column, and is either the cust_main 
+  field, the CustomerInfo key, or a coderef that takes the RT::Ticket
+  as an argument.
+- 'OrderBy' makes it a sort key, and must be set to an RT-SQL field
+  name to sort by.
+</%doc>
+<%once>
+return unless $RT::URI::freeside::IntegrationType eq 'Internal';
+
+my @customer_fields = ( # ordered
+  {
+    # custnum
+    Name    => 'Customer',
+    Label   => 'Customer',
+    Display => sub {
+                my $Ticket = shift;
+                my @return = ();
+                foreach my $c (ticket_cust_resolvers($Ticket)) {
+                    push @return, \'<A HREF="', $c->HREF, \'">',
+                                  $c->AsString,
+                                  \'</A>',
+                                  \'<BR>';
+                }
+                pop @return;
+                @return;
+              },
+    OrderBy => 'Customer.Number',
+  },
+  {
+    #Column name (format string)
+    Name    => 'Agent',
+    # Column heading/query builder name
+    Label   => 'Agent',
+    # Column value (coderef, cust_main field, or CustomerInfo key)
+    Display => 'AgentName',
+    # Query builder options
+    # RT-SQL field, defaults to Name
+    QueryName => 'Customer.agentnum',
+    #QueryLabel => 'Agent' #defaults to Label
+    Op      => equals_notequals,
+    Value   => select_table('agent', 'agentnum', 'agent'),
+    # RT-SQL sort key (if any)
+    OrderBy => 'Customer.agentnum',
+  },
+  {
+    Name    => 'CustomerClass',
+    Label   => 'Customer Class',
+    Display => 'CustomerClass',
+    QueryName => 'Customer.classnum',
+    Op      => equals_notequals,
+    Value   => select_table('cust_class', 'classnum', 'classname'),
+    OrderBy => 'Customer.classnum',
+  },
+  {
+    Name    => 'AdvertisingSource',
+    Label   => 'Advertising Source',
+    Display => 'Referral',
+    QueryName => 'Customer.refnum',
+    Op      => equals_notequals,
+    Value   => select_table('part_referral', 'refnum', 'referral'),
+    OrderBy => 'Customer.refnum',
+  },
+  {
+    Name    => 'BillingType',
+    Label   => 'Billing Type',
+    Display => 'BillingType',
+    QueryName => 'Customer.payby',
+    Op      => equals_notequals,
+    Value   => {
+      Type => 'select',
+      Options => [ '' => '-',
+        map { $_, FS::payby->longname($_) } FS::payby->cust_payby 
+      ],
+    },
+  },
+  {
+    Name    => 'InvoiceEmail',
+    Label   => 'Invoice Email',
+    Display => 'InvoiceEmail',
+    # query/sort needed?
+  },
+  {
+    Name    => 'City',
+    Label   => 'City',
+    Display => 'city',
+    OrderBy => 'Customer.city',
+  },
+  {
+    Name    => 'State',
+    Label   => 'State',
+    Display => 'state',
+    OrderBy => 'Customer.state',
+  },
+  {
+    Name    => 'CustomerTags',
+    Label   => '',
+    Display => sub {
+                my $Ticket = shift;
+                my @return = ();
+                foreach my $c (ticket_cust_resolvers($Ticket)) {
+                  foreach my $t (@{ $c->CustomerInfo->{CustomerTags} }) {
+                    push @return, \'<SPAN style="background-color:#',
+                    $t->{'color'},
+                    \';">&nbsp;',
+                    $t->{'name'},
+                    \'&nbsp;</SPAN>',
+                    \'&nbsp;'
+                    ;
+                  }
+                  pop @return;
+                  push @return, \'<BR>';
+                }
+                pop @return;
+                @return;
+              },
+    QueryName => 'Customer.cust_tag.tagnum',
+    QueryLabel => 'Tag',
+    Op      => equals_notequals,
+    Value   => select_table('part_tag', 'tagnum', 'tagname'),
+    OrderBy => '',
+  },
+);
+
+#helper subs
+#Op      
+sub equals_notequals {
+  return {
+      Type => 'component',
+      Path => '/Elements/SelectBoolean',
+      Arguments => { TrueVal=> '=', FalseVal=> '!=' },
+  }
+}
+
+#Value
+sub select_table {
+  my ($table, $value_col, $name_col, $hashref) = @_;
+  $hashref ||= { disabled => '' }; # common case
+  return {
+    Type => 'select',
+    Options => [ 
+      '' => '-',
+      map { $_->$value_col, $_->$name_col }
+      qsearch($table, $hashref)
+    ],
+  }
+}
+
+sub ticket_cust_resolvers {
+    my $Ticket = shift;
+    my @Customers = @{ $Ticket->Customers->ItemsArrayRef };
+    return map $_->TargetURI->Resolver, @Customers;
+}
+
+sub cust_info_attribute { # the simple case of $resolver->CustomerInfo->{foo}
+    my $attribute = shift;
+    sub {
+        my $Ticket = shift;
+        my @return;
+        foreach my $c (ticket_cust_resolvers($Ticket)) {
+            push @return, $c->CustomerInfo->{$attribute}, '<BR>';
+        }
+        pop @return; #trailing <BR>
+        @return;
+    };
+}
+
+</%once>
+<%init>
+return unless $RT::URI::freeside::IntegrationType eq 'Internal';
+
+my $arg = shift;
+if ( $arg eq 'Names' ) {
+  return map { $_->{Name} } @customer_fields;
+}
+elsif ( $arg eq 'ColumnMap' ) {
+  return map {
+    my $f = $_;
+
+    $f->{Name} => {
+        title     => $f->{Label},
+        attribute => $f->{OrderBy} || '',
+        value     => ref($f->{Display}) eq 'CODE' ? 
+                      $f->{Display} : 
+                      cust_info_attribute($f->{Display})
+      }
+  } #map
+  grep { exists $_->{Display} }
+  @customer_fields;
+}
+elsif ( $arg eq 'PickBasics' ) {
+  return map {
+    my $f = $_;
+    {
+      Name  => ($f->{QueryName} || $f->{Name}),
+      Field => ($f->{QueryLabel} || $f->{Label}),
+      Op    => $f->{Op},
+      Value => $f->{Value},
+    }
+  } #map
+  grep { exists $_->{Value} }
+  @customer_fields;
+}
+else { die "unknown CustomerFields mode '$arg'\n"; }
+</%init>
index cd6ca1f..9e6466c 100644 (file)
@@ -318,100 +318,11 @@ $COLUMN_MAP = {
             return \$bookmark;
         },
     },
-
-    Customer => {
-        title     => 'Customer', #loc
-        attribute => 'Customer.Number', #title/attribute/name... what does it all mean?
-        value     => sub {
-            my $Ticket = shift;
-            my @return = ();
-            foreach my $c (ticket_cust_resolvers($Ticket)) {
-                push @return, \'<A HREF="', $c->HREF, \'">', 
-                              $c->AsString,
-                              \'</A>',
-                              \'<BR>';
-            }
-            pop @return;
-            @return;
-        },
-    },
-    # For future reference:
-    # hash key = name of the column in the format string 
-    #   (see /Search/Elements/BuildFormatString)
-    # title = displayed name in the table header
-    # attribute = the field to ORDER BY when sorting on this column
-    Agent => {
-        title     => 'Agent',
-        attribute => 'Customer.Agent',
-        value => sub {
-            my $Ticket = shift;
-            my @return = ();
-            foreach my $c (ticket_cust_resolvers($Ticket)) {
-                push @return, $c->AgentName, \'<BR>';
-            }
-            pop @return;
-            @return;
-        },
-    },
-    CustomerClass => {
-        title     => 'Class',
-        attribute => 'Customer.Class',
-        value     => sub {
-            my $Ticket = shift;
-            my @return = ();
-            foreach my $c (ticket_cust_resolvers($Ticket)) {
-                push @return, $c->CustomerClass, \'<BR>';
-            }
-            pop @return;
-            @return;
-        },
-    },
-    CustomerTags => {
-        title     => '',
-        attribute => '',
-        value     => sub {
-            my $Ticket = shift;
-            my @return = ();
-            foreach my $c (ticket_cust_resolvers($Ticket)) {
-                my @tags = sort { $a->{'name'} cmp $b->{'name'} }
-                            $c->CustomerTags;
-                foreach my $t (@tags) {
-                    push @return, \'<SPAN style="background-color:#',
-                                  $t->{'color'},
-                                  \';">&nbsp;',
-                                  $t->{'name'},
-                                  \'&nbsp;</SPAN>',
-                                  \'&nbsp;'
-                                  ;
-                }
-                pop @return;
-                push @return, \'<BR>';
-            }
-            pop @return;
-            @return;
-        },
-    },
-    AdvertisingSource => {
-        title     => 'Advertising Source',
-        attribute => 'Customer.Referral',
-        value => sub {
-            my $Ticket = shift;
-            my @return = ();
-            foreach my $c (ticket_cust_resolvers($Ticket)) {
-                push @return, $c->Referral, \'<BR>';
-            }
-            pop @return;
-            @return;
-        },
-    },
+    
+    #freeside
+    $m->comp('/Elements/CustomerFields', 'ColumnMap'),
 };
 
-sub ticket_cust_resolvers {
-    my $Ticket = shift;
-    my @Customers = @{ $Ticket->Customers->ItemsArrayRef };
-    return map $_->TargetURI->Resolver, @Customers;
-}
-
 # if no GPG support, then KeyOwnerName and KeyRequestors fall back to the regular
 # versions
 if (RT->Config->Get('GnuPG')->{'Enable'}) {
diff --git a/rt/share/html/Elements/SelectCustomerAgent b/rt/share/html/Elements/SelectCustomerAgent
deleted file mode 100644 (file)
index 75a1fba..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-% return if ($RT::URI::freeside::IntegrationType ne 'Internal');
-<select name="<%$Name%>">
-% if ($ShowNullOption) {
-  <option value="">-</option>
-% }
-% for my $agent (qsearch('agent', {'disabled' => ''})) {
-  <option value="<%$agent->agentnum%>" <% 
-  $agent->agentnum == $Default||'' ? 'selected' : ''%>
-  ><%$agent->agent%></option>
-% }
-</select>
-<%init></%init>
-<%args>
-$ShowNullOption => 1
-$Name => undef
-$Default => 0
-</%args>
diff --git a/rt/share/html/Elements/SelectCustomerClass b/rt/share/html/Elements/SelectCustomerClass
deleted file mode 100644 (file)
index 1a03cba..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-% return if ($RT::URI::freeside::IntegrationType ne 'Internal');
-<select name="<%$Name%>">
-% if ($ShowNullOption) {
-  <option value="">-</option>
-% }
-% for my $class (qsearch('cust_class', {'disabled' => ''})) {
-  <option value="<%$class->classnum%>" <% 
-  $class->classnum == $Default||'' ? 'selected' : ''%>
-  ><%$class->classname%></option>
-% }
-</select>
-<%init></%init>
-<%args>
-$ShowNullOption => 1
-$Name => undef
-$Default => 0
-</%args>
diff --git a/rt/share/html/Elements/SelectCustomerReferral b/rt/share/html/Elements/SelectCustomerReferral
deleted file mode 100644 (file)
index 84191f8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-% return if ($RT::URI::freeside::IntegrationType ne 'Internal');
-<select name="<%$Name%>">
-% if ($ShowNullOption) {
-  <option value="">-</option>
-% }
-% for my $referral (qsearch('part_referral', {'disabled' => ''})) {
-  <option value="<%$referral->refnum%>" <% 
-  $referral->refnum == $Default||'' ? 'selected' : ''%>
-  ><%$referral->referral%></option>
-% }
-</select>
-<%init></%init>
-<%args>
-$ShowNullOption => 1
-$Name => undef
-$Default => 0
-</%args>
diff --git a/rt/share/html/Elements/SelectCustomerTag b/rt/share/html/Elements/SelectCustomerTag
deleted file mode 100644 (file)
index 8627669..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-% return if ($RT::URI::freeside::IntegrationType ne 'Internal');
-<select name="<%$Name%>">
-% if ($ShowNullOption) {
-  <option value="">-</option>
-% }
-% for my $tag (qsearch('part_tag', {'disabled' => ''})) {
-  <option value="<%$tag->tagnum%>" <% 
-  $tag->tagnum == $Default||'' ? 'selected' : ''%>
-  ><%$tag->tagname%></option>
-% }
-</select>
-<%init></%init>
-<%args>
-$ShowNullOption => 1
-$Name => undef
-$Default => 0
-</%args>
index 9507a2d..506384c 100644 (file)
@@ -188,7 +188,7 @@ my @new_values = ();
 
 # {{{ Try to find if we're adding a clause
 foreach my $arg ( keys %ARGS ) {
-    next unless $arg =~ m/^ValueOf(\w+|'CF.{.*?}')$/
+    next unless $arg =~ m/^ValueOf([\w\.]+|'CF.{.*?}')$/
                 && ( ref $ARGS{$arg} eq "ARRAY"
                      ? grep $_ ne '', @{ $ARGS{$arg} }
                      : $ARGS{$arg} ne '' );
index f77c8da..96e6a28 100644 (file)
@@ -69,11 +69,15 @@ $CurrentDisplayColumns => undef
 # it -- and it grows per request.
 
 # All the things we can display in the format string by default
-my @fields = qw(
+# referenced by their ColumnMap keys
+my @fields = (
+  qw(
     id QueueName Subject
+  ),
+    
+    $m->comp('/Elements/CustomerFields', 'Names'), #freeside
 
-    Customer Agent CustomerClass CustomerTags AdvertisingSource
-
+  qw(
     Status ExtendedStatus UpdateStatus
     Type
 
@@ -99,7 +103,7 @@ my @fields = qw(
     Bookmark
 
     NEWLINE
-
+  )
 ); # loc_qw
 
 $m->callback( CallbackOnce => 1, CallbackName => 'SetFieldsOnce', Fields => \@fields );
index fe21f4d..65e2176 100644 (file)
@@ -82,7 +82,8 @@ $handle_block = sub {
         my $res = '';
         $res .= qq{<select id="$name" name="$name">};
         my @options = @{ $box->{'Options'} };
-        while( my $k = shift @options ) {
+        while( @options ) {
+            my $k = shift @options;
             my $v = shift @options;
             $res .= qq{<option value="$k">$v</option>};
         }
index b03fc15..ff30f7c 100644 (file)
@@ -209,6 +209,9 @@ my @lines = (
     },
 );
 
+#freeside
+push @lines, $m->comp('/Elements/CustomerFields', 'PickBasics');
+
 $m->callback( Conditions => \@lines );
 
 </%INIT>