2 All accessible Freeside customer fields fields go in here. Those of
3 them outside cust_main also need to go in RT::URI::freeside::Internal
4 (where they should be pulled into CustomerInfo). Nothing should need
5 to go in RT::Tickets_Overlay; it already resolves "Customer.foo" as
6 "cust_main.foo", and "Customer.cust_bar.foo" as "JOIN cust_bar using
7 (custnum) ... cust_bar.foo".
10 - 'Value' makes the field a search criterion. This also requires 'Op'.
11 See Search/Elements/PickBasics.
12 - 'Display' makes it an output column, and is either the cust_main
13 field, the CustomerInfo key, or a coderef that takes the RT::Ticket
15 - 'OrderBy' makes it a sort key, and must be set to an RT-SQL field
20 my @customer_fields = ( # ordered
28 foreach my $c (ticket_cust_resolvers($Ticket)) {
29 push @return, \'<A HREF="', $c->HREF, \'">',
37 OrderBy => 'Customer.Number',
40 #Column name (format string)
42 # Column heading/query builder name
44 # Column value (coderef, cust_main field, or CustomerInfo key)
45 Display => 'AgentName',
46 # Query builder options
47 # RT-SQL field, defaults to Name
48 QueryName => 'Customer.agentnum',
49 #QueryLabel => 'Agent' #defaults to Label
50 Op => equals_notequals,
51 Value => select_table('agent', 'agentnum', 'agent'),
52 # RT-SQL sort key (if any)
53 OrderBy => 'Customer.agentnum',
56 Name => 'CustomerClass',
57 Label => 'Customer Class',
58 Display => 'CustomerClass',
59 QueryName => 'Customer.classnum',
60 Op => equals_notequals,
61 Value => select_table('cust_class', 'classnum', 'classname'),
62 OrderBy => 'Customer.classnum',
65 Name => 'AdvertisingSource',
66 Label => 'Advertising Source',
67 Display => 'Referral',
68 QueryName => 'Customer.refnum',
69 Op => equals_notequals,
70 Value => select_table('part_referral', 'refnum', 'referral'),
71 OrderBy => 'Customer.refnum',
74 Name => 'BillingType',
75 Label => 'Billing Type',
76 Display => 'BillingType',
77 QueryName => 'Customer.payby',
78 Op => equals_notequals,
81 Options => [ '' => '-',
82 map { $_, FS::payby->longname($_) } FS::payby->cust_payby
87 Name => 'InvoiceEmail',
88 Label => 'Invoice Email',
89 Display => 'InvoiceEmail',
93 Name => 'BillingAddress',
94 Label => 'Billing Address',
95 Display => 'bill_location',
98 Name => 'StreetAddress1',
99 Label => 'Street Address',
100 Display => 'bill_address1',
103 Name => 'StreetAddress2',
105 Display => 'bill_address2',
110 Display => 'bill_city',
115 Display => 'bill_state',
118 Name => 'CustomerTags',
123 foreach my $c (ticket_cust_resolvers($Ticket)) {
124 foreach my $t (@{ $c->CustomerInfo->{CustomerTags} }) {
125 push @return, \'<SPAN style="background-color:#',
134 push @return, \'<BR>';
139 QueryName => 'Customer.cust_tag.tagnum',
141 Op => equals_notequals,
142 Value => select_table('part_tag', 'tagnum', 'tagname'),
149 sub equals_notequals {
152 Path => '/Elements/SelectBoolean',
153 Arguments => { TrueVal=> '=', FalseVal=> '!=' },
159 my ($table, $value_col, $name_col, $hashref) = @_;
160 $hashref ||= { disabled => '' }; # common case
165 map { $_->$value_col, $_->$name_col }
166 qsearch($table, $hashref)
171 sub ticket_cust_resolvers {
173 my @Customers = map { $_->TargetURI->Resolver->CustomerResolver }
174 @{ $Ticket->Customers->ItemsArrayRef };
175 # this can contain cust_svc links, careful
177 my %seen = map { $_->URI => $_ } @Customers;
181 sub cust_info_attribute { # the simple case of $resolver->CustomerInfo->{foo}
182 my $attribute = shift;
186 foreach my $c (ticket_cust_resolvers($Ticket)) {
187 push @return, $c->CustomerInfo->{$attribute}, '<BR>';
189 pop @return; #trailing <BR>
198 if ( $arg eq 'Names' ) {
199 return map { $_->{Name} } @customer_fields;
201 elsif ( $arg eq 'ColumnMap' ) {
206 title => $f->{Label},
207 attribute => $f->{OrderBy} || '',
208 value => ref($f->{Display}) eq 'CODE' ?
210 cust_info_attribute($f->{Display})
213 grep { exists $_->{Display} }
216 elsif ( $arg eq 'Criteria' ) {
219 # argument to Search/Elements/ConditionRow
222 Name => ($f->{QueryName} || $f->{Name}),
223 Field => ($f->{QueryLabel} || $f->{Label}),
225 Value => $f->{Value},
228 grep { exists $_->{Condition} || exists $_->{Value} }
231 else { die "unknown CustomerFields mode '$arg'\n"; }