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