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