no need for FS calendar buttons in RT 4.2
[freeside.git] / rt / share / html / Elements / CustomerFields
1 <%doc>
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".
8
9 About the keys:
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
14   as an argument.
15 - 'OrderBy' makes it a sort key, and must be set to an RT-SQL field
16   name to sort by.
17 </%doc>
18 <%once>
19
20 my @customer_fields = ( # ordered
21   {
22     # custnum
23     Name    => 'Customer',
24     Label   => 'Customer',
25     Display => sub {
26                 my $Ticket = shift;
27                 my @return = ();
28                 foreach my $c (ticket_cust_resolvers($Ticket)) {
29                     push @return, \'<A HREF="', $c->HREF, \'">',
30                                   $c->AsString,
31                                   \'</A>',
32                                   \'<BR>';
33                 }
34                 pop @return;
35                 @return;
36               },
37     OrderBy => 'Customer.Number',
38   },
39   {
40     #Column name (format string)
41     Name    => 'Agent',
42     # Column heading/query builder name
43     Label   => 'Agent',
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',
54   },
55   {
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',
63   },
64   {
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',
72   },
73   {
74     Name    => 'BillingType',
75     Label   => 'Billing Type',
76     Display => 'BillingType',
77     QueryName => 'Customer.payby',
78     Op      => equals_notequals,
79     Value   => {
80       Type => 'select',
81       Options => [ '' => '-',
82         map { $_, FS::payby->longname($_) } FS::payby->cust_payby 
83       ],
84     },
85   },
86   {
87     Name    => 'InvoiceEmail',
88     Label   => 'Invoice Email',
89     Display => 'InvoiceEmail',
90     # query/sort needed?
91   },
92   {
93     Name    => 'BillingAddress',
94     Label   => 'Billing Address',
95     Display => 'bill_location',
96   },
97   {
98     Name    => 'StreetAddress1',
99     Label   => 'Street Address',
100     Display => 'bill_address1',
101   },
102   {
103     Name    => 'StreetAddress2',
104     Label   => '',
105     Display => 'bill_address2',
106   },
107   {
108     Name    => 'City',
109     Label   => 'City',
110     Display => 'bill_city',
111   },
112   {
113     Name    => 'State',
114     Label   => 'State',
115     Display => 'bill_state',
116   },
117   {
118     Name    => 'CustomerTags',
119     Label   => '',
120     Display => sub {
121                 my $Ticket = shift;
122                 my @return = ();
123                 foreach my $c (ticket_cust_resolvers($Ticket)) {
124                   foreach my $t (@{ $c->CustomerInfo->{CustomerTags} }) {
125                     push @return, \'<SPAN style="background-color:#',
126                     $t->{'color'},
127                     \';">&nbsp;',
128                     $t->{'name'},
129                     \'&nbsp;</SPAN>',
130                     \'&nbsp;'
131                     ;
132                   }
133                   pop @return;
134                   push @return, \'<BR>';
135                 }
136                 pop @return;
137                 @return;
138               },
139     QueryName => 'Customer.cust_tag.tagnum',
140     QueryLabel => 'Tag',
141     Op      => equals_notequals,
142     Value   => select_table('part_tag', 'tagnum', 'tagname'),
143     OrderBy => '',
144   },
145 );
146
147 #helper subs
148 #Op      
149 sub equals_notequals {
150   return {
151       Type => 'component',
152       Path => '/Elements/SelectBoolean',
153       Arguments => { TrueVal=> '=', FalseVal=> '!=' },
154   }
155 }
156
157 #Value
158 sub select_table {
159   my ($table, $value_col, $name_col, $hashref) = @_;
160   $hashref ||= { disabled => '' }; # common case
161   return {
162     Type => 'select',
163     Options => [ 
164       '' => '-',
165       map { $_->$value_col, $_->$name_col }
166       qsearch($table, $hashref)
167     ],
168   }
169 }
170
171 sub ticket_cust_resolvers {
172     my $Ticket = shift;
173     my @Customers = map { $_->TargetURI->Resolver->CustomerResolver }
174                       @{ $Ticket->Customers->ItemsArrayRef };
175     # this can contain cust_svc links, careful
176     # uniq
177     my %seen = map { $_->URI => $_ } @Customers;
178     values %seen;
179 }
180
181 sub cust_info_attribute { # the simple case of $resolver->CustomerInfo->{foo}
182     my $attribute = shift;
183     sub {
184         my $Ticket = shift;
185         my @return;
186         foreach my $c (ticket_cust_resolvers($Ticket)) {
187             push @return, $c->CustomerInfo->{$attribute}, '<BR>';
188         }
189         pop @return; #trailing <BR>
190         @return;
191     };
192 }
193
194 </%once>
195 <%init>
196
197 my $arg = shift;
198 if ( $arg eq 'Names' ) {
199   return map { $_->{Name} } @customer_fields;
200 }
201 elsif ( $arg eq 'ColumnMap' ) {
202   return map {
203     my $f = $_;
204
205     $f->{Name} => {
206         title     => $f->{Label},
207         attribute => $f->{OrderBy} || '',
208         value     => ref($f->{Display}) eq 'CODE' ? 
209                       $f->{Display} : 
210                       cust_info_attribute($f->{Display})
211       }
212   } #map
213   grep { exists $_->{Display} }
214   @customer_fields;
215 }
216 elsif ( $arg eq 'Criteria' ) {
217   return map {
218     my $f = $_;
219     # argument to Search/Elements/ConditionRow
220     $f->{Condition} ||
221     {
222       Name  => ($f->{QueryName} || $f->{Name}),
223       Field => ($f->{QueryLabel} || $f->{Label}),
224       Op    => $f->{Op},
225       Value => $f->{Value},
226     }
227   } #map
228   grep { exists $_->{Condition} || exists $_->{Value} }
229   @customer_fields;
230 }
231 else { die "unknown CustomerFields mode '$arg'\n"; }
232 </%init>