RT#34078: Payment History Report / Statement
[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;search_hash='.
201                       'agent_virt_agentnum='.$agentnum.";custnum=$custnum";
202                      },
203       condition   => sub { $invoicing_list_emailonly },
204       acl         => 'Bulk send customer notices',
205     },
206   ],
207   [
208     {
209       label => 'Notes',
210       show  => 'notes',
211     },
212     {
213       label       => 'Add note',
214       popup       => "edit/cust_main_note.cgi?custnum=$custnum",
215       actionlabel => 'Add note',
216       confexists  => '!cust_main-disable_notes',
217       acl         => 'Add customer note',
218       width       => 616,
219       height      => 538,
220     },
221     {
222       label       => 'Attach file',
223       popup       => "edit/cust_main_attach.cgi?custnum=$custnum",
224       actionlabel => 'Upload file',
225       confexists  => '!disable_cust_attachment',
226       acl         => 'Add attachment',
227       width       => 480,
228       height      => 296,
229     },
230   ],
231   [
232     {
233       label => 'Tickets',
234       show  => 'tickets',
235       confexists => 'ticket_system'
236     },
237   ],
238   [
239     {
240       label => 'Appointments',
241       show  => 'appointments',
242       confexists => 'ticket_system',
243       acl   => 'View appointments',
244     },
245     {
246       label       => 'Schedule new appointment',
247       confexists  => 'ticket_system',
248       acl        => 'Make appointment',
249       popup       => "elements/make_appointment.html?custnum=$custnum",
250       actionlabel => 'Schedule appointment',
251     },
252   ],
253   [
254     {
255       label => 'Quotations',
256       show  => 'quotations',
257     },
258     {
259       label => 'Create new quotation',
260       url   => "edit/quotation.html?custnum=$custnum",
261       acl   => 'Generate quotation',
262     },
263   ],
264   [
265     {
266       label => 'Packages',
267       show  => 'packages',
268     },
269     {
270       label       => 'New qualification',
271       popup       => "misc/qual.html?custnum=$custnum",
272       actionlabel => 'New qualification',
273       color       => '#333399',
274       width       => 763,
275       height      => 436,
276       acl         => 'Qualify service',
277     },
278     {
279       label       => 'Order new package',
280       popup       => "misc/order_pkg.html?custnum=$custnum",
281       actionlabel => 'Order new package',
282       color       => '#333399',
283       width       => 960,
284       height      => 740,
285       acl         => 'Order customer package',
286     },
287     {
288       # it's just a popup, but there's some freaky CCH tax stuff in it
289       label       => 'One-time charge',
290       content     => sub {
291                       include( '/elements/one_time_charge_link.html',
292                         custnum => shift->custnum,
293                       );
294                      },
295       acl         => 'One-time charge',
296     },
297     {
298       label       => 'Move services between packages',
299       popup       => "edit/bulk-cust_svc-pkgnum.html?custnum=$custnum",
300       actionlabel => 'Move services',
301       width       => 968,
302       height      => 575,
303       acl         => 'Bulk move customer services',
304     },
305     {
306       label       => 'Bulk order and cancel packages',
307       url         => "edit/cust_pkg.cgi?$custnum",
308       acl         => 'Bulk change customer packages',
309     },
310 # separator
311     {
312       label => 'Package reports',
313       url   => "search/report_cust_pkg?custnum=$custnum",
314     },
315     {
316       label => 'View qualifications',
317       url   => "search/qual.cgi?custnum=$custnum",
318       acl   => 'Qualify service',
319     },
320     {
321       label => 'View accounts',
322       url   => "search/report_svc_acct.html?custnum=$custnum",
323     },
324     {
325       label => 'View CDRs',
326       url   => "search/report_cdr.html?custnum=$custnum",
327     },
328   ],
329   [
330     {
331       label => 'Payment History',
332       show  => 'payment_history',
333     },
334     # manual payment entry via edit/cust_pay
335     {
336       label       => 'Enter check payment',
337       popup       => "edit/cust_pay.cgi?popup=1;payby=BILL;custnum=$custnum",
338       actionlabel => 'Enter check payment',
339       width       => 763,
340       height      => 392,
341       acl         => [ 'Post payment', 'Post check payment' ],
342       condition   => sub { $payby{BILL} },
343     },
344     {
345       label       => 'Enter cash payment',
346       popup       => "edit/cust_pay.cgi?popup=1;payby=CASH;custnum=$custnum",
347       actionlabel => 'Enter cash payment',
348       width       => 763,
349       height      => 392,
350       acl         => [ 'Post payment', 'Post cash payment' ],
351       condition   => sub { $payby{CASH} },
352     },
353     {
354       label       => 'Enter Western Union payment',
355       popup       => "edit/cust_pay.cgi?popup=1;payby=WEST;custnum=$custnum",
356       actionlabel => 'Enter Western Union payment',
357       width       => 763,
358       height      => 392,
359       acl         => [ 'Post payment', ],
360       condition   => sub { $payby{WEST} },
361     },
362     {
363       label       => 'Post manual (offline/POS) credit card payment',
364       popup       => "edit/cust_pay.cgi?popup=1;payby=MCRD;custnum=$custnum",
365       actionlabel => 'Enter credit card payment',
366       width       => 763,
367       height      => 392,
368       acl         => [ 'Post payment', ],
369       condition   => sub { $payby{MCRD} },
370     },
371     {
372       label       => 'Post manual (offline/POS) electronic check',
373       popup       => "edit/cust_pay.cgi?popup=1;payby=MCHK;custnum=$custnum",
374       actionlabel => 'Enter credit card payment',
375       width       => 763,
376       height      => 392,
377       acl         => [ 'Post payment', ],
378       condition   => sub { $payby{MCHK} },
379     },
380     # realtime payments via payment.cgi
381     {
382       label       => 'Process credit card payment',
383       url         => "misc/payment.cgi?payby=CARD;custnum=$custnum",
384       acl         => [ 'Process payment', 'Process credit card payment', ],
385       condition   => sub { $payby{CARD} or $payby{DCRD} },
386     },
387     {
388       label       => 'Process electronic check payment',
389       url         => "misc/payment.cgi?payby=CHEK;custnum=$custnum",
390       acl         => [ 'Process payment', 'Process Echeck payment', ],
391       condition   => sub { $payby{CHEK} or $payby{DCHK} },
392     },
393 #separator?
394     {
395       label       => 'Enter credit',
396       popup       => "edit/cust_credit.cgi?custnum=$custnum",
397       actionlabel => 'Enter credit',
398       width       => 763,
399       acl         => 'Post credit',
400     },
401     {
402       label       => 'Credit line items',
403       popup       => "edit/credit-cust_bill_pkg.html?custnum=$custnum",
404       actionlabel => 'Credit line items',
405       width       => 968,
406       height      => 575,
407       acl         => 'Credit line items',
408       condition   => sub {
409         FS::cust_bill->count('custnum = ?', shift->custnum) > 0
410       },
411     },
412     {
413       label       => 'Enter check refund',
414       popup       => "edit/cust_refund.cgi?popup=1;payby=BILL;custnum=$custnum",
415       actionlabel => 'Enter check refund',
416       width       => 440,
417       acl         => ['Post refund', 'Post check refund'],
418       condition   => sub { $payby{BILL} },
419     },
420     {
421       label       => 'Enter cash refund',
422       popup       => "edit/cust_refund.cgi?popup=1;payby=CASH;custnum=$custnum",
423       actionlabel => 'Enter cash refund',
424       width       => 392,
425       acl         => ['Post refund', 'Post cash refund'],
426       condition   => sub { $payby{CASH} },
427     },
428     {
429       label       => 'Enter manual (offline/POS) credit card refund',
430       popup       => "edit/cust_refund.cgi?popup=1;payby=MCRD;custnum=$custnum",
431       actionlabel => 'Enter credit card refund',
432       width       => 440,
433       acl         => ['Post refund' ],
434       condition   => sub { $payby{MCRD} },
435     },
436     {
437       label       => 'Enter manual (offline/POS) electronic check refund',
438       popup       => "edit/cust_refund.cgi?popup=1;payby=MCHK;custnum=$custnum",
439       actionlabel => 'Enter electronic check refund',
440       width       => 440,
441       acl         => ['Post refund' ],
442       condition   => sub { $payby{MCHK} },
443     },
444     {
445       label       => 'Add tax adjustment',
446       popup       => "edit/cust_tax_adjustment.html?custnum=$custnum",
447       actionlabel => 'Add tax adjustment',
448       height      => 200,
449       confexists  => 'enable_tax_adjustments',
450       acl         => 'Add customer tax adjustment',
451     },
452 # separator, definitely
453     {
454       label       => 'Download statement',
455       url         => "view/cust_main_statement-pdf.cgi?$custnum",
456       acl         => 'List invoices',
457       condition   => sub {
458         FS::cust_bill->count('custnum = ?', shift->custnum) > 0
459       },
460     },
461     {
462       label       => 'Search invoices',
463       url         => "search/report_cust_bill.html?custnum=$custnum",
464       acl         => 'List invoices',
465     },
466     {
467       label       => 'View tax exemptions',
468       url         => "search/cust_tax_exempt_pkg.cgi?custnum=$custnum",
469       acl         => 'View customer tax exemptions',
470     },
471     {
472       label       => 'View tax adjustments',
473       url         => "search/cust_tax_adjustment.html?custnum=$custnum",
474       confexists  => 'enable_tax_adjustments',
475       acl         => 'Add customer tax adjustment',
476     },
477     {
478       label       => 'View pending payments',
479       url         => "search/cust_pay_pending.html?magic=_date;statusNOT=done;custnum=$custnum",
480       acl         => 'View pending payments',
481       condition   => sub { 
482         FS::cust_pay_pending->count('custnum = ?', shift->custnum) > 0
483       },
484     },
485     {
486       label       => 'Email payment history to this customer',
487       url         => sub {
488                       my $cust_main = shift;
489                       my $agentnum = $cust_main->agentnum;
490                       'misc/email-customers-history.html?table=cust_main;search_hash='.
491                       'agent_virt_agentnum='.$agentnum.";custnum=$custnum;url=".
492                       uri_escape($cgi->self_url);
493                      },
494       condition   => sub { $invoicing_list_emailonly },
495       acl         => 'Bulk send customer notices',
496     },
497   ],
498   [
499     {
500       label => 'Change History',
501       show  => 'change_history',
502       acl   => 'View customer history',
503     },
504   ],
505 );
506
507
508 my @processed_menu;
509 foreach my $submenu (@menu) {
510
511   my @links;
512   my $first = 1;
513   foreach my $entry ( @$submenu ) {
514     # if the menu head was skipped, skip the whole menu
515     last if (!$first and !@links);
516     $first = 0;
517
518     # check conditions
519     if ( $entry->{acl} ) {
520       next unless $curuser->access_right( $entry->{acl} );
521     }
522     if ( $entry->{confexists} ) {
523       if ( $entry->{confexists} =~ /^!(.*)/ ) {
524         # confexists => !foo, a negative condition
525         next if $conf->exists( $1 );
526       } else {
527         next unless $conf->exists( $entry->{confexists} );
528       }
529     }
530     if ( $entry->{condition} ) {
531       next unless &{ $entry->{condition} }($cust_main);
532     }
533
534     my $label = emt($entry->{label});
535     my $target = $entry->{content}
536               || $entry->{popup}
537               || $entry->{url};
538
539     if ( ref($target) eq 'CODE' ) {
540       $target = &$target($cust_main);
541     }
542     my $a = '';
543
544     if ( $entry->{content} ) { # then the coderef specified the whole thing
545       $a = $target;
546
547     } elsif ( $entry->{show} ) {
548
549       # the menu head: always a link back to this page
550       $cgi->param('show', $entry->{show});
551             $target = $cgi->self_url;
552
553       $a = qq[ <A HREF="$target"];
554       if ( $opt{'show'} eq $entry->{show} ) {
555         $a .= ' class="current_show"';
556       }
557       $a .= qq[>$label</A> ];
558
559
560     } elsif ( $entry->{popup} ) {
561
562       $target =~ s/\$custnum/$custnum/g;
563       $target = $p.$target;
564       $a = include('/elements/popup_link.html',
565         action  => $target,
566         width   => 616,
567         height  => 410,
568         %$entry,
569         label   => emt($label),
570       );
571
572     } elsif ( $entry->{url} ) {
573
574       $target =~ s/\$custnum/$custnum/g;
575       $target = $p.$target;
576       $a = qq[ <A HREF="$target">$label</A> ];
577     }
578
579     push @links, $a;
580
581   } # foreach $entry
582   if (@links) {
583     push @processed_menu, \@links;
584   }
585 }
586 </%init>