(start of) reconcile breakage from stale accounts, RT#6407
[freeside.git] / FS / FS / Conf.pm
index d244dce..1542efe 100644 (file)
@@ -8,6 +8,7 @@ use MIME::Base64;
 use FS::ConfItem;
 use FS::ConfDefaults;
 use FS::Conf_compat17;
+use FS::payby;
 use FS::conf;
 use FS::Record qw(qsearch qsearchs);
 use FS::UID qw(dbh datasrc use_confcompat);
@@ -75,11 +76,23 @@ sub base_dir {
   $1;
 }
 
-=item config KEY [ AGENTNUM ]
+=item conf KEY [ AGENTNUM [ NODEFAULT ] ]
+
+Returns the L<FS::conf> record for the key and agent.
+
+=cut
+
+sub conf {
+  my $self = shift;
+  $self->_config(@_);
+}
+
+=item config KEY [ AGENTNUM [ NODEFAULT ] ]
 
 Returns the configuration value or values (depending on context) for key.
 The optional agent number selects an agent specific value instead of the
-global default if one is present.
+global default if one is present.  If NODEFAULT is true only the agent
+specific value(s) is returned.
 
 =cut
 
@@ -92,12 +105,12 @@ sub _usecompat {
 }
 
 sub _config {
-  my($self,$name,$agentnum)=@_;
+  my($self,$name,$agentnum,$agentonly)=@_;
   my $hashref = { 'name' => $name };
   $hashref->{agentnum} = $agentnum;
   local $FS::Record::conf = undef;  # XXX evil hack prevents recursion
   my $cv = FS::Record::qsearchs('conf', $hashref);
-  if (!$cv && defined($agentnum)) {
+  if (!$agentonly && !$cv && defined($agentnum) && $agentnum) {
     $hashref->{agentnum} = '';
     $cv = FS::Record::qsearchs('conf', $hashref);
   }
@@ -108,8 +121,10 @@ sub config {
   my $self = shift;
   return $self->_usecompat('config', @_) if use_confcompat;
 
-  my($name,$agentnum)=@_;
-  my $cv = $self->_config($name, $agentnum) or return;
+  carp "FS::Conf->config(". join(', ', @_). ") called"
+    if $DEBUG > 1;
+
+  my $cv = $self->_config(@_) or return;
 
   if ( wantarray ) {
     my $v = $cv->value;
@@ -120,7 +135,7 @@ sub config {
   }
 }
 
-=item config_binary KEY [ AGENTNUM ]
+=item config_binary KEY [ AGENTNUM [ NODEFAULT ] ]
 
 Returns the exact scalar value for key.
 
@@ -130,12 +145,11 @@ sub config_binary {
   my $self = shift;
   return $self->_usecompat('config_binary', @_) if use_confcompat;
 
-  my($name,$agentnum)=@_;
-  my $cv = $self->_config($name, $agentnum) or return;
-  decode_base64($cv->value);
+  my $cv = $self->_config(@_) or return;
+  length($cv->value) ? decode_base64($cv->value) : '';
 }
 
-=item exists KEY [ AGENTNUM ]
+=item exists KEY [ AGENTNUM [ NODEFAULT ] ]
 
 Returns true if the specified key exists, even if the corresponding value
 is undefined.
@@ -146,8 +160,12 @@ sub exists {
   my $self = shift;
   return $self->_usecompat('exists', @_) if use_confcompat;
 
-  my($name,$agentnum)=@_;
-  defined($self->_config($name, $agentnum));
+  my($name, $agentnum)=@_;
+
+  carp "FS::Conf->exists(". join(', ', @_). ") called"
+    if $DEBUG > 1;
+
+  defined($self->_config(@_));
 }
 
 =item config_orbase KEY SUFFIX
@@ -212,6 +230,7 @@ sub invoice_templatenames {
     }
   }
   
+  map { $_ } #handle scalar context
   sort keys %templatenames;
 
 }
@@ -326,7 +345,7 @@ sub import_config_item {
     warn "Inserting $key\n" if $DEBUG;
     local $/;
     my $value = readline(new IO::File "$dir/$key");
-    if ($item->type eq 'binary') {
+    if ($item->type =~ /^(binary|image)$/ ) {
       $self->set_binary($key, $value);
     }else{
       $self->set($key, $value);
@@ -355,7 +374,8 @@ sub verify_config_item {
   $error .= "$key fails existential comparison; "
     if $self->exists($key) xor $compat->exists($key);
 
-  unless ($type eq 'binary') {
+  if ( $type !~ /^(binary|image)$/ ) {
+
     {
       no warnings;
       $error .= "$key fails scalar comparison; "
@@ -372,22 +392,24 @@ sub verify_config_item {
       $error .= "$key fails list comparison; "
         unless $r;
     }
-  }
 
-  if ($type eq 'binary') {
+  } else {
+
     $error .= "$key fails binary comparison; "
       unless scalar($self->config_binary($key)) eq scalar($compat->config_binary($key));
-  }
 
-  if ($error =~ /existential comparison/ && $item->section eq 'deprecated') {
-    my $proto;
-    for ( @config_items ) { $proto = $_; last if $proto->key eq $key;  }
-    unless ($proto->key eq $key) { 
-      warn "removed config item $error\n" if $DEBUG;
-      $error = '';
-    }
   }
 
+#remove deprecated config on our own terms, not freeside-upgrade's
+#  if ($error =~ /existential comparison/ && $item->section eq 'deprecated') {
+#    my $proto;
+#    for ( @config_items ) { $proto = $_; last if $proto->key eq $key;  }
+#    unless ($proto->key eq $key) { 
+#      warn "removed config item $error\n" if $DEBUG;
+#      $error = '';
+#    }
+#  }
+
   $error;
 }
 
@@ -439,11 +461,12 @@ sub _orbase_items {
           die "don't know about $base items" unless $proto->key eq $base;
 
           map { new FS::ConfItem { 
-                                   'key' => $_,
-                                   'section' => $proto->section,
-                                   'description' => 'Alternate ' . $proto->description . '  See the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.7:Documentation:Administration#Invoice_templates">billing documentation</a> for details.',
-                                   'type' => $proto->type,
-                                 };
+                  'key'         => $_,
+                  'base_key'    => $proto->key,
+                  'section'     => $proto->section,
+                  'description' => 'Alternate ' . $proto->description . '  See the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.7:Documentation:Administration#Invoice_templates">billing documentation</a> for details.',
+                  'type'        => $proto->type,
+                };
               } &$listmaker($base);
         } @base_items,
   );
@@ -471,7 +494,7 @@ sub config_items {
 
 =item init-config DIR
 
-Imports the non-deprecated configuration items from DIR (1.7 compatible)
+Imports the configuration items from DIR (1.7 compatible)
 to conf records in the database.
 
 =cut
@@ -552,16 +575,28 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'alert_expiration',
+    'section'     => 'billing',
+    'description' => 'Enable alerts about billing method expiration (i.e. expiring credit cards).',
+    'type'        => 'checkbox',
+    'per_agent'   => 1,
+  },
+
+  {
     'key'         => 'alerter_template',
     'section'     => 'billing',
-    'description' => 'Template file for billing method expiration alerts.  See the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.7:Documentation:Administration#Credit_cards_and_Electronic_checks">billing documentation</a> for details.',
+    'description' => 'Template file for billing method expiration alerts (i.e. expiring credit cards).  See the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.7:Documentation:Administration#Credit_cards_and_Electronic_checks">billing documentation</a> for details.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
     'key'         => 'apacheip',
-    'section'     => 'deprecated',
-    'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be the current IP address to assign to new virtual hosts',
+    #not actually deprecated yet
+    #'section'     => 'deprecated',
+    #'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead.  Used to be the current IP address to assign to new virtual hosts',
+    'section'     => '',
+    'description' => 'IP address to assign to new virtual hosts',
     'type'        => 'text',
   },
 
@@ -594,6 +629,40 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'billco-url',
+    'section'     => 'billing',
+    'description' => 'The url to use for performing uploads to the invoice mailing service.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'billco-username',
+    'section'     => 'billing',
+    'description' => 'The login name to use for uploads to the invoice mailing service.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+    'agentonly'   => 1,
+  },
+
+  {
+    'key'         => 'billco-password',
+    'section'     => 'billing',
+    'description' => 'The password to use for uploads to the invoice mailing service.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+    'agentonly'   => 1,
+  },
+
+  {
+    'key'         => 'billco-clicode',
+    'section'     => 'billing',
+    'description' => 'The clicode to use for uploads to the invoice mailing service.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
     'key'         => 'business-onlinepayment',
     'section'     => 'billing',
     'description' => '<a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a> support, at least three lines: processor, login, and password.  An optional fourth line specifies the action or actions (multiple actions are separated with `,\': for example: `Authorization Only, Post Authorization\').    Optional additional lines are passed to Business::OnlinePayment as %processor_options.',
@@ -608,6 +677,17 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'business-onlinepayment-namespace',
+    'section'     => 'billing',
+    'description' => 'Specifies which perl module namespace (which group of collection routines) is used by default.',
+    'type'        => 'select',
+    'select_hash' => [
+                       'Business::OnlinePayment' => 'Direct API (Business::OnlinePayment)',
+                      'Business::OnlineThirdPartyPayment' => 'Web API (Business::ThirdPartyPayment)',
+                     ],
+  },
+
+  {
     'key'         => 'business-onlinepayment-description',
     'section'     => 'billing',
     'description' => 'String passed as the description field to <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a>.  Evaluated as a double-quoted perl string, with the following variables available: <code>$agent</code> (the agent name), and <code>$pkgs</code> (a comma-separated list of packages for which these charges apply)',
@@ -649,7 +729,14 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'deletecustomers',
     'section'     => 'UI',
-    'description' => 'Enable customer deletions.  Be very careful!  Deleting a customer will remove all traces that this customer ever existed!  It should probably only be used when auditing a legacy database.  Normally, you cancel all of a customers\' packages if they cancel service.',
+    'description' => 'Enable customer deletions.  Be very careful!  Deleting a customer will remove all traces that the customer ever existed!  It should probably only be used when auditing a legacy database.  Normally, you cancel all of a customers\' packages if they cancel service.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'deleteinvoices',
+    'section'     => 'UI',
+    'description' => 'Enable invoices deletions.  Be very careful!  Deleting an invoice will remove all traces that the invoice ever existed!  Normally, you would apply a credit against the invoice instead.',  #invoice voiding?
     'type'        => 'checkbox',
   },
 
@@ -662,8 +749,11 @@ worry that config_items is freeside-specific and icky.
 
   {
     'key'         => 'deletecredits',
-    'section'     => 'deprecated',
-    'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to enable deletion of unclosed credits.  Be very careful!  Only delete credits that were data-entry errors, not adjustments.  Optionally specify one or more comma-separated email addresses to be notified when a credit is deleted.',
+    #not actually deprecated yet
+    #'section'     => 'deprecated',
+    #'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to enable deletion of unclosed credits.  Be very careful!  Only delete credits that were data-entry errors, not adjustments.  Optionally specify one or more comma-separated email addresses to be notified when a credit is deleted.',
+    'section'     => '',
+    'description' => 'One or more comma-separated email addresses to be notified when a credit is deleted.',
     'type'        => [qw( checkbox text )],
   },
 
@@ -675,6 +765,20 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'unapplypayments',
+    'section'     => 'deprecated',
+    'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to enable "unapplication" of unclosed payments.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'unapplycredits',
+    'section'     => 'deprecated',
+    'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to nable "unapplication" of unclosed credits.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'dirhash',
     'section'     => 'shell',
     'description' => 'Optional numeric value to control directory hashing.  If positive, hashes directories for the specified number of levels from the front of the username.  If negative, hashes directories for the specified number of levels from the end of the username.  Some examples: <ul><li>1: user -> <a href="#home">/home</a>/u/user<li>2: user -> <a href="#home">/home</a>/u/s/user<li>-1: user -> <a href="#home">/home</a>/r/user<li>-2: user -> <a href="#home">home</a>/r/e/user</ul>',
@@ -682,6 +786,20 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'disable_cust_attachment',
+    'section'     => '',
+    'description' => 'Disable customer file attachments',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'max_attachment_size',
+    'section'     => '',
+    'description' => 'Maximum size for customer file attachments (leave blank for unlimited)',
+    'type'        => 'text',
+  },
+
+  {
     'key'         => 'disable_customer_referrals',
     'section'     => 'UI',
     'description' => 'Disable new customer-to-customer referrals in the web interface',
@@ -731,6 +849,13 @@ worry that config_items is freeside-specific and icky.
   },
   
   {
+    'key'         => 'auto_router',
+    'section'     => '',
+    'description' => 'Automatically choose the correct router/block based on supplied ip address when possible while provisioning broadband services',
+    'type'        => 'checkbox',
+  },
+  
+  {
     'key'         => 'hidecancelledpackages',
     'section'     => 'UI',
     'description' => 'Prevent cancelled packages from showing up in listings (though they will still be in the database)',
@@ -756,6 +881,22 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'required',
     'description' => 'Return address on email invoices',
     'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'invoice_subject',
+    'section'     => 'billing',
+    'description' => 'Subject: header on email invoices.  Defaults to "Invoice".  The following substitutions are available: $name, $name_short, $invoice_number, and $invoice_date.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'invoice_usesummary',
+    'section'     => 'billing',
+    'description' => 'Indicates that html and latex invoices should be in summary style and make use of invoice_latexsummary.',
+    'type'        => 'checkbox',
   },
 
   {
@@ -778,6 +919,7 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'billing',
     'description' => 'Notes section for HTML invoices.  Defaults to the same data in invoice_latexnotes if not specified.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
@@ -785,6 +927,15 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'billing',
     'description' => 'Footer for HTML invoices.  Defaults to the same data in invoice_latexfooter if not specified.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'invoice_htmlsummary',
+    'section'     => 'billing',
+    'description' => 'Summary initial page for HTML invoices.',
+    'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
@@ -806,6 +957,7 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'billing',
     'description' => 'Notes section for LaTeX typeset PostScript invoices.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
@@ -813,6 +965,15 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'billing',
     'description' => 'Footer for LaTeX typeset PostScript invoices.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'invoice_latexsummary',
+    'section'     => 'billing',
+    'description' => 'Summary initial page for LaTeX typeset PostScript invoices.',
+    'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
@@ -820,6 +981,7 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'billing',
     'description' => 'Remittance coupon for LaTeX typeset PostScript invoices.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
@@ -834,6 +996,7 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'billing',
     'description' => 'Optional small footer for multi-page LaTeX typeset PostScript invoices.',
     'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
@@ -862,10 +1025,17 @@ worry that config_items is freeside-specific and icky.
   { 
     'key'         => 'invoice_sections',
     'section'     => 'billing',
-    'description' => 'Split invoice into sections and label according to package class when enabled.',
+    'description' => 'Split invoice into sections and label according to package category when enabled.',
     'type'        => 'checkbox',
   },
 
+  {
+    'key'         => 'finance_pkgclass',
+    'section'     => 'billing',
+    'description' => 'The package class for finance charges',
+    'type'        => 'select-pkg_class',
+  },
+
   { 
     'key'         => 'separate_usage',
     'section'     => 'billing',
@@ -874,13 +1044,31 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'invoice_send_receipts',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, this used to send an invoice copy on payments and credits.  See the payment_receipt_email and XXXX instead.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'payment_receipt_email',
     'section'     => 'billing',
-    'description' => 'Template file for payment receipts.  Payment receipts are sent to the customer email invoice destination(s) when a payment is received.  See the <a href="http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm">Text::Template</a> documentation for details on the template substitution language.  The following variables are available: <ul><li><code>$date</code> <li><code>$name</code> <li><code>$paynum</code> - Freeside payment number <li><code>$paid</code> - Amount of payment <li><code>$payby</code> - Payment type (Card, Check, Electronic check, etc.) <li><code>$payinfo</code> - Masked credit card number or check number <li><code>$balance</code> - New balance</ul>',
+    'description' => 'Template file for payment receipts.  Payment receipts are sent to the customer email invoice destination(s) when a payment is received.  See the <a href="http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm">Text::Template</a> documentation for details on the template substitution language.  The following variables are available: <ul><li><code>$date</code> <li><code>$name</code> <li><code>$paynum</code> - Freeside payment number <li><code>$paid</code> - Amount of payment <li><code>$payby</code> - Payment type (Card, Check, Electronic check, etc.) <li><code>$payinfo</code> - Masked credit card number or check number <li><code>$balance</code> - New balance<li><code>$pkg</code> - Package (requires payment_receipt-trigger set to "when payment is applied".)</ul>',
     'type'        => [qw( checkbox textarea )],
   },
 
   {
+    'key'         => 'payment_receipt-trigger',
+    'section'     => 'billing',
+    'description' => 'When payment receipts are triggered.  Defaults to when payment is made.',
+    'type'        => 'select',
+    'select_hash' => [
+                       'cust_pay'          => 'When payment is made.',
+                       'cust_bill_pay_pkg' => 'When payment is applied.',
+                     ],
+  },
+
+  {
     'key'         => 'lpr',
     'section'     => 'required',
     'description' => 'Print command for paper invoices, for example `lpr -h\'',
@@ -962,6 +1150,13 @@ worry that config_items is freeside-specific and icky.
 #  },
 
   {
+    'key'         => 'report_template',
+    'section'     => 'deprecated',
+    'description' => 'Deprecated template file for reports.',
+    'type'        => 'textarea',
+  },
+
+  {
     'key'         => 'maxsearchrecordsperpage',
     'section'     => 'UI',
     'description' => 'If set, number of search records to return per page.',
@@ -1099,6 +1294,7 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'username',
     'description' => 'Usernames must contain at least one letter',
     'type'        => 'checkbox',
+    'per_agent'   => 1,
   },
 
   {
@@ -1143,6 +1339,13 @@ worry that config_items is freeside-specific and icky.
     'type'        => 'checkbox',
   },
 
+  { 
+    'key'         => 'username-colon',
+    'section'     => 'username',
+    'description' => 'Allow the colon character (:) in usernames.',
+    'type'        => 'checkbox',
+  },
+
   {
     'key'         => 'safe-part_bill_event',
     'section'     => 'UI',
@@ -1265,44 +1468,29 @@ worry that config_items is freeside-specific and icky.
     'key'         => 'signup_server-default_pkgpart',
     'section'     => '',
     'description' => 'Default package for the signup server',
-    'type'        => 'select-sub',
-    'options_sub' => sub { require FS::Record;
-                           require FS::part_pkg;
-                           map { $_->pkgpart => $_->pkg.' - '.$_->comment }
-                               FS::Record::qsearch( 'part_pkg',
-                                                   { 'disabled' => ''}
-                                                 );
-                        },
-    'option_sub'  => sub { require FS::Record;
-                           require FS::part_pkg;
-                           my $part_pkg = FS::Record::qsearchs(
-                            'part_pkg', { 'pkgpart'=>shift }
-                          );
-                           $part_pkg
-                            ? $part_pkg->pkg.' - '.$part_pkg->comment
-                            : '';
-                        },
+    'type'        => 'select-part_pkg',
   },
 
   {
     'key'         => 'signup_server-default_svcpart',
     'section'     => '',
-    'description' => 'Default svcpart for the signup server - only necessary for services that trigger special provisioning widgets (such as DID provisioning).',
-    'type'        => 'select-sub',
-    'options_sub' => sub { require FS::Record;
-                           require FS::part_svc;
-                           map { $_->svcpart => $_->svc }
-                               FS::Record::qsearch( 'part_svc',
-                                                   { 'disabled' => ''}
-                                                 );
-                        },
-    'option_sub'  => sub { require FS::Record;
-                           require FS::part_svc;
-                           my $part_svc = FS::Record::qsearchs(
-                            'part_svc', { 'svcpart'=>shift }
-                          );
-                           $part_svc ? $part_svc->svc : '';
-                        },
+    'description' => 'Default service definition for the signup server - only necessary for services that trigger special provisioning widgets (such as DID provisioning).',
+    'type'        => 'select-part_svc',
+  },
+
+  {
+    'key'         => 'signup_server-mac_addr_svcparts',
+    'section'     => '',
+    'description' => 'Service definitions which can receive mac addresses (current mapped to username for svc_acct).',
+    'type'        => 'select-part_svc',
+    'multiple'    => 1,
+  },
+
+  {
+    'key'         => 'signup_server-nomadix',
+    'section'     => '',
+    'description' => 'Signup page Nomadix integration',
+    'type'        => 'checkbox',
   },
 
   {
@@ -1319,7 +1507,7 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'selfservice_server-base_url',
     'section'     => '',
-    'description' => 'Base URL for the self-service web interface - necessary for special provisioning widgets to find their way.',
+    'description' => 'Base URL for the self-service web interface - necessary for some widgets to find their way, including retrieval of non-US state information and phone number provisioning.',
     'type'        => 'text',
   },
 
@@ -1340,38 +1528,14 @@ worry that config_items is freeside-specific and icky.
     'key'         => 'signup_server-classnum2',
     'section'     => '',
     'description' => 'Package Class for first optional purchase',
-    'type'        => 'select-sub',
-    'options_sub' => sub { require FS::Record;
-                           require FS::pkg_class;
-                           map { $_->classnum => $_->classname }
-                               FS::Record::qsearch('pkg_class', {} );
-                        },
-    'option_sub'  => sub { require FS::Record;
-                           require FS::pkg_class;
-                           my $pkg_class = FS::Record::qsearchs(
-                            'pkg_class', { 'classnum'=>shift }
-                          );
-                           $pkg_class ? $pkg_class->classname : '';
-                        },
+    'type'        => 'select-pkg_class',
   },
 
   {
     'key'         => 'signup_server-classnum3',
     'section'     => '',
     'description' => 'Package Class for second optional purchase',
-    'type'        => 'select-sub',
-    'options_sub' => sub { require FS::Record;
-                           require FS::pkg_class;
-                           map { $_->classnum => $_->classname }
-                               FS::Record::qsearch('pkg_class', {} );
-                        },
-    'option_sub'  => sub { require FS::Record;
-                           require FS::pkg_class;
-                           my $pkg_class = FS::Record::qsearchs(
-                            'pkg_class', { 'classnum'=>shift }
-                          );
-                           $pkg_class ? $pkg_class->classname : '';
-                        },
+    'type'        => 'select-pkg_class',
   },
 
   {
@@ -1384,14 +1548,14 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'declinetemplate',
     'section'     => 'billing',
-    'description' => 'Template file for credit card decline emails.',
+    'description' => 'Template file for credit card and electronic check decline emails.',
     'type'        => 'textarea',
   },
 
   {
     'key'         => 'emaildecline',
     'section'     => 'billing',
-    'description' => 'Enable emailing of credit card decline notices.',
+    'description' => 'Enable emailing of credit card and electronic check decline notices.',
     'type'        => 'checkbox',
   },
 
@@ -1424,6 +1588,13 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'bill_usage_on_cancel',
+    'section'     => 'billing',
+    'description' => 'Enable automatic generation of an invoice for usage when a package is cancelled.  Not all packages can do this.  Usage data must already be available.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'require_cardname',
     'section'     => 'billing',
     'description' => 'Require an "Exact name on card" to be entered explicitly; don\'t default to using the first and last name.',
@@ -1447,7 +1618,21 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'enable_taxproducts',
     'section'     => 'billing',
-    'description' => 'Enable per-package mapping to new style tax classes',
+    'description' => 'Enable per-package mapping to vendor tax data from CCH or elsewhere.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'taxdatadirectdownload',
+    'section'     => 'billing',  #well
+    'description' => 'Enable downloading tax data directly from the vendor site',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'ignore_incalculable_taxes',
+    'section'     => 'billing',
+    'description' => 'Prefer to invoice without tax over not billing at all',
     'type'        => 'checkbox',
   },
 
@@ -1545,8 +1730,8 @@ worry that config_items is freeside-specific and icky.
 
   {
     'key'         => 'paymentforcedtobatch',
-    'section'     => 'UI',
-    'description' => 'Causes per customer payment entry to be forced to a batch processor rather than performed realtime.',
+    'section'     => 'deprecated',
+    'description' => 'See batch-enable_payby and realtime-disable_payby.  Used to (for CHEK): Cause per customer payment entry to be forced to a batch processor rather than performed realtime.',
     'type'        => 'checkbox',
   },
 
@@ -1573,6 +1758,14 @@ worry that config_items is freeside-specific and icky.
     'select_enum' => [ 'Framed-IP-Address', 'Framed-Address' ],
   },
 
+  #http://dev.coova.org/svn/coova-chilli/doc/dictionary.chillispot
+  {
+    'key'         => 'radius-chillispot-max',
+    'section'     => '',
+    'description' => 'Enable ChilliSpot (and CoovaChilli) Max attributes, specifically ChilliSpot-Max-{Input,Output,Total}-{Octets,Gigawords}.',
+    'type'        => 'checkbox',
+  },
+
   {
     'key'         => 'svc_acct-alldomains',
     'section'     => '',
@@ -1595,6 +1788,31 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'users-allow_comp',
+    'section'     => 'deprecated',
+    'description' => '<b>DEPRECATED</b>, enable the <i>Complimentary customer</i> access right instead.  Was: Usernames (Freeside users, created with <a href="../docs/man/bin/freeside-adduser.html">freeside-adduser</a>) which can create complimentary customers, one per line.  If no usernames are entered, all users can create complimentary accounts.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'credit_card-recurring_billing_flag',
+    'section'     => 'billing',
+    'description' => 'This controls when the system passes the "recurring_billing" flag on credit card transactions.  If supported by your processor (and the Business::OnlinePayment processor module), passing the flag indicates this is a recurring transaction and may turn off the CVV requirement. ',
+    'type'        => 'select',
+    'select_hash' => [
+                       'actual_oncard' => 'Default/classic behavior: set the flag if a customer has actual previous charges on the card.',
+                      'transaction_is_recur' => 'Set the flag if the transaction itself is recurring, irregardless of previous charges on the card.',
+                     ],
+  },
+
+  {
+    'key'         => 'credit_card-recurring_billing_acct_code',
+    'section'     => 'billing',
+    'description' => 'When the "recurring billing" flag is set, also set the "acct_code" to "rebill".  Useful for reporting purposes with supported gateways (PlugNPay, others?)',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'cvv-save',
     'section'     => 'billing',
     'description' => 'Save CVV2 information after the initial transaction for the selected credit card types.  Enabling this option may be in violation of your merchant agreement(s), so please check them carefully before enabling this option for any credit card types.',
@@ -1603,6 +1821,31 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'manual_process-pkgpart',
+    'section'     => 'billing',
+    'description' => 'Package to add to each manual credit card and ACH payments entered from the backend.  Enabling this option may be in violation of your merchant agreement(s), so please check them carefully before enabling this option.',
+    'type'        => 'select-part_pkg',
+  },
+
+  {
+    'key'         => 'manual_process-display',
+    'section'     => 'billing',
+    'description' => 'When using manual_process-pkgpart, add the fee to the amount entered (default), or subtract the fee from the amount entered.',
+    'type'        => 'select',
+    'select_hash' => [
+                       'add'      => 'Add fee to amount entered',
+                       'subtract' => 'Subtract fee from amount entered',
+                     ],
+  },
+
+  {
+    'key'         => 'manual_process-skip_first',
+    'section'     => 'billing',
+    'description' => "When using manual_process-pkgpart, omit the fee if it is the customer's first payment.",
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'allow_negative_charges',
     'section'     => 'billing',
     'description' => 'Allow negative charges.  Normally not used unless importing data from a legacy system that requires this.',
@@ -1647,7 +1890,8 @@ worry that config_items is freeside-specific and icky.
     'key'         => 'svc_www-usersvc_svcpart',
     'section'     => '',
     'description' => 'Allowable service definition svcparts for virtual hosts, one per line.',
-    'type'        => 'textarea',
+    'type'        => 'select-part_svc',
+    'multiple'    => 1,
   },
 
   {
@@ -1665,6 +1909,13 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'selfservice_server-single_domain',
+    'section'     => '',
+    'description' => 'If specified, only use this one domain for self-service access.',
+    'type'        => 'text',
+  },
+
+  {
     'key'         => 'card_refund-days',
     'section'     => 'billing',
     'description' => 'After a payment, the number of days a refund link will be available for that payment.  Defaults to 120.',
@@ -1687,6 +1938,14 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'global_unique-phonenum',
+    'section'     => '',
+    'description' => 'Global phone number uniqueness control: none (usual setting - check countrycode+phonenumun uniqueness per exports), or countrycode+phonenum (all countrycode+phonenum pairs are globally unique, regardless of exports).  disabled turns off duplicate checking completely and is STRONGLY NOT RECOMMENDED unless you REALLY need to turn this off.',
+    'type'        => 'select',
+    'select_enum' => [ 'none', 'countrycode+phonenum', 'disabled' ],
+  },
+
+  {
     'key'         => 'svc_external-skip_manual',
     'section'     => 'UI',
     'description' => 'When provisioning svc_external services, skip manual entry of id and title fields in the UI.  Usually used in conjunction with an export that populates these fields (i.e. artera_turbo).',
@@ -1785,6 +2044,7 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'required',
     'description' => 'Your company name',
     'type'        => 'text',
+    'per_agent'   => 1, #XXX just FS/FS/ClientAPI/Signup.pm
   },
 
   {
@@ -1792,26 +2052,62 @@ worry that config_items is freeside-specific and icky.
     'section'     => 'required',
     'description' => 'Your company address',
     'type'        => 'textarea',
+    'per_agent'   => 1,
   },
 
   {
-    'key'         => 'address2-search',
-    'section'     => 'UI',
-    'description' => 'Enable a "Unit" search box which searches the second address field.  Useful for multi-tenant applications.  See also: cust_main-require_address2',
+    'key'         => 'echeck-void',
+    'section'     => 'deprecated',
+    'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to enable local-only voiding of echeck payments in addition to refunds against the payment gateway',
     'type'        => 'checkbox',
   },
 
   {
-    'key'         => 'cust_main-require_address2',
-    'section'     => 'UI',
-    'description' => 'Second address field is required (on service address only, if billing and service addresses differ).  Also enables "Unit" labeling of address2 on customer view and edit pages.  Useful for multi-tenant applications.  See also: address2-search',
+    'key'         => 'cc-void',
+    'section'     => 'deprecated',
+    'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to enable local-only voiding of credit card payments in addition to refunds against the payment gateway',
     'type'        => 'checkbox',
   },
 
-  { 'key'         => 'referral_credit',
-    'section'     => 'billing',
-    'description' => "Enables one-time referral credits in the amount of one month <i>referred</i> customer's recurring fee (irregardless of frequency).",
-    'type'        => 'checkbox',
+  {
+    'key'         => 'unvoid',
+    'section'     => 'deprecated',
+    'description' => '<B>DEPRECATED</B>, now controlled by ACLs.  Used to enable unvoiding of voided payments',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'address1-search',
+    'section'     => 'UI',
+    'description' => 'Enable the ability to search the address1 field from customer search.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'address2-search',
+    'section'     => 'UI',
+    'description' => 'Enable a "Unit" search box which searches the second address field.  Useful for multi-tenant applications.  See also: cust_main-require_address2',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_main-require_address2',
+    'section'     => 'UI',
+    'description' => 'Second address field is required (on service address only, if billing and service addresses differ).  Also enables "Unit" labeling of address2 on customer view and edit pages.  Useful for multi-tenant applications.  See also: address2-search',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'agent-ship_address',
+    'section'     => '',
+    'description' => "Use the agent's master service address as the service address (only ship_address2 can be entered, if blank on the master address).  Useful for multi-tenant applications.",
+    'type'        => 'checkbox',
+  },
+
+  { 'key'         => 'referral_credit',
+    'section'     => 'deprecated',
+    'description' => "Used to enable one-time referral credits in the amount of one month <i>referred</i> customer's recurring fee (irregardless of frequency).  Replace with a billing event on appropriate packages.",
+    'type'        => 'checkbox',
   },
 
   { 'key'         => 'selfservice_server-cache_module',
@@ -1896,7 +2192,7 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'svc_acct-usage_threshold',
     'section'     => 'billing',
-    'description' => 'The threshold (expressed as percentage) of acct.seconds or acct.up|down|totalbytes at which a warning message is sent to a service holder.  Typically used in conjunction with prepaid packages and freeside-sqlradius-radacctd.  Defaults to 80.',
+    'description' => 'The threshold (expressed as percentage) of acct.seconds or acct.up|down|totalbytes at which a warning message is sent to a service holder.  Typically used in conjunction with prepaid packages and freeside-sqlradius-radacctd.',
     'type'        => 'text',
   },
 
@@ -1916,6 +2212,13 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'cust_pkg-always_show_location',
+    'section'     => 'UI',
+    'description' => "Always display package locations, even when they're all the default service address.",
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'svc_acct-edit_uid',
     'section'     => 'shell',
     'description' => 'Allow UID editing.',
@@ -1958,6 +2261,20 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'voip-cdr_email',
+    'section'     => '',
+    'description' => 'Include the call details on emailed invoices even if the customer is configured for not printing them on the invoices.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'voip-cust_email_csv_cdr',
+    'section'     => '',
+    'description' => 'Enable the per-customer option for including CDR information as a CSV attachment on emailed invoices.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'svc_forward-arbitrary_dst',
     'section'     => '',
     'description' => "Allow forwards to point to arbitrary strings that don't necessarily look like email addresses.  Only used when using forwards for weird, non-email things.",
@@ -1967,21 +2284,42 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'tax-ship_address',
     'section'     => 'billing',
-    'description' => 'By default, tax calculations are done based on the billing address.  Enable this switch to calculate tax based on the shipping address instead.  Note: Tax reports can take a long time when enabled.',
+    'description' => 'By default, tax calculations are done based on the billing address.  Enable this switch to calculate tax based on the shipping address instead.',
+    'type'        => 'checkbox',
+  }
+,
+  {
+    'key'         => 'tax-pkg_address',
+    'section'     => 'billing',
+    'description' => 'By default, tax calculations are done based on the billing address.  Enable this switch to calculate tax based on the package address instead (when present).  Note that this option is currently incompatible with vendor data taxation enabled by enable_taxproducts.',
     'type'        => 'checkbox',
   },
 
   {
     'key'         => 'invoice-ship_address',
     'section'     => 'billing',
-    'description' => 'Enable this switch to include the ship address on the invoice.',
+    'description' => 'Include the shipping address on invoices.',
     'type'        => 'checkbox',
   },
 
   {
     'key'         => 'invoice-unitprice',
     'section'     => 'billing',
-    'description' => 'This switch enables unit pricing on the invoice.',
+    'description' => 'Enable unit pricing on invoices.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'invoice-smallernotes',
+    'section'     => 'billing',
+    'description' => 'Display the notes section in a smaller font on invoices.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'invoice-smallerfooter',
+    'section'     => 'billing',
+    'description' => 'Display footers in a smaller font on invoices.',
     'type'        => 'checkbox',
   },
 
@@ -1989,46 +2327,59 @@ worry that config_items is freeside-specific and icky.
     'key'         => 'postal_invoice-fee_pkgpart',
     'section'     => 'billing',
     'description' => 'This allows selection of a package to insert on invoices for customers with postal invoices selected.',
-    'type'        => 'select-sub',
-    'options_sub' => sub { require FS::Record;
-                           require FS::part_pkg;
-                          map { $_->pkgpart => $_->pkg }
-                               FS::Record::qsearch('part_pkg', { disabled=>'' } );
-                        },
-    'option_sub'  => sub { require FS::Record;
-                           require FS::part_pkg;
-                          my $part_pkg = FS::Record::qsearchs(
-                            'part_pkg', { 'pkgpart'=>shift }
-                          );
-                           $part_pkg ? $part_pkg->pkg : '';
-                        },
+    'type'        => 'select-part_pkg',
   },
 
   {
-    'key'         => 'batch-enable',
+    'key'         => 'postal_invoice-recurring_only',
     'section'     => 'billing',
+    'description' => 'The postal invoice fee is omitted on invoices without reucrring charges when this is set.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'batch-enable',
+    'section'     => 'deprecated', #make sure batch-enable_payby is set for
+                                   #everyone before removing
     'description' => 'Enable credit card and/or ACH batching - leave disabled for real-time installations.',
     'type'        => 'checkbox',
   },
 
   {
+    'key'         => 'batch-enable_payby',
+    'section'     => 'billing',
+    'description' => 'Enable batch processing for the specified payment types.',
+    'type'        => 'selectmultiple',
+    'select_enum' => [qw( CARD CHEK )],
+  },
+
+  {
+    'key'         => 'realtime-disable_payby',
+    'section'     => 'billing',
+    'description' => 'Disable realtime processing for the specified payment types.',
+    'type'        => 'selectmultiple',
+    'select_enum' => [qw( CARD CHEK )],
+  },
+
+  {
     'key'         => 'batch-default_format',
     'section'     => 'billing',
     'description' => 'Default format for batches.',
     'type'        => 'select',
     'select_enum' => [ 'csv-td_canada_trust-merchant_pc_batch',
                        'csv-chase_canada-E-xactBatch', 'BoM', 'PAP',
-                       'ach-spiritone',
+                       'paymentech', 'ach-spiritone',
                     ]
   },
 
