ACL for hardware class config, RT#85057
[freeside.git] / httemplate / elements / menu.html
index 55645cf..f6fc254 100644 (file)
 % }
 
 % unless ( $opt{'nocss'} ) {
-  <link href="<%$fsurl%>elements/freeside.css" type="text/css" rel="stylesheet">
-  <link href="<%$fsurl%>elements/freeside-print.css" type="text/css" rel="stylesheet" media="print">
+  <link href="<%$fsurl%>elements/freeside.css?v=<% $FS::VERSION %>" type="text/css" rel="stylesheet">
+  <link href="<%$fsurl%>elements/freeside-print.css?v=<% $FS::VERSION %>" type="text/css" rel="stylesheet" media="print">
 % }
-<link href="<%$fsurl%>elements/freeside-menu.css" type="text/css" rel="stylesheet">
+<link href="<%$fsurl%>elements/freeside-menu.css?v=<% $FS::VERSION %>" type="text/css" rel="stylesheet">
 
 <SCRIPT TYPE="text/javascript">
 
@@ -87,6 +87,21 @@ my $mobile = $opt{'mobile'} || 0;
 
 my $curuser = $FS::CurrentUser::CurrentUser;
 
+# saved searches
+tie my %report_saved_searches, 'Tie::IxHash';
+if ( my @searches = grep { $_->disabled eq '' } $curuser->saved_search ) {
+  foreach my $search (@searches) {
+    $report_saved_searches{ $search->searchname } = [
+      # don't use query_string here; we don't want to override the format
+      $fsurl . $search->path . '?' . $search->params , ''
+    ];
+  }
+  $report_saved_searches{'separator'} = '';
+  $report_saved_searches{'My saved searches'} =
+    [ $fsurl. 'browse/saved_search.html',
+      'Manage saved searches and subscriptions' ];
+}
+
 #XXX Active tickets not assigned to a customer
 
 tie my %report_prospects, 'Tie::IxHash';
@@ -114,13 +129,17 @@ $report_customers_lists{'by active trouble tickets'} = [ $fsurl. 'search/cust_ma
   if $conf->config('ticket_system');
 $report_customers_lists{'with USPS-unvalidated addresses'} = [ $fsurl. 'search/cust_main.cgi?browse=uspsunvalid', '' ]
   if $conf->config('usps_webtools-userid') && $conf->config('usps_webtools-password');
+$report_customers_lists{'with referrals'} = [ $fsurl. 'search/cust_main.html?with_referrals=1' ];
 
 tie my %report_customers, 'Tie::IxHash';
 $report_customers{'List customers'} = [ \%report_customers_lists, 'List customers' ]
   if $curuser->access_right('List all customers');
-$report_customers{'Zip code distribution'}     = [ $fsurl. 'search/report_cust_main-zip.html', 'Zip codes by number of customers' ];
-$report_customers{'Customer signup report'}    = [ $fsurl. 'graph/report_cust_signup.html',    'New customer signups by date' ];
-$report_customers{'Customer churn report'} =  [ $fsurl.'graph/report_cust_churn.html', 'New customers, suspensions, and cancellations summary' ];
+$report_customers{'Zip code distribution'}     = [ $fsurl. 'search/report_cust_main-zip.html', 'Zip codes by number of customers' ]
+  if $curuser->access_right('List zip codes');
+$report_customers{'Customer signup report'}    = [ $fsurl. 'graph/report_cust_signup.html',    'New customer signups by date' ]
+  if $curuser->access_right('Financial reports');
+$report_customers{'Customer churn report'} =  [ $fsurl.'graph/report_cust_churn.html', 'New customers, suspensions, and cancellations summary' ]
+  if $curuser->access_right('Customers: Customer churn report');
 $report_customers{'Signup date report'}        = [ $fsurl. 'graph/report_signupdate.html',     'Signup date report (by date of signup)' ];
 $report_customers{'Advanced customer reports'} = [ $fsurl. 'search/report_cust_main.html',     'by status, signup date, agent, etc.' ]
   if $curuser->access_right('Advanced customer search');
@@ -128,6 +147,7 @@ if ( $curuser->access_right('List contacts') ) {
   $report_customers{'separator'} = '';
   $report_customers{'Customer contacts'} = [ $fsurl. 'search/report_contact.html?link=cust_main' ];
   $report_customers{'Customer stored payment information'} = [ $fsurl. 'search/report_cust_payby.html' ];
+  $report_customers{'Customer timespan'} = [ $fsurl. 'search/report_cust_timespan.html' ];
 }
 
 tie my %report_invoices_open, 'Tie::IxHash',
@@ -227,10 +247,12 @@ foreach my $svcdb ( FS::part_svc->svc_tables() ) {
       ];
   }
 
