1 <style type="text/css">
22 text-decoration: none;
23 border-bottom: thin solid #CFDFDF;
24 border-top-left-radius: .5em;
25 border-top-right-radius: .5em;
28 #menu_ul a.current_show {
31 border-top: thin solid #CFDEFF;
32 border-left: thin solid #CFDEFF;
33 border-right: thin solid #CFDEFF;
46 border-left: thin solid #CFDEFF;
47 border-right: thin solid #CFDEFF;
48 border-bottom: thin solid #CFDEFF;
59 background: transparent;
66 text-decoration: underline;
71 <script src="<% $p %>elements/jquery.js"></script>
72 <script type="text/javascript">
74 $(document).ready(function() {
76 function closemenu () {
77 if (openmenu !== undefined) {
82 $('#menu_ul > li').hover(function(){
84 openmenu = $('ul:first', this);
93 % foreach my $submenu (@processed_menu) {
97 % foreach my $link ( @$submenu ) {
107 my $cust_main = $opt{'cust_main'};
108 my $custnum = $cust_main->custnum;
109 my $curuser = $FS::CurrentUser::CurrentUser;
110 my $conf = FS::Conf->new;
112 my %payby = map { $_ => 1 } $conf->config('payby');
114 # nice declarative menu; should be a parameter to some kind of menu generator
121 label => 'Edit customer',
122 url => "edit/cust_main.cgi?$custnum",
123 acl => 'Edit customer'
126 label => 'Edit contacts',
127 url => "edit/cust_main-contacts.html?$custnum",
132 acl => 'Bill customer now',
133 content => sub { include( '/elements/bill.html',
134 label => emt('Bill now'),
135 url => $cgi->self_url,
136 custnum => shift->custnum,
142 popup => "misc/suspend_cust.html?custnum=$custnum",
143 acl => 'Suspend customer',
144 condition => sub { shift->unsuspended_pkgs > 0 },
145 actionlabel => 'Confirm Suspension',
149 label => 'Unsuspend',
150 popup => "misc/unsuspend_cust.html?custnum=$custnum",
151 acl => 'Unsuspend customer',
152 condition => sub { shift->suspended_pkgs > 0 },
153 actionlabel => 'Confirm Unsuspension',
157 popup => "misc/suspend_cust.html?custnum=$custnum",
158 acl => 'Cancel customer',
159 condition => sub { shift->ncancelled_pkgs > 0 },
160 actionlabel => 'Confirm Cancellation',
165 popup => "misc/merge_cust.html?custnum=$custnum",
166 acl => 'Merge customer',
167 actionlabel => 'Merge customer',
172 label => 'Refer a new customer',
173 url => "edit/cust_main.cgi?referral_custnum=$custnum",
174 confexists => '!disable_customer_referrals',
176 # should have a separator here
178 label => 'View this customer\'s referrals',
179 url => "search/cust_main.cgi?referral_custnum=$custnum",
180 confexists => '!disable_customer_referrals',
182 FS::cust_main->count('referral_custnum = ?', shift->custnum) > 0
186 label => 'View billing events',
187 url => "search/cust_event.html?custnum=$custnum",
188 acl => [ 'Billing event reports',
189 'View customer billing events' ],
192 label => 'Email a notice to this customer',
194 my $cust_main = shift;
195 my $agentnum = $cust_main->agentnum;
196 'misc/email-customers.html?table=cust_main;search_hash='.
197 'agent_virt_agentnum='.$agentnum.";custnum=$custnum";
199 condition => sub { shift->invoicing_list_emailonly },
209 popup => "edit/cust_main_note.cgi?custnum=$custnum",
210 actionlabel => 'Add note',
211 confexists => '!cust_main-disable_notes',
212 acl => 'Add customer note',
217 label => 'Attach file',
218 popup => "edit/cust_main_attach.cgi?custnum=$custnum",
219 actionlabel => 'Upload file',
220 confexists => '!disable_cust_attachment',
221 acl => 'Add attachment',
230 confexists => 'ticket_system'
235 label => 'Appointments',
236 show => 'appointments',
237 confexists => 'ticket_system',
238 acl => 'View appointments',
241 label => 'Schedule new appointment',
242 confexists => 'ticket_system',
243 acl => 'Make appointment',
244 popup => "elements/make_appointment.html?custnum=$custnum",
245 actionlabel => 'Schedule appointment',
250 label => 'Quotations',
251 show => 'quotations',
254 label => 'Add quotation',
255 url => "edit/quotation.html?custnum=$custnum",
256 acl => 'Generate quotation',
265 label => 'New qualification',
266 popup => "misc/qual.html?custnum=$custnum",
267 actionlabel => 'New qualification',
271 acl => 'Qualify service',
274 label => 'Order new package',
275 popup => "misc/order_pkg.html?custnum=$custnum",
276 actionlabel => 'Order new package',
280 acl => 'Order customer package',
283 # it's just a popup, but there's some freaky CCH tax stuff in it
284 label => 'One-time charge',
286 include( '/elements/one_time_charge_link.html',
287 custnum => shift->custnum,
290 acl => 'One-time charge',
293 label => 'Move services between packages',
294 popup => "edit/bulk-cust_svc-pkgnum.html?custnum=$custnum",
295 actionlabel => 'Move services',
298 acl => 'Bulk move customer services',
301 label => 'Bulk order and cancel packages',
302 url => "edit/cust_pkg.cgi?$custnum",
303 acl => 'Bulk change customer packages',
307 label => 'Package reports',
308 url => "search/report_cust_pkg?custnum=$custnum",
311 label => 'View qualifications',
312 url => "search/qual.cgi?custnum=$custnum",
313 acl => 'Qualify service',
316 label => 'View accounts',
317 url => "search/report_svc_acct.html?custnum=$custnum",
320 label => 'View CDRs',
321 url => "search/report_cdr.html?custnum=$custnum",
326 label => 'Payment History',
327 show => 'payment_history',
329 # manual payment entry via edit/cust_pay
331 label => 'Enter check payment',
332 popup => "edit/cust_pay.cgi?popup=1;payby=BILL;custnum=$custnum",
333 actionlabel => 'Enter check payment',
336 acl => [ 'Post payment', 'Post check payment' ],
337 condition => sub { $payby{BILL} },
340 label => 'Enter cash payment',
341 popup => "edit/cust_pay.cgi?popup=1;payby=CASH;custnum=$custnum",
342 actionlabel => 'Enter cash payment',
345 acl => [ 'Post payment', 'Post cash payment' ],
346 condition => sub { $payby{CASH} },
349 label => 'Enter Western Union payment',
350 popup => "edit/cust_pay.cgi?popup=1;payby=WEST;custnum=$custnum",
351 actionlabel => 'Enter Western Union payment',
354 acl => [ 'Post payment', ],
355 condition => sub { $payby{WEST} },
358 label => 'Post manual (offline/POS) credit card payment',
359 popup => "edit/cust_pay.cgi?popup=1;payby=MCRD;custnum=$custnum",
360 actionlabel => 'Enter credit card payment',
363 acl => [ 'Post payment', ],
364 condition => sub { $payby{MCRD} },
367 label => 'Post manual (offline/POS) electronic check',
368 popup => "edit/cust_pay.cgi?popup=1;payby=MCHK;custnum=$custnum",
369 actionlabel => 'Enter credit card payment',
372 acl => [ 'Post payment', ],
373 condition => sub { $payby{MCHK} },
375 # realtime payments via payment.cgi
377 label => 'Process credit card payment',
378 url => "misc/payment.cgi?payby=CARD;custnum=$custnum",
379 acl => [ 'Process payment', 'Process credit card payment', ],
380 condition => sub { $payby{CARD} or $payby{DCRD} },
383 label => 'Process electronic check payment',
384 url => "misc/payment.cgi?payby=CHEK;custnum=$custnum",
385 acl => [ 'Process payment', 'Process Echeck payment', ],
386 condition => sub { $payby{CHEK} or $payby{DCHK} },
390 label => 'Enter credit',
391 popup => "edit/cust_credit.cgi?custnum=$custnum",
392 actionlabel => 'Enter credit',
394 acl => 'Post credit',
397 label => 'Credit line items',
398 popup => "edit/credit-cust_bill_pkg.html?custnum=$custnum",
399 actionlabel => 'Credit line items',
402 acl => 'Credit line items',
404 FS::cust_bill->count('custnum = ?', shift->custnum) > 0
408 label => 'Enter check refund',
409 popup => "edit/cust_refund.cgi?popup=1;payby=BILL;custnum=$custnum",
410 actionlabel => 'Enter check refund',
412 acl => ['Post refund', 'Post check refund'],
413 condition => sub { $payby{BILL} },
416 label => 'Enter cash refund',
417 popup => "edit/cust_refund.cgi?popup=1;payby=CASH;custnum=$custnum",
418 actionlabel => 'Enter cash refund',
420 acl => ['Post refund', 'Post cash refund'],
421 condition => sub { $payby{CASH} },
424 label => 'Enter manual (offline/POS) credit card refund',
425 popup => "edit/cust_refund.cgi?popup=1;payby=MCRD;custnum=$custnum",
426 actionlabel => 'Enter credit card refund',
428 acl => ['Post refund' ],
429 condition => sub { $payby{MCRD} },
432 label => 'Enter manual (offline/POS) electronic check refund',
433 popup => "edit/cust_refund.cgi?popup=1;payby=MCHK;custnum=$custnum",
434 actionlabel => 'Enter electronic check refund',
436 acl => ['Post refund' ],
437 condition => sub { $payby{MCHK} },
440 label => 'Add tax adjustment',
441 popup => "edit/cust_tax_adjustment.html?custnum=$custnum",
442 actionlabel => 'Add tax adjustment',
444 confexists => 'enable_tax_adjustments',
445 acl => 'Add customer tax adjustment',
447 # separator, definitely
449 label => 'Download statement',
450 url => "view/cust_main_statement-pdf.cgi?$custnum",
451 acl => 'List invoices',
453 FS::cust_bill->count('custnum = ?', shift->custnum) > 0
457 label => 'Search invoices',
458 url => "search/report_cust_bill.html?custnum=$custnum",
459 acl => 'List invoices',
462 label => 'View tax exemptions',
463 url => "search/cust_tax_exempt_pkg.cgi?custnum=$custnum",
464 acl => 'View customer tax exemptions',
467 label => 'View tax adjustments',
468 url => "search/cust_tax_adjustment.html?custnum=$custnum",
469 confexists => 'enable_tax_adjustments',
470 acl => 'Add customer tax adjustment',
473 label => 'View pending payments',
474 url => "search/cust_pay_pending.html?magic=_date;statusNOT=done;custnum=$custnum",
475 acl => 'View pending payments',
477 FS::cust_pay_pending->count('custnum = ?', shift->custnum) > 0
483 label => 'Change History',
484 show => 'change_history',
485 acl => 'View customer history',
492 foreach my $submenu (@menu) {
496 foreach my $entry ( @$submenu ) {
497 # if the menu head was skipped, skip the whole menu
498 last if (!$first and !@links);
502 if ( $entry->{acl} ) {
503 next unless $curuser->access_right( $entry->{acl} );
505 if ( $entry->{confexists} ) {
506 if ( $entry->{confexists} =~ /^!(.*)/ ) {
507 # confexists => !foo, a negative condition
508 next if $conf->exists( $1 );
510 next unless $conf->exists( $entry->{confexists} );
513 if ( $entry->{condition} ) {
514 next unless &{ $entry->{condition} }($cust_main);
517 my $label = emt($entry->{label});
518 my $target = $entry->{content}
522 if ( ref($target) eq 'CODE' ) {
523 $target = &$target($cust_main);
527 if ( $entry->{content} ) { # then the coderef specified the whole thing
530 } elsif ( $entry->{show} ) {
532 # the menu head: always a link back to this page
533 $cgi->param('show', $entry->{show});
534 $target = $cgi->self_url;
536 $a = qq[ <A HREF="$target"];
537 if ( $opt{'show'} eq $entry->{show} ) {
538 $a .= ' class="current_show"';
540 $a .= qq[>$label</A> ];
543 } elsif ( $entry->{popup} ) {
545 $target =~ s/\$custnum/$custnum/g;
546 $target = $p.$target;
547 $a = include('/elements/popup_link.html',
552 label => emt($label),
555 } elsif ( $entry->{url} ) {
557 $target =~ s/\$custnum/$custnum/g;
558 $target = $p.$target;
559 $a = qq[ <A HREF="$target">$label</A> ];
566 push @processed_menu, \@links;