customer view UI
[freeside.git] / httemplate / view / cust_main / menu.html
1 <style type="text/css">
2 #menu_ul {
3   padding: 0;
4   margin: .5em 0 0 0;
5   font-size: smaller;
6 }
7
8 #menu_ul li {
9   margin: 0;
10   float: left;
11   list-style: none;
12   position: relative;
13 }
14
15 #menu_ul a {
16   display: block;
17   margin: 0;
18   padding: .5em .75em;
19   background: #ffffff;
20   color: #525151;
21   white-space: nowrap;
22   text-decoration: none;
23   border-top: thin solid #CFDEFF;
24 }
25
26 #menu_ul a.current_show {
27   font-weight: bold;
28   background: #cfdeff;
29 }
30
31 #menu_ul ul {
32   margin:0;
33   padding:0;
34   display:none;
35   position: absolute;
36   top: 100%;
37   left: 0;
38   background: #ffffff;
39   border-bottom: thin solid #CFDEFF;
40 }
41
42 #menu_ul ul li {
43   margin: 0;
44   padding: 0;
45   float: none;
46 }
47
48 #menu_ul ul a {
49   border-top: thin solid #CFDEFF;
50   color: #333333;
51   background: transparent;
52 }
53
54 #menu_ul a:hover {
55   background: #cfdeff;
56   text-decoration: underline;
57   color: #7e0079;
58 }
59
60 </style>
61 <script src="<% $p %>elements/jquery.js"></script>
62 <script type="text/javascript">
63
64 $(document).ready(function() {
65         var openmenu;
66         function closemenu () {
67                 if (openmenu !== undefined) {
68                         openmenu.hide();
69                         openmenu = undefined;
70                 }
71         }               
72         $('#menu_ul > li').hover(function(){
73                 closemenu();
74                 openmenu = $('ul:first', this);
75                 openmenu.show();
76         }, function(){
77                 closemenu();
78         });
79 });
80 </script>
81
82 <ul id="menu_ul">
83 % foreach my $submenu (@processed_menu) {
84   <li>
85     <% shift @$submenu %>
86     <ul>
87 %   foreach my $link ( @$submenu ) {
88       <li><% $link %></li>
89 %   }
90     </ul>
91   </li>
92 % }
93 </ul>
94
95 <%init>
96 my %opt = @_;
97 my $cust_main = $opt{'cust_main'};
98 my $custnum = $cust_main->custnum;
99 my $curuser = $FS::CurrentUser::CurrentUser;
100 my $conf = FS::Conf->new;
101
102 my %payby = map { $_ => 1 } $conf->config('payby');
103
104 # nice declarative menu; should be a parameter to some kind of menu generator
105 my @menu = ( 
106   [
107     { show        => 'basics',
108       label       => 'Basics',
109     },
110     {
111       label       => 'Edit customer',
112       url         => 'edit/cust_main.cgi?$custnum',
113       acl         => 'Edit customer'
114     },
115     {
116       label       => 'Edit contacts',
117       url         => 'edit/cust_main-contacts.html?$custnum',
118     },
119 # separator
120     {
121       label       => 'Bill now',
122       acl         => 'Bill customer now',
123       content     => sub { include( '/elements/bill.html',
124                               label   => emt('Bill now'),
125                               url     => $cgi->self_url,
126                               custnum => shift->custnum,
127                            ),
128                      },
129     },
130     {
131       label       => 'Suspend',
132       popup       => 'misc/suspend_cust.html?custnum=$custnum',
133       acl         => 'Suspend customer',
134       condition   => sub { shift->unsuspended_pkgs > 0 },
135       actionlabel => 'Confirm Suspension',
136       color       => '#ff9900',
137     },
138     {
139       label       => 'Unsuspend',
140       popup       => 'misc/unsuspend_cust.html?custnum=$custnum',
141       acl         => 'Unsuspend customer',
142       condition   => sub { shift->suspended_pkgs > 0 },
143       actionlabel => 'Confirm Unsuspension',
144     },
145     {
146       label       => 'Cancel',
147       popup       => 'misc/suspend_cust.html?custnum=$custnum',
148       acl         => 'Cancel customer',
149       condition   => sub { shift->ncancelled_pkgs > 0 },
150       actionlabel => 'Confirm Cancellation',
151       color       => '#ff0000',
152     },
153     {
154       label       => 'Merge',
155       popup       => 'misc/merge_cust.html?custnum=$custnum',
156       acl         => 'Merge customer',
157       actionlabel => 'Merge customer',
158       width       => 569,
159       height      => 210,
160     },
161     {
162       label       => 'Refer a new customer',
163       url         => 'edit/cust_main.cgi?referral_custnum=$custnum',
164       confexists  => '!disable_customer_referrals',
165     },
166 # should have a separator here
167     {
168       label       => 'View this customer\'s referrals',
169       url         => 'search/cust_main.cgi?referral_custnum=$custnum',
170       confexists  => '!disable_customer_referrals',
171       condition   => sub {
172         FS::cust_main->count('referral_custnum = ?', shift->custnum) > 0
173       },
174     },
175     {
176       label       => 'View billing events',
177       url         => 'search/cust_event.html?custnum=$custnum',
178       acl         => [ 'Billing event reports',
179                        'View customer billing events' ],
180     },
181     {
182       label       => 'Email a notice to this customer',
183       url         => sub {
184                       my $cust_main = shift;
185                       my $agentnum = $cust_main->agentnum;
186                       'misc/email-customers.html?table=cust_main;search_hash='.
187                       'agent_virt_agentnum='.$agentnum.';custnum=$custnum';
188                      },
189       condition   => sub { shift->invoicing_list_emailonly },
190     },
191   ],
192   [
193     {
194       label => 'Notes',
195       show  => 'notes',
196     },
197     {
198       label       => 'Add note',
199       popup       => 'edit/cust_main_note.cgi?custnum=$custnum',
200       actionlabel => 'Add note',
201       confexists  => '!cust_main-disable_notes',
202       acl         => 'Add customer note',
203       width       => 616,
204       height      => 538,
205     },
206     {
207       label       => 'Attach file',
208       popup       => 'edit/cust_main_attach.cgi?custnum=$custnum',
209       actionlabel => 'Upload file',
210       confexists  => '!disable_cust_attachment',
211       acl         => 'Add attachment',
212       width       => 480,
213       height      => 296,
214     },
215   ],
216   [
217     {
218       label => 'Tickets',
219       show  => 'tickets',
220       confexists => 'ticket_system'
221     },
222   ],
223   [
224     {
225       label => 'Appointments',
226       show  => 'appointments',
227       confexists => 'ticket_system',
228       acl   => 'View appointments',
229     },
230   ],
231   [
232     {
233       label => 'Quotations',
234       show  => 'quotations',
235     },
236     {
237       label => 'Add quotation',
238       url   => 'edit/quotation.html?custnum=$custnum',
239       acl   => 'Generate quotation',
240     },
241   ],
242   [
243     {
244       label => 'Packages',
245       show  => 'packages',
246     },
247     {
248       label       => 'New qualification',
249       popup       => 'misc/qual.html?custnum=$custnum',
250       actionlabel => 'New qualification',
251       color       => '#333399',
252       width       => 763,
253       height      => 436,
254       acl         => 'Qualify service',
255     },
256     {
257       label       => 'Order new package',
258       popup       => 'misc/order_pkg.html?custnum=$custnum',
259       actionlabel => 'Order new package',
260       color       => '#333399',
261       width       => 960,
262       height      => 740,
263       acl         => 'Order customer package',
264     },
265     {
266       # it's just a popup, but there's some freaky CCH tax stuff in it
267       label       => 'One-time charge',
268       content     => sub {
269                       include( '/elements/one_time_charge_link.html',
270                         custnum => shift->custnum,
271                       );
272                      },
273       acl         => 'One-time charge',
274     },
275     {
276       label       => 'Move services between packages',
277       popup       => 'edit/bulk-cust_svc-pkgnum.html?custnum=$custnum',
278       actionlabel => 'Move services',
279       width       => 968,
280       height      => 575,
281       acl         => 'Bulk move customer services',
282     },
283     {
284       label       => 'Bulk order and cancel packages',
285       url         => 'edit/cust_pkg.cgi?$custnum',
286       acl         => 'Bulk change customer packages',
287     },
288 # separator
289     {
290       label => 'Package reports',
291       url   => 'search/report_cust_pkg?custnum=$custnum',
292     },
293     {
294       label => 'View qualifications',
295       url   => 'search/qual.cgi?custnum=$custnum',
296       acl   => 'Qualify service',
297     },
298     {
299       label => 'View accounts',
300       url   => 'search/report_svc_acct.html?custnum=$custnum',
301     },
302     {
303       label => 'View CDRs',
304       url   => 'search/report_cdr.html?custnum=$custnum',
305     },
306   ],
307   [
308     {
309       label => 'Payment History',
310       show  => 'payment_history',
311     },
312     # manual payment entry via edit/cust_pay
313     {
314       label       => 'Enter check payment',
315       popup       => 'edit/cust_pay.cgi?popup=1;payby=BILL;custnum=$custnum',
316       actionlabel => 'Enter check payment',
317       width       => 763,
318       height      => 392,
319       acl         => [ 'Post payment', 'Post check payment' ],
320       condition   => sub { $payby{BILL} },
321     },
322     {
323       label       => 'Enter cash payment',
324       popup       => 'edit/cust_pay.cgi?popup=1;payby=CASH;custnum=$custnum',
325       actionlabel => 'Enter cash payment',
326       width       => 763,
327       height      => 392,
328       acl         => [ 'Post payment', 'Post cash payment' ],
329       condition   => sub { $payby{CASH} },
330     },
331     {
332       label       => 'Enter Western Union payment',
333       popup       => 'edit/cust_pay.cgi?popup=1;payby=WEST;custnum=$custnum',
334       actionlabel => 'Enter Western Union payment',
335       width       => 763,
336       height      => 392,
337       acl         => [ 'Post payment', ],
338       condition   => sub { $payby{WEST} },
339     },
340     {
341       label       => 'Post manual (offline/POS) credit card payment',
342       popup       => 'edit/cust_pay.cgi?popup=1;payby=MCRD;custnum=$custnum',
343       actionlabel => 'Enter credit card payment',
344       width       => 763,
345       height      => 392,
346       acl         => [ 'Post payment', ],
347       condition   => sub { $payby{MCRD} },
348     },
349     {
350       label       => 'Post manual (offline/POS) electronic check',
351       popup       => 'edit/cust_pay.cgi?popup=1;payby=MCHK;custnum=$custnum',
352       actionlabel => 'Enter credit card payment',
353       width       => 763,
354       height      => 392,
355       acl         => [ 'Post payment', ],
356       condition   => sub { $payby{MCHK} },
357     },
358     # realtime payments via payment.cgi
359     {
360       label       => 'Process credit card payment',
361       url         => 'misc/payment.cgi?payby=CARD;custnum=$custnum',
362       acl         => [ 'Process payment', 'Process credit card payment', ],
363       condition   => sub { $payby{CARD} or $payby{DCRD} },
364     },
365     {
366       label       => 'Process electronic check payment',
367       url         => 'misc/payment.cgi?payby=CHEK;custnum=$custnum',
368       acl         => [ 'Process payment', 'Process Echeck payment', ],
369       condition   => sub { $payby{CHEK} or $payby{DCHK} },
370     },
371 #separator?
372     {
373       label       => 'Enter credit',
374       popup       => 'edit/cust_credit.cgi?custnum=$custnum',
375       actionlabel => 'Enter credit',
376       width       => 763,
377       acl         => 'Post credit',
378     },
379     {
380       label       => 'Credit line items',
381       popup       => 'edit/credit-cust_bill_pkg.html?custnum=$custnum',
382       actionlabel => 'Credit line items',
383       width       => 968,
384       height      => 575,
385       acl         => 'Credit line items',
386       condition   => sub {
387         FS::cust_bill->count('custnum = ?', shift->custnum) > 0
388       },
389     },
390     {
391       label       => 'Enter check refund',
392       popup       => 'edit/cust_refund.cgi?popup=1;payby=BILL;custnum=$custnum',
393       actionlabel => 'Enter check refund',
394       width       => 440,
395       acl         => ['Post refund', 'Post check refund'],
396       condition   => sub { $payby{BILL} },
397     },
398     {
399       label       => 'Enter cash refund',
400       popup       => 'edit/cust_refund.cgi?popup=1;payby=CASH;custnum=$custnum',
401       actionlabel => 'Enter cash refund',
402       width       => 392,
403       acl         => ['Post refund', 'Post cash refund'],
404       condition   => sub { $payby{CASH} },
405     },
406     {
407       label       => 'Enter manual (offline/POS) credit card refund',
408       popup       => 'edit/cust_refund.cgi?popup=1;payby=MCRD;custnum=$custnum',
409       actionlabel => 'Enter credit card refund',
410       width       => 440,
411       acl         => ['Post refund' ],
412       condition   => sub { $payby{MCRD} },
413     },
414     {
415       label       => 'Enter manual (offline/POS) electronic check refund',
416       popup       => 'edit/cust_refund.cgi?popup=1;payby=MCHK;custnum=$custnum',
417       actionlabel => 'Enter electronic check refund',
418       width       => 440,
419       acl         => ['Post refund' ],
420       condition   => sub { $payby{MCHK} },
421     },
422     {
423       label       => 'Add tax adjustment',
424       popup       => 'edit/cust_tax_adjustment.html?custnum=$custnum',
425       actionlabel => 'Add tax adjustment',
426       height      => 200,
427       confexists  => 'enable_tax_adjustments',
428       acl         => 'Add customer tax adjustment',
429     },
430 # separator, definitely
431     {
432       label       => 'Download statement',
433       url         => 'view/cust_main_statement-pdf.cgi?$custnum',
434       acl         => 'List invoices',
435       condition   => sub {
436         FS::cust_bill->count('custnum = ?', shift->custnum) > 0
437       },
438     },
439     {
440       label       => 'Search invoices',
441       url         => 'search/report_cust_bill.html?custnum=$custnum',
442       acl         => 'List invoices',
443     },
444     {
445       label       => 'View tax exemptions',
446       url         => 'search/cust_tax_exempt_pkg.cgi?custnum=$custnum',
447       acl         => 'View customer tax exemptions',
448     },
449     {
450       label       => 'View tax adjustments',
451       url         => 'search/cust_tax_adjustment.html?custnum=$custnum',
452       confexists  => 'enable_tax_adjustments',
453       acl         => 'Add customer tax adjustment',
454     },
455     {
456       label       => 'View pending payments',
457       url         => 'search/cust_pay_pending.html?magic=_date;statusNOT=done;custnum=$custnum',
458       acl         => 'View pending payments',
459       condition   => sub { 
460         FS::cust_pay_pending->count('custnum = ?', shift->custnum) > 0
461       },
462     },
463   ],
464   [
465     {
466       label => 'Change History',
467       show  => 'change_history',
468       acl   => 'View customer history',
469     },
470   ],
471 );
472
473
474 my @processed_menu;
475 foreach my $submenu (@menu) {
476
477   my @links;
478   my $first = 1;
479   foreach my $entry ( @$submenu ) {
480     # if the menu head was skipped, skip the whole menu
481     last if (!$first and !@links);
482     $first = 0;
483
484     # check conditions
485     if ( $entry->{acl} ) {
486       next unless $curuser->access_right( $entry->{acl} );
487     }
488     if ( $entry->{confexists} ) {
489       if ( $entry->{confexists} =~ /^!(.*)/ ) {
490         # confexists => !foo, a negative condition
491         next if $conf->exists( $1 );
492       } else {
493         next unless $conf->exists( $entry->{confexists} );
494       }
495     }
496     if ( $entry->{condition} ) {
497       next unless &{ $entry->{condition} }($cust_main);
498     }
499
500     my $label = emt($entry->{label});
501     my $target = $entry->{content}
502               || $entry->{popup}
503               || $entry->{url};
504
505     if ( ref($target) eq 'CODE' ) {
506       $target = &$target($cust_main);
507     }
508     my $a = '';
509
510     if ( $entry->{content} ) { # then the coderef specified the whole thing
511       $a = $target;
512
513     } elsif ( $entry->{show} ) {
514
515       # the menu head: always a link back to this page
516       $cgi->param('show', $entry->{show});
517             $target = $cgi->self_url;
518
519       $a = qq[ <A HREF="$target"];
520       if ( $opt{'show'} eq $entry->{show} ) {
521         $a .= ' class="current_show"';
522       }
523       $a .= qq[>$label</A> ];
524
525
526     } elsif ( $entry->{popup} ) {
527
528       $target =~ s/\$custnum/$custnum/g;
529       $target = $p.$target;
530       $a = include('/elements/popup_link.html',
531         action  => $target,
532         width   => 616,
533         height  => 410,
534         %$entry,
535         label   => emt($label),
536       );
537
538     } elsif ( $entry->{url} ) {
539
540       $target =~ s/\$custnum/$custnum/g;
541       $target = $p.$target;
542       $a = qq[ <A HREF="$target">$label</A> ];
543     }
544
545     push @links, $a;
546
547   } # foreach $entry
548   if (@links) {
549     push @processed_menu, \@links;
550   }
551 }
552 </%init>