+  #lists could be auto-generated from pay_batch info
   {
     'key'         => 'batch-fixed_format-CARD',
     'section'     => 'billing',
     'description' => 'Fixed (unchangeable) format for credit card batches.',
     'type'        => 'select',
     'select_enum' => [ 'csv-td_canada_trust-merchant_pc_batch', 'BoM', 'PAP' ,
-                       'csv-chase_canada-E-xactBatch', 'BoM', 'PAP' ]
+                       'csv-chase_canada-E-xactBatch', 'paymentech' ]
   },
 
   {
@@ -2037,7 +2388,7 @@ worry that config_items is freeside-specific and icky.
     'description' => 'Fixed (unchangeable) format for electronic check batches.',
     'type'        => 'select',
     'select_enum' => [ 'csv-td_canada_trust-merchant_pc_batch', 'BoM', 'PAP',
-                       'ach-spiritone',
+                       'paymentech', 'ach-spiritone',
                      ]
   },
 
@@ -2070,6 +2421,13 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'batchconfig-paymentech',
+    'section'     => 'billing',
+    'description' => 'Configuration for Chase Paymentech batching, five lines: 1. BIN, 2. Terminal ID, 3. Merchant ID, 4. Username, 5. Password (for batch uploads)',
+    'type'        => 'textarea',
+  },
+
+  {
     'key'         => 'payment_history-years',
     'section'     => 'UI',
     'description' => 'Number of years of payment history to show by default.  Currently defaults to 2.',
@@ -2077,6 +2435,20 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'change_history-years',
+    'section'     => 'UI',
+    'description' => 'Number of years of change history to show by default.  Currently defaults to 0.5.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'cust_main-packages-years',
+    'section'     => 'UI',
+    'description' => 'Number of years to show old (cancelled and one-time charge) packages by default.  Currently defaults to 2.',
+    'type'        => 'text',
+  },
+
+  {
     'key'         => 'cust_main-use_comments',
     'section'     => 'UI',
     'description' => 'Display free form comments on the customer edit screen.  Useful as a scratch pad.',
@@ -2168,6 +2540,14 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'dashboard-install_welcome',
+    'section'     => 'UI',
+    'description' => 'New install welcome screen.',
+    'type'        => 'select',
+    'select_enum' => [ '', 'ITSP_fsinc_hosted', ],
+  },
+
+  {
     'key'         => 'dashboard-toplist',
     'section'     => 'UI',
     'description' => 'List of items to display on the top of the front page',
@@ -2185,15 +2565,18 @@ worry that config_items is freeside-specific and icky.
   {
     'key'         => 'logo.png',
     'section'     => 'billing',  #? 
-    'description' => 'An image to include in some types of invoices',
-    'type'        => 'binary',
+    'description' => 'Company logo for HTML invoices and the backoffice interface, in PNG format.  Suggested size somewhere near 92x62.',
+    'type'        => 'image',
+    'per_agent'   => 1, #XXX just view/logo.cgi, which is for the global
+                        #old-style editor anyway...?
   },
 
   {
     'key'         => 'logo.eps',
     'section'     => 'billing',  #? 
-    'description' => 'An image to include in some types of invoices',
-    'type'        => 'binary',
+    'description' => 'Company logo for printed and PDF invoices, in EPS format.',
+    'type'        => 'image',
+    'per_agent'   => 1, #XXX as above, kinda
   },
 
   {
@@ -2257,13 +2640,14 @@ worry that config_items is freeside-specific and icky.
     'key'         => 'support_packages',
     'section'     => '',
     'description' => 'A list of packages eligible for RT ticket time transfer, one pkgpart per line.', #this should really be a select multiple, or specified in the packages themselves...
-    'type'        => 'textarea',
+    'type'        => 'select-part_pkg',
+    'multiple'    => 1,
   },
 
   {
     'key'         => 'cust_main-require_phone',
     'section'     => '',
-    'description' => 'Require daytime or night for all customer records.',
+    'description' => 'Require daytime or night phone for all customer records.',
     'type'        => 'checkbox',
   },
 
@@ -2302,8 +2686,8 @@ worry that config_items is freeside-specific and icky.
 
   {
     'key'         => 'referral_credit_type',
-    'section'     => 'billing',
-    'description' => 'The group to use for new, automatically generated credit reasons resulting from referrals.',
+    'section'     => 'deprecated',
+    'description' => 'Used to be the group to use for new, automatically generated credit reasons resulting from referrals.  Now set in a package billing event for the referral.',
     'type'        => 'select-sub',
     'options_sub' => sub { require FS::Record;
                            require FS::reason_type;
@@ -2374,6 +2758,13 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'previous_balance-summary_only',
+    'section'     => 'billing',
+    'description' => 'Only show a single line summarizing the total previous balance rather than one line per invoice.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'usps_webtools-userid',
     'section'     => 'UI',
     'description' => 'Production UserID for USPS web tools.   Enables USPS address standardization.  See the <a href="http://www.usps.com/webtools/">USPS website</a>, register and agree not to use the tools for batch purposes.',
@@ -2395,6 +2786,35 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'cust_main-require_censustract',
+    'section'     => 'UI',
+    'description' => 'Customer is required to have a census tract.  Useful for FCC form 477 reports. See also: cust_main-auto_standardize_address',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'census_year',
+    'section'     => 'UI',
+    'description' => 'The year to use in census tract lookups',
+    'type'        => 'select',
+    'select_enum' => [ qw( 2009 2008 2007 2006 ) ],
+  },
+
+  {
+    'key'         => 'company_latitude',
+    'section'     => 'UI',
+    'description' => 'Your company latitude (-90 through 90)',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'company_longitude',
+    'section'     => 'UI',
+    'description' => 'Your company longitude (-180 thru 180)',
+    'type'        => 'text',
+  },
+
+  {
     'key'         => 'disable_acl_changes',
     'section'     => '',
     'description' => 'Disable all ACL changes, for demos.',
@@ -2409,6 +2829,30 @@ worry that config_items is freeside-specific and icky.
   },
 
   {
+    'key'         => 'cust_main-default_agent_custid',
+    'section'     => 'UI',
+    'description' => 'Display the agent_custid field when available instead of the custnum field.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_bill-default_agent_invid',
+    'section'     => 'UI',
+    'description' => 'Display the agent_invid field when available instead of the invnum field.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_main-auto_agent_custid',
+    'section'     => 'UI',
+    'description' => 'Automatically assign an agent_custid - select format',
+    'type'        => 'select',
+    'select_hash' => [ '' => 'No',
+                       '1YMMXXXXXXXX' => '1YMMXXXXXXXX',
+                     ],
+  },
+
+  {
     'key'         => 'cust_main-default_areacode',
     'section'     => 'UI',
     'description' => 'Default area code for customers.',
@@ -2419,9 +2863,411 @@ worry that config_items is freeside-specific and icky.
     'key'         => 'mcp_svcpart',
     'section'     => '',
     'description' => 'Master Control Program svcpart.  Leave this blank.',
+    'type'        => 'text', #select-part_svc
+  },
+
+  {
+    'key'         => 'cust_bill-max_same_services',
+    'section'     => 'billing',
+    'description' => 'Maximum number of the same service to list individually on invoices before condensing to a single line listing the number of services.  Defaults to 5.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'cust_bill-consolidate_services',
+    'section'     => 'billing',
+    'description' => 'Consolidate service display into fewer lines on invoices rather than one per service.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'suspend_email_admin',
+    'section'     => '',
+    'description' => 'Destination admin email address to enable suspension notices',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'email_report-subject',
+    'section'     => '',
+    'description' => 'Subject for reports emailed by freeside-fetch.  Defaults to "Freeside report".',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'selfservice-head',
+    'section'     => '',
+    'description' => 'HTML for the HEAD section of the self-service interface, typically used for LINK stylesheet tags',
+    'type'        => 'textarea', #htmlarea?
+    'per_agent'   => 1,
+  },
+
+
+  {
+    'key'         => 'selfservice-body_header',
+    'section'     => '',
+    'description' => 'HTML header for the self-service interface',
+    'type'        => 'textarea', #htmlarea?
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'selfservice-body_footer',
+    'section'     => '',
+    'description' => 'HTML header for the self-service interface',
+    'type'        => 'textarea', #htmlarea?
+    'per_agent'   => 1,
+  },
+
+
+  {
+    'key'         => 'selfservice-body_bgcolor',
+    'section'     => '',
+    'description' => 'HTML background color for the self-service interface, for example, #FFFFFF',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'selfservice-box_bgcolor',
+    'section'     => '',
+    'description' => 'HTML color for self-service interface input boxes, for example, #C0C0C0"',
     'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'selfservice-bulk_format',
+    'section'     => '',
+    'description' => 'Parameter arrangement for selfservice bulk features',
+    'type'        => 'select',
+    'select_enum' => [ '', 'izoom-soap', 'izoom-ftp' ],
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'selfservice-bulk_ftp_dir',
+    'section'     => '',
+    'description' => 'Enable bulk ftp provisioning in this folder',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'signup-no_company',
+    'section'     => '',
+    'description' => "Don't display a field for company name on signup.",
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'signup-recommend_email',
+    'section'     => '',
+    'description' => 'Encourage the entry of an invoicing email address on signup.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'signup-recommend_daytime',
+    'section'     => '',
+    'description' => 'Encourage the entry of a daytime phone number  invoicing email address on signup.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'svc_phone-radius-default_password',
+    'section'     => '',
+    'description' => 'Default password when exporting svc_phone records to RADIUS',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'svc_phone-allow_alpha_phonenum',
+    'section'     => '',
+    'description' => 'Allow letters in phone numbers.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'default_phone_countrycode',
+    'section'     => '',
+    'description' => 'Default countrcode',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'cdr-charged_party-accountcode',
+    'section'     => '',
+    'description' => 'Set the charged_party field of CDRs to the accountcode.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cdr-charged_party-accountcode-trim_leading_0s',
+    'section'     => '',
+    'description' => 'When setting the charged_party field of CDRs to the accountcode, trim any leading zeros.',
+    'type'        => 'checkbox',
+  },
+
+#  {
+#    'key'         => 'cdr-charged_party-truncate_prefix',
+#    'section'     => '',
+#    'description' => 'If the charged_party field has this prefix, truncate it to the length in cdr-charged_party-truncate_length.',
+#    'type'        => 'text',
+#  },
+#
+#  {
+#    'key'         => 'cdr-charged_party-truncate_length',
+#    'section'     => '',
+#    'description' => 'If the charged_party field has the prefix in cdr-charged_party-truncate_prefix, truncate it to this length.',
+#    'type'        => 'text',
+#  },
+
+  {
+    'key'         => 'cdr-charged_party_rewrite',
+    'section'     => '',
+    'description' => 'Do charged party rewriting in the freeside-cdrrewrited daemon; useful if CDRs are being dropped off directly in the database and require special charged_party processing such as cdr-charged_party-accountcode or cdr-charged_party-truncate*.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cdr-taqua-da_rewrite',
+    'section'     => '',
+    'description' => 'For the Taqua CDR format, a comma-separated list of directory assistance 800 numbers.  Any CDRs with these numbers as "BilledNumber" will be rewritten to the "CallingPartyNumber" (and CallType "12") on import.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'cust_pkg-show_autosuspend',
+    'section'     => 'UI',
+    'description' => 'Show package auto-suspend dates.  Use with caution for now; can slow down customer view for large insallations.',
+    'type'       => 'checkbox',
+  },
+
+  {
+    'key'         => 'cdr-asterisk_forward_rewrite',
+    'section'     => '',
+    'description' => 'Enable special processing for CDRs representing forwarded calls: For CDRs that have a dcontext that starts with "Local/" but does not match dst, set charged_party to dst, parse a new dst from dstchannel, and set amaflags to "2" ("BILL"/"BILLING").',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'sg-multicustomer_hack',
+    'section'     => '',
+    'description' => "Don't use this.",
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'sg-ping_username',
+    'section'     => '',
+    'description' => "Don't use this.",
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'sg-ping_password',
+    'section'     => '',
+    'description' => "Don't use this.",
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'sg-login_username',
+    'section'     => '',
+    'description' => "Don't use this.",
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'disable-cust-pkg_class',
+    'section'     => 'UI',
+    'description' => 'Disable the two-step dropdown for selecting package class and package, and return to the classic single dropdown.',
+    'type'        => 'checkbox',
   },
 
+  {
+    'key'         => 'queued-max_kids',
+    'section'     => '',
+    'description' => 'Maximum number of queued processes.  Defaults to 10.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'cancelled_cust-noevents',
+    'section'     => 'billing',
+    'description' => "Don't run events for cancelled customers",
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'agent-invoice_template',
+    'section'     => 'billing',
+    'description' => 'Enable display/edit of old-style per-agent invoice template selection',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'svc_broadband-manage_link',
+    'section'     => 'UI',
+    'description' => 'URL for svc_broadband "Manage Device" link.  The following substitutions are available: $ip_addr.',
+    'type'        => 'text',
+  },
+
+  #more fine-grained, service def-level control could be useful eventually?
+  {
+    'key'         => 'svc_broadband-allow_null_ip_addr',
+    'section'     => '',
+    'description' => '',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'tax-report_groups',
+    'section'     => '',
+    'description' => 'List of grouping possibilities for tax names on reports, one per line, "label op value" (op can be = or !=).',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'tax-cust_exempt-groups',
+    'section'     => '',
+    'description' => 'List of grouping possibilities for tax names, for per-customer exemption purposes, one tax name per line.  For example, "GST" would indicate the ability to exempt customers individually from taxes named "GST" (but not other taxes).',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'cust_main-default_view',
+    'section'     => 'UI',
+    'description' => 'Default customer view, for users who have not selected a default view in their preferences.',
+    'type'        => 'select',
+    'select_hash' => [
+      #false laziness w/view/cust_main.cgi and pref/pref.html
+      'basics'          => 'Basics',
+      'notes'           => 'Notes',
+      'tickets'         => 'Tickets',
+      'packages'        => 'Packages',
+      'payment_history' => 'Payment History',
+      'change_history'  => 'Change History',
+      'jumbo'           => 'Jumbo',
+    ],
+  },
+
+  {
+    'key'         => 'enable_tax_adjustments',
+    'section'     => 'billing',
+    'description' => 'Enable the ability to add manual tax adjustments.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'rt-crontool',
+    'section'     => '',
+    'description' => 'Enable the RT CronTool extension.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'pkg-balances',
+    'section'     => 'billing',
+    'description' => 'Enable experimental package balances.  Not recommended for general use.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'pkg-addon_classnum',
+    'section'     => 'billing',
+    'description' => 'Enable the ability to restrict additional package orders based on package class.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_main-edit_signupdate',
+    'section'     => 'UI',
+    'descritpion' => 'Enable manual editing of the signup date.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'svc_acct-disable_access_number',
+    'section'     => 'UI',
+    'descritpion' => 'Disable access number selection.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_bill_pay_pkg-manual',
+    'section'     => 'UI',
+    'description' => 'Allow manual application of payments to line items.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_credit_bill_pkg-manual',
+    'section'     => 'UI',
+    'description' => 'Allow manual application of credits to line items.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'breakage-days',
+    'section'     => 'billing',
+    'description' => 'If set to a number of days, after an account goes that long without activity, recognizes any outstanding payments and credits as "breakage" by creating a breakage charge and invoice.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'breakage-pkg_class',
+    'section'     => 'billing',
+    'description' => 'Package class to use for breakage reconciliation.',
+    'type'        => 'select-pkg_class',
+  },
+
+
+  { key => "apacheroot", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "apachemachine", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "apachemachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "bindprimary", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "bindsecondaries", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "bsdshellmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "cyrus", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "cp_app", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "erpcdmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "icradiusmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "icradius_mysqldest", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "icradius_mysqlsource", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "icradius_secrets", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "maildisablecatchall", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "mxmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "nsmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "arecords", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "cnamerecords", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "nismachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "qmailmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "radiusmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "sendmailconfigpath", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "sendmailmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "sendmailrestart", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "shellmachine", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "shellmachine-useradd", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "shellmachine-userdel", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "shellmachine-usermod", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "shellmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "radiusprepend", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "textradiusprepend", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "username_policy", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "vpopmailmachines", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "vpopmailrestart", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "safe-part_pkg", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "selfservice_server-quiet", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "signup_server-quiet", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "signup_server-email", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "vonage-username", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "vonage-password", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+  { key => "vonage-fromnumber", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
+
 );
 
 1;
+