1 <style type="text/css">
10 border-right: 4px solid #e8e8e8;
20 -moz-border-radius-topleft:8px;
21 -moz-border-radius-topright:8px;
22 -webkit-border-radius-topleft:8px;
23 -webkit-border-radius-topright:8px;
24 border-top-left-radius:8px;
25 border-top-right-radius:8px;
36 border: 1px solid #ffffff;
51 background: transparent;
55 -moz-border-radius-topleft:0px;
56 -moz-border-radius-topright:0px;
57 -webkit-border-radius-topleft:0px;
58 -webkit-border-radius-topright:0px;
59 border-top-left-radius:0px;
60 border-top-right-radius:0px;
63 #menu_ul a.current_menu, #menu_ul a.hover {
68 <script src="<% $p %>elements/jquery.js"></script>
69 <script type="text/javascript">
70 $(document).ready(function() {
71 $('#menu_ul > li').hover(function(){
72 $('a:first', this).addClass('hover');
73 $('ul:first', this).show();
74 if ($('.current_menu:first', this).length == 0) {
75 $('img[src*="dropdown_arrow_white"]', this).show();
76 $('img[src*="dropdown_arrow_grey"]', this).hide();
79 $('ul:first', this).hide();
80 $('a:first', this).removeClass('hover');
81 if ($('.current_menu:first', this).length == 0) {
82 $('img[src*="dropdown_arrow_white"]', this).hide();
83 $('img[src*="dropdown_arrow_grey"]', this).show();
90 % foreach my $submenu (@processed_menu) {
94 % foreach my $link ( @$submenu ) {
104 my $cust_main = $opt{'cust_main'};
105 my $custnum = $cust_main->custnum;
106 my $curuser = $FS::CurrentUser::CurrentUser;
107 my $conf = FS::Conf->new;
109 my %payby = map { $_ => 1 } $conf->config('payby');
111 # nice declarative menu; should be a parameter to some kind of menu generator
118 label => 'Edit customer',
119 url => 'edit/cust_main.cgi?$custnum',
120 acl => 'Edit customer'
123 label => 'Edit contacts',
124 url => 'edit/cust_main-contacts.html?$custnum',
129 acl => 'Bill customer now',
130 content => sub { include( '/elements/bill.html',
131 label => emt('Bill now'),
132 url => $cgi->self_url,
133 custnum => shift->custnum,
139 popup => 'misc/suspend_cust.html?custnum=$custnum',
140 acl => 'Suspend customer',
141 condition => sub { shift->unsuspended_pkgs > 0 },
142 actionlabel => 'Confirm Suspension',
146 label => 'Unsuspend',
147 popup => 'misc/unsuspend_cust.html?custnum=$custnum',
148 acl => 'Unsuspend customer',
149 condition => sub { shift->suspended_pkgs > 0 },
150 actionlabel => 'Confirm Unsuspension',
154 popup => 'misc/suspend_cust.html?custnum=$custnum',
155 acl => 'Cancel customer',
156 condition => sub { shift->ncancelled_pkgs > 0 },
157 actionlabel => 'Confirm Cancellation',
162 popup => 'misc/merge_cust.html?custnum=$custnum',
163 acl => 'Merge customer',
164 actionlabel => 'Merge customer',
169 label => 'Refer a new customer',
170 url => 'edit/cust_main.cgi?referral_custnum=$custnum',
171 confexists => '!disable_customer_referrals',
173 # should have a separator here
175 label => 'View this customer\'s referrals',
176 url => 'search/cust_main.cgi?referral_custnum=$custnum',
177 confexists => '!disable_customer_referrals',
179 FS::cust_main->count('referral_custnum = ?', shift->custnum) > 0
183 label => 'View billing events',
184 url => 'search/cust_event.html?custnum=$custnum',
185 acl => [ 'Billing event reports',
186 'View customer billing events' ],
189 label => 'Email a notice to this customer',
191 my $cust_main = shift;
192 my $agentnum = $cust_main->agentnum;
193 'misc/email-customers.html?table=cust_main;search_hash='.
194 'agent_virt_agentnum='.$agentnum.';custnum=$custnum';
196 condition => sub { shift->invoicing_list_emailonly },
206 popup => 'edit/cust_main_note.cgi?custnum=$custnum',
207 actionlabel => 'Add note',
208 confexists => '!cust_main-disable_notes',
209 acl => 'Add customer note',
214 label => 'Attach file',
215 popup => 'edit/cust_main_attach.cgi?custnum=$custnum',
216 actionlabel => 'Upload file',
217 confexists => '!disable_cust_attachment',
218 acl => 'Add attachment',
227 confexists => 'ticket_system'
232 label => 'Appointments',
233 show => 'appointments',
234 confexists => 'ticket_system',
235 acl => 'View appointments',
240 label => 'Quotations',
241 show => 'quotations',
244 label => 'Add quotation',
245 url => 'edit/quotation.html?custnum=$custnum',
246 acl => 'Generate quotation',
255 label => 'New qualification',
256 popup => 'misc/qual.html?custnum=$custnum',
257 actionlabel => 'New qualification',
261 acl => 'Qualify service',
264 label => 'Order new package',
265 popup => 'misc/order_pkg.html?custnum=$custnum',
266 actionlabel => 'Order new package',
270 acl => 'Order customer package',
273 # it's just a popup, but there's some freaky CCH tax stuff in it
274 label => 'One-time charge',
276 include( '/elements/one_time_charge_link.html',
277 custnum => shift->custnum,
280 acl => 'One-time charge',
283 label => 'Move services between packages',
284 popup => 'edit/bulk-cust_svc-pkgnum.html?custnum=$custnum',
285 actionlabel => 'Move services',
288 acl => 'Bulk move customer services',
291 label => 'Bulk order and cancel packages',
292 url => 'edit/cust_pkg.cgi?$custnum',
293 acl => 'Bulk change customer packages',
297 label => 'Package reports',
298 url => 'search/report_cust_pkg?custnum=$custnum',
301 label => 'View qualifications',
302 url => 'search/qual.cgi?custnum=$custnum',
303 acl => 'Qualify service',
306 label => 'View accounts',
307 url => 'search/report_svc_acct.html?custnum=$custnum',
310 label => 'View CDRs',
311 url => 'search/report_cdr.html?custnum=$custnum',
316 label => 'Payment History',
317 show => 'payment_history',
319 # manual payment entry via edit/cust_pay
321 label => 'Enter check payment',
322 popup => 'edit/cust_pay.cgi?popup=1;payby=BILL;custnum=$custnum',
323 actionlabel => 'Enter check payment',
326 acl => [ 'Post payment', 'Post check payment' ],
327 condition => sub { $payby{BILL} },
330 label => 'Enter cash payment',
331 popup => 'edit/cust_pay.cgi?popup=1;payby=CASH;custnum=$custnum',
332 actionlabel => 'Enter cash payment',
335 acl => [ 'Post payment', 'Post cash payment' ],
336 condition => sub { $payby{CASH} },
339 label => 'Enter Western Union payment',
340 popup => 'edit/cust_pay.cgi?popup=1;payby=WEST;custnum=$custnum',
341 actionlabel => 'Enter Western Union payment',
344 acl => [ 'Post payment', ],
345 condition => sub { $payby{WEST} },
348 label => 'Post manual (offline/POS) credit card payment',
349 popup => 'edit/cust_pay.cgi?popup=1;payby=MCRD;custnum=$custnum',
350 actionlabel => 'Enter credit card payment',
353 acl => [ 'Post payment', ],
354 condition => sub { $payby{MCRD} },
357 label => 'Post manual (offline/POS) electronic check',
358 popup => 'edit/cust_pay.cgi?popup=1;payby=MCHK;custnum=$custnum',
359 actionlabel => 'Enter credit card payment',
362 acl => [ 'Post payment', ],
363 condition => sub { $payby{MCHK} },
365 # realtime payments via payment.cgi
367 label => 'Process credit card payment',
368 url => 'misc/payment.cgi?payby=CARD;custnum=$custnum',
369 acl => [ 'Process payment', 'Process credit card payment', ],
370 condition => sub { $payby{CARD} or $payby{DCRD} },
373 label => 'Process electronic check payment',
374 url => 'misc/payment.cgi?payby=CHEK;custnum=$custnum',
375 acl => [ 'Process payment', 'Process Echeck payment', ],
376 condition => sub { $payby{CHEK} or $payby{DCHK} },
380 label => 'Enter credit',
381 popup => 'edit/cust_credit.cgi?custnum=$custnum',
382 actionlabel => 'Enter credit',
384 acl => 'Post credit',
387 label => 'Credit line items',
388 popup => 'edit/credit-cust_bill_pkg.html?custnum=$custnum',
389 actionlabel => 'Credit line items',
392 acl => 'Credit line items',
394 FS::cust_bill->count('custnum = ?', shift->custnum) > 0
398 label => 'Enter check refund',
399 popup => 'edit/cust_refund.cgi?popup=1;payby=BILL;custnum=$custnum',
400 actionlabel => 'Enter check refund',
402 acl => ['Post refund', 'Post check refund'],
403 condition => sub { $payby{BILL} },
406 label => 'Enter cash refund',
407 popup => 'edit/cust_refund.cgi?popup=1;payby=CASH;custnum=$custnum',
408 actionlabel => 'Enter cash refund',
410 acl => ['Post refund', 'Post cash refund'],
411 condition => sub { $payby{CASH} },
414 label => 'Enter manual (offline/POS) credit card refund',
415 popup => 'edit/cust_refund.cgi?popup=1;payby=MCRD;custnum=$custnum',
416 actionlabel => 'Enter credit card refund',
418 acl => ['Post refund' ],
419 condition => sub { $payby{MCRD} },
422 label => 'Enter manual (offline/POS) electronic check refund',
423 popup => 'edit/cust_refund.cgi?popup=1;payby=MCHK;custnum=$custnum',
424 actionlabel => 'Enter electronic check refund',
426 acl => ['Post refund' ],
427 condition => sub { $payby{MCHK} },
430 label => 'Add tax adjustment',
431 popup => 'edit/cust_tax_adjustment.html?custnum=$custnum',
432 actionlabel => 'Add tax adjustment',
434 confexists => 'enable_tax_adjustments',
435 acl => 'Add customer tax adjustment',
437 # separator, definitely
439 label => 'Download statement',
440 url => 'view/cust_main_statement-pdf.cgi?$custnum',
441 acl => 'List invoices',
443 FS::cust_bill->count('custnum = ?', shift->custnum) > 0
447 label => 'Search invoices',
448 url => 'search/report_cust_bill.html?custnum=$custnum',
449 acl => 'List invoices',
452 label => 'View tax exemptions',
453 url => 'search/cust_tax_exempt_pkg.cgi?custnum=$custnum',
454 acl => 'View customer tax exemptions',
457 label => 'View tax adjustments',
458 url => 'search/cust_tax_adjustment.html?custnum=$custnum',
459 confexists => 'enable_tax_adjustments',
460 acl => 'Add customer tax adjustment',
463 label => 'View pending payments',
464 url => 'search/cust_pay_pending.html?magic=_date;statusNOT=done;custnum=$custnum',
465 acl => 'View pending payments',
467 FS::cust_pay_pending->count('custnum = ?', shift->custnum) > 0
473 label => 'Change History',
474 show => 'change_history',
475 acl => 'View customer history',
482 foreach my $submenu (@menu) {
486 foreach my $entry ( @$submenu ) {
487 # if the menu head was skipped, skip the whole menu
488 last if (!$first and !@links);
492 if ( $entry->{acl} ) {
493 next unless $curuser->access_right( $entry->{acl} );
495 if ( $entry->{confexists} ) {
496 if ( $entry->{confexists} =~ /^!(.*)/ ) {
497 # confexists => !foo, a negative condition
498 next if $conf->exists( $1 );
500 next unless $conf->exists( $entry->{confexists} );
503 if ( $entry->{condition} ) {
504 next unless &{ $entry->{condition} }($cust_main);
507 my $label = emt($entry->{label});
508 my $target = $entry->{content}
512 if ( ref($target) eq 'CODE' ) {
513 $target = &$target($cust_main);
517 if ( $entry->{content} ) { # then the coderef specified the whole thing
520 } elsif ( $entry->{show} ) {
522 # the menu head: always a link back to this page
523 $cgi->param('show', $entry->{show});
524 $target = $cgi->self_url;
526 $a = qq[ <A HREF="$target"];
527 if ( $opt{'show'} eq $entry->{show} ) {
528 $a .= ' class="fstabselected"';
530 $a .= qq[>$label</A> ];
533 } elsif ( $entry->{popup} ) {
535 $target =~ s/\$custnum/$custnum/g;
536 $target = $p.$target;
537 $a = include('/elements/popup_link.html',
542 label => emt($label),
545 } elsif ( $entry->{url} ) {
547 $target =~ s/\$custnum/$custnum/g;
548 $target = $p.$target;
549 $a = qq[ <A HREF="$target">$label</A> ];
556 push @processed_menu, \@links;