-  $report_svc{"Advanced $lcsname reports"} = 
+  if ( $curuser->access_right("Services: $name: Advanced search")
+    && $svcdb =~ /^svc_(acct|broadband|hardware|phone|fiber)$/ ) {
+
+    $report_svc{"Advanced $lcsname reports"} = 
       [ $fsurl."search/report_$svcdb.html", '' ]
-    if $svcdb =~ /^svc_(acct|broadband|hardware|phone)$/
-    && $curuser->access_right("Services: $name: Advanced search");
+  }
 
   if ( $svcdb eq 'svc_phone' ) {
 
@@ -252,6 +274,25 @@ foreach my $svcdb ( FS::part_svc->svc_tables() ) {
 
 }
 
+## adding export test reports
+tie my %report_exports, 'Tie::IxHash';
+my $exports = FS::part_export::export_info();
+my $exportname;
+tie my %export_list, 'Tie::IxHash',
+  '' => '',
+  map { $_ => "$_ - ". $exports->{$_}{desc} }
+  sort { $a cmp $b }
+  keys %$exports;
+;
+
+foreach my $export (keys %export_list) {
+  $report_exports{"$export export test"} =
+    [ $fsurl. 'search/report_svc_export_test.cgi?export='.$export,
+      "Report of invalid service setup for services tied to $export export",
+    ] if "FS::part_export::$export"->can('test_export_report');
+}
+$report_services{'exports'} = [ \%report_exports, "Exports" ];
+
 tie my %report_packages, 'Tie::IxHash';
 $report_packages{'Package definitions (by # active)'} =  [ $fsurl.'browse/part_pkg.cgi?active=1', 'Package definitions by number of active packages' ]
   if    $curuser->access_right('Edit package definitions')
@@ -273,6 +314,7 @@ $report_packages{'Suspension summary'} = [ $fsurl.'search/cust_pkg_susp.html', '
 $report_packages{'Customer packages with unconfigured services'} =  [ $fsurl.'search/cust_pkg.cgi?APKG_pkgnum', 'List packages which have provisionable services' ];
 $report_packages{'FCC Form 477'} =  [ $fsurl.'search/report_477.html' ]
   if $conf->exists('part_pkg-show_fcc_options');
+$report_packages{'Contract end dates'} = [ $fsurl.'search/report_cust_pkg-date.html?date=contract_end', 'Show packages by contract end date' ];
 $report_packages{'Advanced package reports'} =  [ $fsurl.'search/report_cust_pkg.html', 'by agent, date range, status, package definition' ];
 
 tie my %report_inventory, 'Tie::IxHash',
@@ -289,6 +331,8 @@ $report_rating{'Call Detail Records (CDRs)'} = [ $fsurl.'search/report_cdr.html'
   if $curuser->access_right("Usage: Call Detail Records (CDRs)");
 $report_rating{'Unrateable CDRs'} = [ $fsurl.'search/cdr.html?freesidestatus=failed;cdrbatchnum=_ALL_' ]
   if $curuser->access_right("Usage: Unrateable CDRs");
+$report_rating{'Customer CDRs Profit/Loss'} = [ $fsurl.'search/report_customer_cdr_profit.html', 'Profit/loss from customer CDRs' ]
+  if $curuser->access_right('Financial reports');
 if ( $curuser->access_right("Usage: Time worked") ) {
   $report_rating{'Time worked'} = [ $fsurl.'search/report_rt_transaction.html', '' ];
   $report_rating{'Time worked summary per ticket'} = [ $fsurl.'search/report_rt_ticket.html', '' ];
@@ -316,24 +360,28 @@ tie my %report_ticketing, 'Tie::IxHash',
 ;
 
 tie my %report_bill_event, 'Tie::IxHash',
-  'All billing events' => [ $fsurl.'search/report_cust_event.html', 'All billing events for a date range' ],
   'Billing event errors' => [ $fsurl.'search/report_cust_event.html?failed=1', 'Failed credit cards, processor or printer problems, etc.' ],
 ;
 
-tie my %report_payments, 'Tie::IxHash',
-  'Payments' => [ $fsurl.'search/report_cust_pay.html', 'Payment report (by type and/or date range)' ],
-  'Payment application detail' => [ $fsurl.'search/report_cust_bill_pay_pkg.html', 'Line item application detail' ],
-;
+tie my %report_payments, 'Tie::IxHash';
+$report_payments{'Payments'} = [ $fsurl.'search/report_cust_pay.html', 'Payment report (by type and/or date range)' ]
+  if $curuser->access_right('Basic payment and refund reports');
+$report_payments{'Payment application detail'} = [ $fsurl.'search/report_cust_bill_pay_pkg.html', 'Line item application detail' ]
+  if $curuser->access_right('Financial reports');
 $report_payments{'Pending Payments'} = [ $fsurl.'search/cust_pay_pending.html?magic=_date;statusNOT=done', 'Pending real-time payments' ]
   if $curuser->access_right('View customer pending payments');
-$report_payments{'Unapplied Payments'} = [ $fsurl.'search/report_cust_pay.html?unapplied=1', 'Unapplied payment report (by type and/or date range)' ];
+$report_payments{'Unapplied Payments'} = [ $fsurl.'search/report_cust_pay.html?unapplied=1', 'Unapplied payment report (by type and/or date range)' ]
+  if $curuser->access_right('Financial reports'); #not enforced
 $report_payments{'Voided Payments'} = [ $fsurl.'search/report_cust_pay.html?void=1', 'Voided payment report (by type and/or date range)' ]
-  if $curuser->access_right('View customer pending payments');
+  if $curuser->access_right('Financial reports'); #not enforced
 $report_payments{'Payment Batches'} = [ $fsurl.'search/pay_batch.html', 'Payment batches (by status and/or date range)' ]
-  if $conf->exists('batch-enable') || $conf->config('batch-enable_payby');
-$report_payments{'Unapplied Payment Aging'} = [ $fsurl.'search/report_unapplied_cust_pay.html', 'Unapplied payment aging report' ];
+  if ( $conf->exists('batch-enable') || $conf->config('batch-enable_payby') )
+  && $curuser->access_right('Financial reports');
+$report_payments{'Unapplied Payment Aging'} = [ $fsurl.'search/report_unapplied_cust_pay.html', 'Unapplied payment aging report' ]
+  if $curuser->access_right('Financial reports');
 $report_payments{'Deleted Payments / Payment history table'} = [ $fsurl.'search/report_h_cust_pay.html', 'Deleted payments / payment history table' ]
-  if $conf->exists('payment-history-report');
+  if $conf->exists('payment-history-report')
+  && $curuser->access_right('Financial reports');
 
 tie my %report_credits, 'Tie::IxHash',
   'Credit Report' => [ $fsurl.'search/report_cust_credit.html', 'Credit report (by employee and/or date range)' ],
@@ -361,7 +409,8 @@ tie my %report_commissions, 'Tie::IxHash',
   'Agent per package' => [ $fsurl.'search/report_agent_commission_pkg.html' ],
   'Sales Person' => [ $fsurl.'search/report_sales_commission.html' ],
   'Sales Person per package' => [ $fsurl.'search/report_sales_commission_pkg.html' ],
-  'Employee' => [ $fsurl.'search/report_employee_commission.html', '' ]
+  'Employee' => [ $fsurl.'search/report_employee_commission.html', '' ],
+  'Agent Credits and Payments' => [ $fsurl.'search/report_agent_credit_payment.html' ],
 ;
 
 tie my %report_financial, 'Tie::IxHash';
@@ -381,11 +430,17 @@ if( $curuser->access_right('Financial reports') ) {
   $report_financial{'Tax Liability (vendor tax data)'} = [ $fsurl.'search/report_newtax.html', 'Tax liability report (vendor tax data)' ]
     if $taxproducts;
 
+  $report_financial{'Monthly Sales and Taxes'} = [$fsurl.'search/tax_sales.html', 'Monthly sales and taxes report'];
+
   # most sites don't need this but there isn't really a config to enable it
   $report_financial{'E911 Fee Summary'} = [ $fsurl.'search/report_e911.html', 'E911 fee summary' ];
 
   $report_financial{'Customer Accounting Summary'} = [ $fsurl.'search/report_customer_accounting_summary.html', 'Customer accounting summary report' ];
 
+  if ( my $report_title = FS::cust_payby->future_autobill_report_title ) {
+    $report_financial{$report_title} = [ $fsurl.'search/report_future_autobill.html', "$report_title for customers with automatic payment methods (by date)" ];
+  }
+
 } elsif($curuser->access_right('Receivables report')) {
 
   $report_financial{'A/R Aging'} = [ $fsurl.'search/report_receivables.html', 'Accounts Receivable Aging report' ];
@@ -398,12 +453,12 @@ tie my %report_payable, 'Tie::IxHash',
 ;
 
 tie my %report_logs, 'Tie::IxHash';
-$report_logs{'Billing events'} =  [ \%report_bill_event, 'Billing events' ]
+$report_logs{'Billing events'} =  [ $fsurl.'search/report_cust_event.html', 'Search billing events by date and status' ]
+  if $curuser->access_right('Billing event reports');
+$report_logs{'Billing event fees'} =  [ $fsurl.'search/report_cust_event_fee.html', 'Search fees triggered by billing events' ]
   if $curuser->access_right('Billing event reports');
 $report_logs{'Credit limit incidents'} = [ $fsurl.'search/report_cust_main_credit_limit.html', '' ]
   if $curuser->access_right('List rating data');
-$report_logs{'Employee activity'} = [ $fsurl.'search/report_employee_audit.html', '' ]
-  if $curuser->access_right('Employees: Audit Report');
 $report_logs{'System log'} = [ $fsurl.'search/log.html', 'View system events and debugging information.' ],
   if $curuser->access_right('View system logs')
   || $curuser->access_right('Configuration');
@@ -411,7 +466,15 @@ $report_logs{'Outgoing messages'} = [ $fsurl.'search/cust_msg.html', 'View outgo
   if $curuser->access_right('View email logs')
   || $curuser->access_right('Configuration');
 
+tie my %report_employee, 'Tie::IxHash',
+  'Employee activity' => [ $fsurl.'search/report_employee_audit.html', '' ],
+  'Employee sessions' => [ $fsurl.'search/report_access_user_session_log.html', '' ],
+  'Access log statistics' => [ $fsurl.'search/report_access_user_log.html?group_by=path', '' ],
+;
+
 tie my %report_menu, 'Tie::IxHash';
+$report_menu{'Saved searches'} = [ \%report_saved_searches, 'My saved searches' ]
+  if keys(%report_saved_searches);
 $report_menu{'Prospects'}      = [ \%report_prospects, 'Prospect reports' ]
   if $curuser->access_right('List prospects')
   || $curuser->access_right('List contacts');
@@ -419,13 +482,17 @@ $report_menu{'Quotations'}     = [ \%report_quotations, 'Quotation reports' ]
   if $curuser->access_right('List quotations');
 $report_menu{'Customers'}      = [ \%report_customers, 'Customer reports'  ]
   if $curuser->access_right('List customers')
-  || $curuser->access_right('List contacts');
+  || $curuser->access_right('List contacts')
+  || $curuser->access_right('Advanced customer search')
+  || $curuser->access_right('List zip codes')
+  || $curuser->access_right('Financial reports')
+  || $curuser->access_right('Customers: Customer churn report');
 $report_menu{'Invoices'}       =  [ \%report_invoices,  'Invoice reports'   ]
   if $curuser->access_right('List invoices');
 $report_menu{'Discounts'}      =  [ \%report_discounts, 'Discount reports'  ]
   if $curuser->access_right('Financial reports');
 $report_menu{'Payments'}       =  [ \%report_payments,  'Payment reports'   ]
-  if $curuser->access_right('Financial reports');
+  if keys %report_payments;
 $report_menu{'Packages'}       =  [ \%report_packages,  'Package reports'   ]
   if $curuser->access_right('List packages');
 $report_menu{'Services'}       =  [ \%report_services,  'Services reports'  ]
@@ -443,6 +510,8 @@ $report_menu{'Financial (Receivables)'} = [ \%report_financial, 'Financial repor
 $report_menu{'Financial (Payables)'} = [ \%report_payable, 'Financial reports (Payables)' ]
   if $curuser->access_right('Financial reports');
 
+$report_menu{'Employees'}      = [ \%report_employee, 'Employee reports' ]
+  if $curuser->access_right('Employee Reports');
 $report_menu{'Logs'}           = [ \%report_logs, 'System and email logs' ]
   if (keys %report_logs); # empty if the user has no rights to it
 $report_menu{'SQL Query'}      = [ $fsurl.'search/report_sql.html', 'SQL Query']
@@ -451,7 +520,7 @@ $report_menu{'SQL Query'}      = [ $fsurl.'search/report_sql.html', 'SQL Query']
 tie my %tools_customers, 'Tie::IxHash', ();
 $tools_customers{'Appointments'} = [ $fsurl.'rt/Search/Schedule.html?LengthMin=0', 'View appointment schedule' ]
   if $curuser->access_right('View appointments');
-$tools_customers{'Attachments'} = [ $fsurl.'browse/cust_attachment.html', 'View customer attachments' ]
+$tools_customers{'Attachments'} = [ $fsurl.'search/report_cust_attachment.html', 'View customer attachments' ]
   if !$conf->config('disable_cust_attachment') and $curuser->access_right('View attachments') and $curuser->access_right('Browse attachments');
 $tools_customers{'Customer email settings'} = [ $fsurl.'misc/manage_cust_email.html' ]
   if $curuser->access_right('Edit customer');
@@ -472,14 +541,16 @@ tie my %tools_importing, 'Tie::IxHash',
   'Customers'            => [ $fsurl.'misc/cust_main-import.cgi', '' ],
   'Package definitions'  => [ $fsurl.'misc/part_pkg-import.html', '' ],
   'Customer packages'    => [ $fsurl.'misc/cust_pkg-import.html', '' ],
-  'Customer comments'    => [ $fsurl.'misc/cust_main_note-import.html', '' ],
+#  'Customer broadband services' => [ $fsurl.'misc/svc_broadband-import.html', '' ],
+  'Customer notes'       => [ $fsurl.'misc/cust_main_note-import.html', '' ],
+  'Customer contacts'    => [ $fsurl.'misc/contact-import.cgi', '' ],
   'One-time charges'     => [ $fsurl.'misc/cust_main-import_charges.cgi', '' ],
   'Payments'             => [ $fsurl.'misc/cust_pay-import.cgi', '' ],
   'Credits'              => [ $fsurl.'misc/cust_credit-import.html', '' ],
   'Phone numbers (DIDs)' => [ $fsurl.'misc/phone_avail-import.html', '' ],
   'Call Detail Records (CDRs)' => [ $fsurl.'misc/cdr-import.html', '' ],
 ;
-if ( $conf->config('tax_data_vendor') eq 'cch' ) {
+if ( $conf->config('tax_data_vendor') ) {
   if ( $conf->exists('taxdatadirectdownload') ) {
       $tools_importing{'Tax rates from vendor site'} =
       [ $fsurl.'misc/tax-fetch_and_import.cgi', '' ];
@@ -541,7 +612,7 @@ $tools_menu{'System'} = [ \%tools_system, 'System tools' ]
 
 tie my %config_employees, 'Tie::IxHash',
   'Employees' => [ $fsurl.'browse/access_user.html', 'Setup internal users' ],
-  'Employee groups' => [ $fsurl.'browse/access_group.html', 'Employee groups allow you to control access to the backend' ],
+  'Employee groups and access control' => [ $fsurl.'browse/access_group.html', 'Employee groups allow you to control access to the backend' ],
   'Installer availability' => [ $fsurl.'browse/sched_item.html', 'Installer availability' ],
 ;
 
@@ -592,6 +663,10 @@ tie my %config_circuit, 'Tie::IxHash',
   'Termination types' => [ $fsurl.'browse/circuit_termination.html',  '' ],
 ;
 
+tie my %config_fiber, 'Tie::IxHash',
+  'OLTs' => [ $fsurl.'browse/fiber_olt.html', '' ],
+;
+
 tie my %config_export_svc, 'Tie::IxHash', ();
 if ( $curuser->access_right('Configuration') ) {
   $config_export_svc{'Service definitions'} = [ $fsurl.'browse/part_svc.cgi', 'Services are items you offer to your customers' ];
@@ -615,14 +690,14 @@ $config_export_svc{'Alarm'} = [ \%config_alarm, '' ]
   if $curuser->access_right(['Alarm configuration', 'Alarm global configuration']);
 $config_export_svc{'Circuits'} = [ \%config_circuit, '' ]
   if $curuser->access_right('Configuration');
-$config_export_svc{'Hardware types'} = [ $fsurl.'browse/hardware_class.html', 'Set up hardware type catalog' ]
+$config_export_svc{'Fiber'} = [ \%config_fiber, '' ]
   if $curuser->access_right('Configuration');
+$config_export_svc{'Hardware types'} = [ $fsurl.'browse/hardware_class.html', 'Set up hardware type catalog' ]
+  if $curuser->access_right('Edit hardware classes and types');
 
 tie my %config_pkg_reason, 'Tie::IxHash',
-  'Cancel reasons' => [ $fsurl.'browse/reason.html?class=C', 'Cancel reasons explain why a service was cancelled.' ],
-  'Cancel reason types' => [ $fsurl.'browse/reason_type.html?class=C', 'Cancel reason types define groups of reasons.' ],
-  'Suspend reasons' => [ $fsurl.'browse/reason.html?class=S', 'Suspend reasons explain why a service was suspended.' ],
-  'Suspend reason types' => [ $fsurl.'browse/reason_type.html?class=S', 'Suspend reason types define groups of reasons.' ],
+  'Cancel reasons' => [ $fsurl.'browse/reason_type.html?class=C', 'Cancel reasons explain why a service was cancelled.' ],
+  'Suspend reasons' => [ $fsurl.'browse/reason_type.html?class=S', 'Suspend reasons explain why a service was suspended.' ],
 ;
 
 tie my %config_pkg, 'Tie::IxHash', ();
@@ -654,13 +729,15 @@ tie my %config_cust, 'Tie::IxHash',
   'Contact types'    =>  [ $fsurl.'browse/contact_class.html', ''], #XXX useful description
 ;
   
-$config_cust{'Note classes'} = [ $fsurl.'browse/cust_note_class.html', 'Note classes define groups of customer notes for reporting.' ]
-    if ($conf->exists('note-classes') && $conf->config('note-classes') > 0);
+$config_cust{'Note classes'} = [ $fsurl.'browse/cust_note_class.html', 'Note classes define groups of customer notes for reporting.' ];
 
 tie my %config_agent, 'Tie::IxHash',
   'Agent types' => [ $fsurl.'browse/agent_type.cgi', 'Agent types define groups of package definitions that you can then assign to particular agents' ],
   'Agents'      => [ $fsurl.'browse/agent.cgi', 'Agents are resellers of your service. Agents may be limited to a subset of your full offerings (via their type)' ],
-  'Agent payment gateways'         => [ $fsurl.'browse/payment_gateway.html', 'Credit card and electronic check processors for agent overrides' ];
+  'Agent payment gateways'         => [ $fsurl.'browse/payment_gateway.html', 'Credit card and electronic check processors for agent overrides' ],
+  'separator' => '',
+  'Commission schedules' => [ $fsurl.'browse/commission_schedule.html',
+    'Commission schedules for consecutive billing periods' ],
 ;
 
 tie my %config_sales, 'Tie::IxHash',
@@ -713,12 +790,13 @@ if ( $curuser->access_right('Configuration') ) {
   }
 
   $config_billing{'separator4'} = ''; #its a separator!
-  $config_billing{'Credit reasons'}  = [ $fsurl.'browse/reason.html?class=R', 'Credit reasons explain why a credit was issued.' ];
-  $config_billing{'Credit reason types'}  = [ $fsurl.'browse/reason_type.html?class=R', 'Credit reason types define groups of reasons.' ];
+  $config_billing{'Credit reasons'}  = [ $fsurl.'browse/reason_type.html?class=R', 'Credit reasons explain why a credit was issued.' ];
   
-  $config_billing{'separator5'} = ''; #its a separator!
-  $config_billing{'Refund reasons'}  = [ $fsurl.'browse/reason.html?class=F', 'Refund reasons explain why a refund was issued.' ];
-  $config_billing{'Refund reason types'}  = [ $fsurl.'browse/reason_type.html?class=F', 'Refund reason types define groups of reasons.' ];
+  $config_billing{'Refund reasons'}  = [ $fsurl.'browse/reason_type.html?class=F', 'Refund reasons explain why a refund was issued.' ];
+
+  $config_billing{'Invoice void reasons'}  = [ $fsurl.'browse/reason_type.html?class=I', 'Invoice void reasons explain why an invoice was voided.' ];
+  $config_billing{'Payment void reasons'}  = [ $fsurl.'browse/reason_type.html?class=P', 'Payment void reasons explain why a payment was voided.' ];
+  $config_billing{'Credit void reasons'}  = [ $fsurl.'browse/reason_type.html?class=X', 'Credit void reasons explain why a credit was voided.' ];
 }
 
 #XXX also to be unified
@@ -782,9 +860,18 @@ $config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/inventory_cla
   || $curuser->access_right('Edit global inventory')
   || $curuser->access_right('Configuration');
 
+$config_misc{'Real estate inventory'} = [ $fsurl.'browse/realestate_unit.html', 'Setup real estate inventory' ]
+  if $curuser->access_right('Edit realestate inventory')
+  || $curuser->access_right('Edit global inventory')
+  || $curuser->access_right('Configuration');
+
 $config_misc{'Upload targets'} = [ $fsurl.'browse/upload_target.html', 'Billing and payment upload destinations' ]
   if $curuser->access_right('Configuration');
 
+$config_misc{'System log emails'} = [ $fsurl.'browse/log_email.html', 'Configure conditions for sending email when logging' ]
+  if $curuser->access_right('View system logs')
+  || $curuser->access_right('Configuration');
+
 tie my %config_menu, 'Tie::IxHash';
 if ( $curuser->access_right('Configuration' ) ) {
   %config_menu = (
@@ -828,7 +915,7 @@ $config_menu{'Billing'} = [ \%config_billing, '' ]
   if keys %config_billing;
 $config_menu{'Ticketing'} = [ \%config_ticketing, '' ]
   if $conf->config('ticket_system')
-  && FS::TicketSystem->access_right(\%session, 'ShowConfigTab');
+  && eval { FS::TicketSystem->access_right(\%session, 'ShowConfigTab') };
 $config_menu{'Network Monitoring'} = [ \%config_nms, '' ]
   if $curuser->access_right('Configure network monitoring')
   && $conf->config('network_monitoring_system') eq 'Torrus_Internal';
@@ -866,6 +953,7 @@ if ( $agentnum ) {
     if $conf->config('ticket_system') eq 'RT_Internal';
   $help_menu{'Networking monitoring documentation'} = [ 'http://torrus.org/userguide.pod.html', 'Torrus User Guide' ]
     if $conf->config('network_monitoring_system') eq 'Torrus_Internal';
+  $help_menu{'Developer documentation'} = [ "${fsurl}docs/library/FS.html", 'Developer documentation' ];
   $help_menu{'separator'} = '';
   $help_menu{"About Freeside v$FS::VERSION"} = [ "javascript:about_freeside()", '' ];
   $help_menu{"About RT v$RT::VERSION"} = [ 'http://www.bestpractical.com/rt', 'Request Tracker Homepage' ]
@@ -963,11 +1051,11 @@ sub submenu {
           my($subhtml, $submenuname ) = submenu($url_or_submenu, $_); #mmm, recursion
 
           "$subhtml\n".
-          "myMenu$menunum.add(new WebFXMenuItem(\"$_\", null, \"$tooltip\", $submenuname ));";
+          "myMenu$menunum.add(new WebFXMenuItem(\"".mt($_)."\", null, \"".mt($tooltip)."\", $submenuname ));";
 
         } else {
 
-          "myMenu$menunum.add(new WebFXMenuItem(\"$_\", \"$url_or_submenu\", \"$tooltip\" ));";
+          "myMenu$menunum.add(new WebFXMenuItem(\"".mt($_)."\", \"$url_or_submenu\", \"".mt($tooltip)."\" ));";
 
         }
 
@@ -982,4 +1070,3 @@ sub submenu {
 }
 
 </%init>
-