verify credit card changes via $1 auth, RT#37632
[freeside.git] / FS / FS / Conf.pm
index 4c02797..c7bf65f 100644 (file)
@@ -1,6 +1,7 @@
 package FS::Conf;
 
 use vars qw($base_dir @config_items @base_items @card_types $DEBUG);
+use strict;
 use Carp;
 use IO::File;
 use File::Basename;
@@ -592,6 +593,21 @@ sub config_items {
   ( @config_items, $self->_orbase_items(@_) );
 }
 
+=item invoice_from_full [ AGENTNUM ]
+
+Returns values of invoice_from and invoice_from_name, appropriately combined
+based on their current values.
+
+=cut
+
+sub invoice_from_full {
+  my ($self, $agentnum) = @_;
+  return $self->config('invoice_from_name', $agentnum ) ?
+         $self->config('invoice_from_name', $agentnum ) . ' <' .
+         $self->config('invoice_from', $agentnum ) . '>' :
+         $self->config('invoice_from', $agentnum );
+}
+
 =back
 
 =head1 SUBROUTINES
@@ -663,10 +679,12 @@ invoice_latexfooter
 invoice_latexsmallfooter
 invoice_latexnotes
 invoice_latexcoupon
+invoice_latexwatermark
 invoice_html
 invoice_htmlreturnaddress
 invoice_htmlfooter
 invoice_htmlnotes
+invoice_htmlwatermark
 logo.png
 logo.eps
 );
@@ -717,6 +735,23 @@ my %batch_gateway_options = (
   },
 );
 
+my %invoice_mode_options = (
+  'type'        => 'select-sub',
+  'options_sub' => sub { 
+    my @modes = qsearch({
+        'table' => 'invoice_mode', 
+        'extra_sql' => ' WHERE '.
+          $FS::CurrentUser::CurrentUser->agentnums_sql(null => 1),
+        });
+    map { $_->modenum, $_->modename } @modes;
+  },
+  'option_sub'  => sub { 
+                         my $mode = FS::invoice_mode->by_key(shift);
+                         $mode ? $mode->modename : '',
+                       },
+  'per_agent' => 1,
+);
+
 my @cdr_formats = (
   '' => '',
   'default' => 'Default',
@@ -744,6 +779,11 @@ sub reason_type_options {
   }
 }
 
+my $validate_email = sub { $_[0] =~
+                             /^[^@]+\@[[:alnum:]-]+(\.[[:alnum:]-]+)+$/
+                             ? '' : 'Invalid email address';
+                         };
+
 #Billing (81 items)
 #Invoicing (50 items)
 #UI (69 items)
@@ -957,7 +997,7 @@ sub reason_type_options {
   {
     '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.',
+    '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.  For more detailed information and examples see the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:3:Documentation:Administration:Real-time_Processing">real-time credit card processing documentation</a>.',
     'type'        => 'textarea',
   },
 
@@ -1016,6 +1056,13 @@ sub reason_type_options {
   },
 
   {
+    'key'         => 'business-onlinepayment-verification',
+    'section'     => 'billing',
+    'description' => 'Run a $1 authorization (followed by a void) to verify new credit card information.',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'currency',
     'section'     => 'billing',
     'description' => 'Currency',
@@ -1233,12 +1280,33 @@ sub reason_type_options {
   {
     'key'         => 'invoice_from',
     'section'     => 'required',
-    'description' => 'Return address on email invoices',
+    'description' => 'Return address on email invoices (address only, see invoice_from_name)',
+    'type'        => 'text',
+    'per_agent'   => 1,
+    'validate'    => $validate_email,
+  },
+
+  {
+    'key'         => 'invoice_from_name',
+    'section'     => 'invoicing',
+    'description' => 'Return name on email invoices (set address in invoice_from)',
     'type'        => 'text',
     'per_agent'   => 1,
+    'validate'    => sub { (($_[0] =~ /[^[:alnum:][:space:]]/) && ($_[0] !~ /^\".*\"$/))
+                           ? 'Invalid name.  Use quotation marks around names that contain punctuation.'
+                           : '' }
   },
 
   {
+    'key'         => 'quotation_from',
+    'section'     => '',
+    'description' => 'Return address on email quotations',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+
+  {
     'key'         => 'invoice_subject',
     'section'     => 'invoicing',
     'description' => 'Subject: header on email invoices.  Defaults to "Invoice".  The following substitutions are available: $name, $name_short, $invoice_number, and $invoice_date.',
@@ -1248,6 +1316,15 @@ sub reason_type_options {
   },
 
   {
+    'key'         => 'quotation_subject',
+    'section'     => '',
+    'description' => 'Subject: header on email quotations.  Defaults to "Quotation".', #  The following substitutions are available: $name, $name_short, $invoice_number, and $invoice_date.',
+    'type'        => 'text',
+    #'per_agent'   => 1,
+    'per_locale'  => 1,
+  },
+
+  {
     'key'         => 'invoice_usesummary',
     'section'     => 'invoicing',
     'description' => 'Indicates that html and latex invoices should be in summary style and make use of invoice_latexsummary.',
@@ -1313,6 +1390,15 @@ sub reason_type_options {
   },
 
   {
+    'key'         => 'invoice_htmlwatermark',
+    'section'     => 'invoicing',
+    'description' => 'Watermark for HTML invoices. Appears in a semitransparent positioned DIV overlaid on the main invoice container.',
+    'type'        => 'textarea',
+    'per_agent'   => 1,
+    'per_locale'  => 1,
+  },
+
+  {
     'key'         => 'invoice_latex',
     'section'     => 'invoicing',
     'description' => 'Optional LaTeX template for typeset PostScript invoices.  See the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:2.1:Documentation:Administration#Typeset_.28LaTeX.29_invoice_templates">billing documentation</a> for details.',
@@ -1423,7 +1509,7 @@ and customer address. Include units.',
   {
     'key'         => 'invoice_latexextracouponspace',
     'section'     => 'invoicing',
-    'description' => 'Optional LaTeX invoice textheight space to reserve for a tear off coupon.  Include units.  Default is 3.6cm',
+    'description' => 'Optional LaTeX invoice textheight space to reserve for a tear off coupon.  Include units.  Default is 2.7 inches.',
     'type'        => 'text',
     'per_agent'   => 1,
     'validate'    => sub { shift =~
@@ -1435,7 +1521,7 @@ and customer address. Include units.',
   {
     'key'         => 'invoice_latexcouponfootsep',
     'section'     => 'invoicing',
-    'description' => 'Optional LaTeX invoice separation between tear off coupon and footer. Include units.',
+    'description' => 'Optional LaTeX invoice separation between bottom of coupon address and footer. Include units. Default is 0.2 inches.',
     'type'        => 'text',
     'per_agent'   => 1,
     'validate'    => sub { shift =~
@@ -1447,7 +1533,7 @@ and customer address. Include units.',
   {
     'key'         => 'invoice_latexcouponamountenclosedsep',
     'section'     => 'invoicing',
-    'description' => 'Optional LaTeX invoice separation between total due and amount enclosed line. Include units.',
+    'description' => 'Optional LaTeX invoice separation between total due and amount enclosed line. Include units. Default is 2.25 em.',
     'type'        => 'text',
     'per_agent'   => 1,
     'validate'    => sub { shift =~
@@ -1458,7 +1544,7 @@ and customer address. Include units.',
   {
     'key'         => 'invoice_latexcoupontoaddresssep',
     'section'     => 'invoicing',
-    'description' => 'Optional LaTeX invoice separation between invoice data and the to address (usually invoice_latexreturnaddress).  Include units.',
+    'description' => 'Optional LaTeX invoice separation between invoice data and the address (usually invoice_latexreturnaddress).  Include units. Default is 1 inch.',
     'type'        => 'text',
     'per_agent'   => 1,
     'validate'    => sub { shift =~
@@ -1476,8 +1562,8 @@ and customer address. Include units.',
 
   {
     'key'         => 'invoice_latexverticalreturnaddress',
-    'section'     => 'invoicing',
-    'description' => 'Place the return address under the company logo rather than beside it.',
+    'section'     => 'deprecated',
+    'description' => 'Deprecated.  With old invoice_latex template, places the return address under the company logo rather than beside it.',
     'type'        => 'checkbox',
     'per_agent'   => 1,
   },
@@ -1500,16 +1586,46 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'invoice_latexwatermark',
+    'section'     => 'invoicing',
+    'description' => 'Watermark for LaTeX invoices. See "texdoc background" for information on what this can contain. The content itself should be enclosed in braces, optionally followed by a comma and any formatting options.',
+    'type'        => 'textarea',
+    'per_agent'   => 1,
+    'per_locale'  => 1,
+  },
+
+  {
     'key'         => 'invoice_email_pdf',
     'section'     => 'invoicing',
-    'description' => 'Send PDF invoice as an attachment to emailed invoices.  By default, includes the plain text invoice as the email body, unless invoice_email_pdf_note is set.',
+    'description' => 'Send PDF invoice as an attachment to emailed invoices.  By default, includes the HTML invoice as the email body, unless invoice_email_pdf_note is set.',
     'type'        => 'checkbox'
   },
 
   {
+    'key'         => 'quotation_email_pdf',
+    'section'     => '',
+    'description' => 'Send PDF quotations as an attachment to emailed quotations.  By default, includes the HTML quotation as the email body, unless quotation_email_pdf_note is set.',
+    'type'        => 'checkbox'
+  },
+
+  {
+    'key'         => 'invoice_email_pdf_msgnum',
+    'section'     => 'invoicing',
+    'description' => 'Message template to send as the text and HTML part of PDF invoices. If not selected, a text and HTML version of the invoice will be sent.',
+    %msg_template_options,
+  },
+
+  {
     'key'         => 'invoice_email_pdf_note',
     'section'     => 'invoicing',
-    'description' => 'If defined, this text will replace the default plain text invoice as the body of emailed PDF invoices.',
+    'description' => 'If defined, this text will replace the default HTML invoice as the body of emailed PDF invoices.',
+    'type'        => 'textarea'
+  },
+
+  {
+    'key'         => 'quotation_email_pdf_note',
+    'section'     => '',
+    'description' => 'If defined, this text will replace the default HTML quotation as the body of emailed PDF quotations.',
     'type'        => 'textarea'
   },
 
@@ -1539,8 +1655,9 @@ and customer address. Include units.',
     'section'     => 'invoicing',
     'description' => 'Optional default invoice term, used to calculate a due date printed on invoices.',
     'type'        => 'select',
+    'per_agent'   => 1,
     'select_enum' => [ 
-      '', 'Payable upon receipt', 'Net 0', 'Net 3', 'Net 5', 'Net 9', 'Net 10', 'Net 14', 
+      '', 'Payable upon receipt', 'Net 0', 'Net 3', 'Net 5', 'Net 7', 'Net 9', 'Net 10', 'Net 14', 
       'Net 15', 'Net 18', 'Net 20', 'Net 21', 'Net 25', 'Net 30', 'Net 45', 
       'Net 60', 'Net 90'
     ], },
@@ -1651,9 +1768,16 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'payment_receipt_statement_mode',
+    'section'     => 'notification',
+    'description' => 'Automatic payments will cause a post-payment statement to be sent to the customer. Select the invoice mode to use for this statement. If unspecified, it will use the "_statement" versions of invoice configuration settings, and have the notice name "Statement".',
+    %invoice_mode_options,
+  },
+
+  {
     'key'         => 'payment_receipt_msgnum',
     'section'     => 'notification',
-    'description' => 'Template to use for payment receipts.',
+    'description' => 'Template to use for manual payment receipts.',
     %msg_template_options,
   },
   
@@ -1685,6 +1809,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'refund_receipt_msgnum',
+    'section'     => 'notification',
+    'description' => 'Template to use for manual refund receipts.',
+    %msg_template_options,
+  },
+  
+  {
     'key'         => 'trigger_export_insert_on_payment',
     'section'     => 'billing',
     'description' => 'Enable exports on payment application.',
@@ -1977,10 +2108,13 @@ and customer address. Include units.',
   },
 
   {
-    'key'         => 'unsuspendauto',
+    'key'         => 'unsuspend_balance',
     'section'     => 'billing',
-    'description' => 'Enables the automatic unsuspension of suspended packages when a customer\'s balance due changes from positive to zero or negative as the result of a payment or credit',
-    'type'        => 'checkbox',
+    'description' => 'Enables the automatic unsuspension of suspended packages when a customer\'s balance due is at or below the specified amount after a payment or credit',
+    'type'        => 'select',
+    'select_enum' => [ 
+      '', 'Zero', 'Latest invoice charges', 'Charges not past due'
+    ],
   },
 
   {
@@ -2282,6 +2416,7 @@ and customer address. Include units.',
                        'svc_acct'  => 'Account (svc_acct)',
                        'svc_phone' => 'Phone number (svc_phone)',
                        'svc_pbx'   => 'PBX (svc_pbx)',
+                       'none'      => 'None - package only',
                      ],
   },
   
@@ -2574,7 +2709,7 @@ and customer address. Include units.',
     'section'     => 'billing',
     'description' => 'Available payment types.',
     'type'        => 'selectmultiple',
-    'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB BILL CASH WEST MCRD PPAL COMP) ],
+    'select_enum' => [ qw(CARD DCRD CHEK DCHK LECB BILL CASH WEST MCRD MCHK PPAL COMP) ],
   },
 
   {
@@ -2631,6 +2766,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'radius-canopy',
+    'section'     => '',
+    'description' => 'Enable RADIUS attributes for Cambium (formerly Motorola) Canopy (Motorola-Canopy-Gateway).',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'svc_broadband-radius',
     'section'     => '',
     'description' => 'Enable RADIUS groups for broadband services.',
@@ -2666,6 +2808,14 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'dump-email_to',
+    'section'     => '',
+    'description' => "Optional email address to send success/failure message for database dumps.",
+    'type'        => 'text',
+    'validate'    => $validate_email,
+  },
+
+  {
     '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.',
@@ -2727,6 +2877,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'manual_process-single_invoice_amount',
+    'section'     => 'billing',
+    'description' => 'When entering manual credit card and ACH payments, amount will not autofill if the customer has more than one open invoice',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'manual_process-pkgpart',
     'section'     => 'billing',
     'description' => 'Package to add to each manual credit card and ACH payment entered by employees from the backend.  Enabling this option may be in violation of your merchant agreement(s), so please check it(/them) carefully before enabling this option.',
@@ -2753,6 +2910,22 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'selfservice_immutable-package',
+    'section'     => 'self-service',
+    'description' => 'Disable package changes in self-service interface.',
+    'type'        => 'checkbox',
+    'per_agent'   => 1,
+  },
+
+  {
+    'key'         => 'selfservice_hide-usage',
+    'section'     => 'self-service',
+    'description' => 'Hide usage data in self-service interface.',
+    'type'        => 'checkbox',
+    'per_agent'   => 1,
+  },
+
+  {
     'key'         => 'selfservice_process-pkgpart',
     'section'     => 'billing',
     'description' => 'Package to add to each manual credit card and ACH payment entered by the customer themselves in the self-service interface.  Enabling this option may be in violation of your merchant agreement(s), so please check it(/them) carefully before enabling this option.',
@@ -2960,7 +3133,7 @@ and customer address. Include units.',
                         },
     'option_sub'  => sub { require FS::Record;
                            require FS::agent_type;
-                          my $agent = FS::Record::qsearchs(
+                          my $agent_type = FS::Record::qsearchs(
                             'agent_type', { 'typenum'=>shift }
                           );
                            $agent_type ? $agent_type->atype : '';
@@ -3120,12 +3293,14 @@ and customer address. Include units.',
                            }
                          },
   },
+
   {
     'key'         => 'ticket_system-force_default_queueid',
     'section'     => 'ticketing',
     'description' => 'Disallow queue selection when creating new tickets from customer view.',
     'type'        => 'checkbox',
   },
+
   {
     'key'         => 'ticket_system-selfservice_queueid',
     'section'     => 'ticketing',
@@ -3204,6 +3379,41 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'ticket_system-appointment-queueid',
+    'section'     => 'ticketing',
+    'description' => 'Ticketing queue to use for appointments.',
+    #false laziness w/above
+    'type'        => 'select-sub',
+    'options_sub' => sub {
+                           my $conf = new FS::Conf;
+                           if ( $conf->config('ticket_system') ) {
+                             eval "use FS::TicketSystem;";
+                             die $@ if $@;
+                             FS::TicketSystem->queues();
+                           } else {
+                             ();
+                           }
+                         },
+    'option_sub'  => sub { 
+                           my $conf = new FS::Conf;
+                           if ( $conf->config('ticket_system') ) {
+                             eval "use FS::TicketSystem;";
+                             die $@ if $@;
+                             FS::TicketSystem->queue(shift);
+                           } else {
+                             '';
+                           }
+                         },
+  },
+
+  {
+    'key'         => 'ticket_system-appointment-custom_field',
+    'section'     => 'ticketing',
+    'description' => 'Ticketing custom field to use as an appointment classification.',
+    'type'        => 'text',
+  },
+
+  {
     'key'         => 'ticket_system-escalation',
     'section'     => 'ticketing',
     'description' => 'Enable priority escalation of tickets as part of daily batch processing.',
@@ -3295,7 +3505,7 @@ and customer address. Include units.',
   {
     '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',
+    'description' => 'Second address field is required.  Also enables "Unit" labeling of address2 on customer view and edit pages.  Useful for multi-tenant applications.  See also: address2-search', # service address only part not working in the modern world, see #41184  (on service address only, if billing and service addresses differ)
     'type'        => 'checkbox',
   },
 
@@ -3468,7 +3678,8 @@ and customer address. Include units.',
     'description' => 'Optional "site ID" to show in the location label',
     'type'        => 'select',
     'select_hash' => [ '' => '',
-                       'CoStAg' => 'CoStAgXXXXX (country, state, agent name, locationnum)',
+                       'CoStAg'    => 'CoStAgXXXXX (country, state, agent name, locationnum)',
+                       '_location' => 'Manually defined per location',
                       ],
   },
 
@@ -3584,18 +3795,29 @@ and customer address. Include units.',
   {
     'key'         => 'voip-cdr_email',
     'section'     => 'telephony',
-    'description' => 'Include the call details on emailed invoices (and HTML invoices viewed in the backend), even if the customer is configured for not printing them on the invoices.',
+    'description' => 'Include the call details inline on emailed invoices (and HTML invoices viewed in the backend), even if the customer is configured for not printing them on the invoices.  Useful for including these details in electronic delivery but omitting them when printing.',
     'type'        => 'checkbox',
   },
 
   {
     'key'         => 'voip-cust_email_csv_cdr',
-    'section'     => 'telephony',
-    'description' => 'Enable the per-customer option for including CDR information as a CSV attachment on emailed invoices.',
+    'section'     => 'deprecated',
+    'description' => 'Deprecated, see voip-cdr_email_attach instead.  Used to enable the per-customer option for including CDR information as a CSV attachment on emailed invoices.',
     'type'        => 'checkbox',
   },
 
   {
+    'key'         => 'voip-cdr_email_attach',
+    'section'     => 'telephony',
+    'description' => 'Enable the per-customer option for including CDR information as an attachment on emailed invoices.',
+    'type'        => 'select',
+    'select_hash' => [ ''    => 'Disabled',
+                       'csv' => 'Text (CSV) attachment',
+                       'zip' => 'Zip attachment',
+                     ],
+  },
+
+  {
     'key'         => 'cgp_rule-domain_templates',
     'section'     => '',
     'description' => 'Communigate Pro rule templates for domains, one per line, "svcnum Name"',
@@ -3704,7 +3926,7 @@ and customer address. Include units.',
     'type'        => 'select',
     'select_enum' => [ 'NACHA', 'csv-td_canada_trust-merchant_pc_batch',
                        'csv-chase_canada-E-xactBatch', 'BoM', 'PAP',
-                       'paymentech', 'ach-spiritone', 'RBC'
+                       'paymentech', 'ach-spiritone', 'RBC', 'CIBC',
                     ]
   },
 
@@ -3766,7 +3988,7 @@ and customer address. Include units.',
     'type'        => 'select',
     'select_enum' => [ 'NACHA', 'csv-td_canada_trust-merchant_pc_batch', 'BoM',
                        'PAP', 'paymentech', 'ach-spiritone', 'RBC',
-                       'td_eft1464', 'eft_canada'
+                       'td_eft1464', 'eft_canada', 'CIBC'
                      ]
   },
 
@@ -3784,6 +4006,13 @@ and customer address. Include units.',
     'type'        => 'textarea',
   },
 
+{
+    'key'         => 'batchconfig-CIBC',
+    'section'     => 'billing',
+    'description' => 'Configuration for Canadian Imperial Bank of Commerce, six lines: 1. Origin ID, 2. Datacenter, 3. Typecode, 4. Short name, 5. Bank, 6. Bank account',
+    'type'        => 'textarea',
+  },
+
   {
     'key'         => 'batchconfig-PAP',
     'section'     => 'billing',
@@ -3808,7 +4037,14 @@ and customer address. Include units.',
   {
     'key'         => 'batchconfig-RBC',
     'section'     => 'billing',
-    'description' => 'Configuration for Royal Bank of Canada PDS batching, four lines: 1. Client number, 2. Short name, 3. Long name, 4. Transaction code.',
+    'description' => 'Configuration for Royal Bank of Canada PDS batching, five lines: 1. Client number, 2. Short name, 3. Long name, 4. Transaction code 5. (optional) set to TEST to turn on test mode.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'batchconfig-RBC-login',
+    'section'     => 'billing',
+    'description' => 'FTPS login for uploading Royal Bank of Canada batches. Two lines: 1. username, 2. password. If not supplied, batches can still be created but not automatically uploaded.',
     'type'        => 'textarea',
   },
 
@@ -3822,7 +4058,7 @@ and customer address. Include units.',
   {
     'key'         => 'batchconfig-eft_canada',
     'section'     => 'billing',
-    'description' => 'Configuration for EFT Canada batching, four lines: 1. SFTP username, 2. SFTP password, 3. Transaction code, 4. Number of days to delay process date.  If you are using separate per-agent batches (batch-spoolagent), you must set this option separately for each agent, as the global setting will be ignored.',
+    'description' => 'Configuration for EFT Canada batching, five lines: 1. SFTP username, 2. SFTP password, 3. Business transaction code, 4. Personal transaction code, 5. Number of days to delay process date.  If you are using separate per-agent batches (batch-spoolagent), you must set this option separately for each agent, as the global setting will be ignored.',
     'type'        => 'textarea',
     'per_agent'   => 1,
   },
@@ -3849,6 +4085,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'batchconfig-nacha-origin_name',
+    'section'     => 'billing',
+    'description' => 'Configuration for NACHA batching, Origin name (defaults to company name, but sometimes bank name is needed instead.)',
+    'type'        => 'text',
+  },
+
+  {
     'key'         => 'batch-manual_approval',
     'section'     => 'billing',
     'description' => 'Allow manual batch closure, which will approve all payments that do not yet have a status.  This is not advised unless needed for specific payment processors that provide a report of rejected rather than approved payments.',
@@ -3957,7 +4200,14 @@ and customer address. Include units.',
   {
     'key'         => 'support-key',
     'section'     => '',
-    'description' => 'A support key enables access to commercial services delivered over the network, such as the payroll module, access to the internal ticket system, priority support and optional backups.',
+    'description' => 'A support key enables access to commercial services delivered over the network, such as address normalization and invoice printing.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'freesideinc-webservice-svcpart',
+    'section'     => '',
+    'description' => 'Do not set this.',
     'type'        => 'text',
   },
 
@@ -4067,10 +4317,25 @@ and customer address. Include units.',
   },
 
   {
-    'key'         => 'password-generated-allcaps',
+    'key'         => 'password-generated-characters',
+    'section'     => 'password',
+    'description' => 'Set of characters to use when generating random passwords. This must contain at least one lowercase letter, uppercase letter, digit, and punctuation mark.',
+    'type'        => 'textarea',
+  },
+
+  {
+    'key'         => 'password-no_reuse',
+    'section'     => 'password',
+    'description' => 'Minimum number of password changes before a password can be reused. By default, passwords can be reused without restriction.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'password-insecure',
     'section'     => 'password',
-    'description' => 'Causes passwords automatically generated to consist entirely of capital letters',
+    'description' => 'Disable all password security checks and allow entry of insecure passwords.  NOT RECOMMENDED.',
     'type'        => 'checkbox',
+    'per_agent'   => 1,
   },
 
   {
@@ -4197,9 +4462,10 @@ and customer address. Include units.',
     reason_type_options('R'),
   },
 
+  # was only used to negate invoices during signup when card was declined, now we just void
   {
     'key'         => 'signup_credit_type',
-    'section'     => 'billing', #self-service?
+    'section'     => 'deprecated', #self-service?
     'description' => 'The group to use for new, automatically generated credit reasons resulting from signup and self-service declines.',
     reason_type_options('R'),
   },
@@ -4243,7 +4509,7 @@ and customer address. Include units.',
   {
     'key'         => 'disable_previous_balance',
     'section'     => 'invoicing',
-    'description' => 'Disable inclusion of previous balance, payment, and credit lines on invoices.',
+    'description' => 'Show new charges only; do not list previous invoices, payments, or credits on the invoice.',
     'type'        => 'checkbox',
     'per_agent'   => 1,
   },
@@ -4251,8 +4517,22 @@ and customer address. Include units.',
   {
     'key'         => 'previous_balance-exclude_from_total',
     'section'     => 'invoicing',
-    'description' => 'Do not include previous balance in the \'Total\' line.  Only meaningful when invoice_sections is false.  Optionally provide text to override the Total New Charges description',
-    'type'        => [ qw(checkbox text) ],
+    'description' => 'Show separate totals for previous invoice balance and new charges. Only meaningful when invoice_sections is false.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'previous_balance-text',
+    'section'     => 'invoicing',
+    'description' => 'Text for the label of the total previous balance, when it is shown separately. Defaults to "Previous Balance".',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'previous_balance-text-total_new_charges',
+    'section'     => 'invoicing',
+    'description' => 'Text for the label of the total of new charges, when it is shown separately. If invoice_show_prior_due_date is enabled, the due date of current charges will be appended. Defaults to "Total New Charges".',
+    'type'        => 'text',
   },
 
   {
@@ -4321,9 +4601,11 @@ and customer address. Include units.',
     'type'        => 'select',
     'select_hash' => [ '' => '', 
                        'usps'     => 'U.S. Postal Service',
+                       'uscensus' => 'U.S. Census Bureau',
                        'ezlocate' => 'EZLocate',
                        'tomtom'   => 'TomTom',
                        'melissa'  => 'Melissa WebSmart',
+                       'freeside' => 'Freeside web service (support contract required)',
                      ],
   },
 
@@ -4391,6 +4673,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'cust_main-no_city_in_address',
+    'section'     => 'UI',
+    'description' => 'Turn off City for billing & shipping addresses',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'census_year',
     'section'     => 'UI',
     'description' => 'The year to use in census tract lookups.  NOTE: you need to select 2012 or 2013 for Year 2010 Census tract codes.  A selection of 2011 provides Year 2000 Census tract codes.  Use the freeside-censustract-update tool if exisitng customers need to be changed.',
@@ -4464,7 +4753,7 @@ and customer address. Include units.',
   {
     'key'         => 'cust_main-default_agent_custid',
     'section'     => 'UI',
-    'description' => 'Display the agent_custid field when available instead of the custnum field.',
+    'description' => 'Display the agent_custid field when available instead of the custnum field.  Restart Apache after changing.',
     'type'        => 'checkbox',
   },
 
@@ -4501,19 +4790,9 @@ and customer address. Include units.',
   },
 
   {
-    'key'         => 'cust_main-custnum-display_special',
-    'section'     => 'UI',
-    'description' => 'Use this customer number prefix format',
-    'type'        => 'select',
-    'select_hash' => [ '' => '',
-                       'CoStAg' => 'CoStAg (country, state, agent name or display_prefix)',
-                       'CoStCl' => 'CoStCl (country, state, class name)' ],
-  },
-
-  {
     'key'         => 'cust_main-custnum-display_length',
     'section'     => 'UI',
-    'description' => 'Zero fill the customer number to this many digits for display purposes.',
+    'description' => 'Zero fill the customer number to this many digits for display purposes.  Restart Apache after changing.',
     'type'        => 'text',
   },
 
@@ -4539,6 +4818,16 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'part_pkg-delay_cancel-days',
+    'section'     => '',
+    'description' => 'Number of days to suspend when using automatic suspension period before cancel (default is 1)',
+    'type'        => 'text',
+    'validate'    => sub { (($_[0] =~ /^\d*$/) && (($_[0] eq '') || $_[0]))
+                           ? ''
+                           : 'Must specify an integer number of days' }
+  },
+
+  {
     'key'         => 'mcp_svcpart',
     'section'     => '',
     'description' => 'Master Control Program svcpart.  Leave this blank.',
@@ -4932,9 +5221,16 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'svc_phone-bulk_provision_simple',
+    'section'     => 'telephony',
+    'description' => 'Bulk provision phone numbers with a simple number range instead of from DID vendor orders',
+    'type'        => 'checkbox',
+  },
+
+  {
     'key'         => 'default_phone_countrycode',
-    'section'     => '',
-    'description' => 'Default countrcode',
+    'section'     => 'telephony',
+    'description' => 'Default countrycode',
     'type'        => 'text',
   },
 
@@ -5144,15 +5440,33 @@ and customer address. Include units.',
 
   {
     'key'         => 'tax-cust_exempt-groups',
-    'section'     => '',
+    'section'     => 'billing',
     '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'         => 'tax-cust_exempt-groups-require_individual_nums',
-    'section'     => '',
-    'description' => 'When using tax-cust_exempt-groups, require an individual tax exemption number for each exemption from different taxes.',
+    'section'     => 'deprecated',
+    'description' => 'Deprecated: see tax-cust_exempt-groups-number_requirement',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'tax-cust_exempt-groups-num_req',
+    'section'     => 'billing',
+    'description' => 'When using tax-cust_exempt-groups, control whether individual tax exemption numbers are required for exemption from different taxes.',
+    'type'        => 'select',
+    'select_hash' => [ ''            => 'Not required',
+                       'residential' => 'Required for residential customers only',
+                       'all'         => 'Required for all customers',
+                     ],
+  },
+
+  {
+    'key'         => 'tax-round_per_line_item',
+    'section'     => 'billing',
+    'description' => 'Calculate tax and round to the nearest cent for each line item, rather than for the whole invoice.',
     'type'        => 'checkbox',
   },
 
@@ -5277,7 +5591,7 @@ and customer address. Include units.',
       my @part_export =
         map { qsearch( 'part_export', {exporttype => $_ } ) }
           keys %{FS::part_export::export_info('cust_main')};
-      map { $_->exportnum => $_->exporttype.' to '.$_->machine } @part_export;
+      map { $_->exportnum => $_->exportname } @part_export;
     },
     'option_sub'  => sub {
       require FS::Record;
@@ -5286,7 +5600,7 @@ and customer address. Include units.',
         'part_export', { 'exportnum' => shift }
       );
       $part_export
-        ? $part_export->exporttype.' to '.$part_export->machine
+        ? $part_export->exportname
         : '';
     },
   },
@@ -5295,7 +5609,7 @@ and customer address. Include units.',
   {
     'key'         => 'cust_location-exports',
     'section'     => '',
-    'description' => 'Export(s) to call on cust_location insert, modification and deletion.',
+    'description' => 'Export(s) to call on cust_location insert or modification',
     'type'        => 'select-sub',
     'multiple'    => 1,
     'options_sub' => sub {
@@ -5304,7 +5618,7 @@ and customer address. Include units.',
       my @part_export =
         map { qsearch( 'part_export', {exporttype => $_ } ) }
           keys %{FS::part_export::export_info('cust_location')};
-      map { $_->exportnum => $_->exporttype.' to '.$_->machine } @part_export;
+      map { $_->exportnum => $_->exportname } @part_export;
     },
     'option_sub'  => sub {
       require FS::Record;
@@ -5313,7 +5627,7 @@ and customer address. Include units.',
         'part_export', { 'exportnum' => shift }
       );
       $part_export
-        ? $part_export->exporttype.' to '.$part_export->machine
+        ? $part_export->exportname
         : '';
     },
   },
@@ -5473,7 +5787,7 @@ and customer address. Include units.',
   {
     'key'         => 'cust_main-status_module',
     'section'     => 'UI',
-    'description' => 'Which module to use for customer status display.  The "Classic" module (the default) considers accounts with cancelled recurring packages but un-cancelled one-time charges Inactive.  The "Recurring" module considers those customers Cancelled.  Similarly for customers with suspended recurring packages but one-time charges.', #other differences?
+    'description' => 'Which module to use for customer status display.  The "Classic" module (the default) considers accounts with cancelled recurring packages but un-cancelled one-time charges Inactive.  The "Recurring" module considers those customers Cancelled.  Similarly for customers with suspended recurring packages but one-time charges.  Restart Apache after changing.', #other differences?
     'type'        => 'select',
     'select_enum' => [ 'Classic', 'Recurring' ],
   },
@@ -5550,7 +5864,6 @@ and customer address. Include units.',
     'multiple'    => 1,
     'options_sub' => sub { 
       map { $_ => FS::Locales->description($_) }
-      grep { $_ ne 'en_US' } 
       FS::Locales->locales;
     },
     'option_sub'  => sub { FS::Locales->description(shift) },
@@ -5566,7 +5879,7 @@ and customer address. Include units.',
   {
     'key'         => 'translate-auto-insert',
     'section'     => '',
-    'description' => 'Auto-insert untranslated strings for selected non-en_US locales with their default/en_US values.  Do not turn this on unless translating the interface into a new language.',
+    'description' => 'Auto-insert untranslated strings for selected non-en_US locales with their default/en_US values.  Do not turn this on unless translating the interface into a new language.  Restart Apache after changing.',
     'type'        => 'select',
     'multiple'    => 1,
     'select_enum' => [ grep { $_ ne 'en_US' } FS::Locales::locales ],
@@ -5665,6 +5978,20 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'selfservice-enable_payment_without_balance',
+    'section'     => 'self-service',
+    'description' => 'Allow selfservice customers to make payments even if balance is zero or below (resulting in an unapplied payment and negative balance.)',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'selfservice-announcement',
+    'section'     => 'self-service',
+    'description' => 'HTML announcement to display to all authenticated users on account overview page',
+    'type'        => 'textarea',
+  },
+
+  {
     'key'         => 'logout-timeout',
     'section'     => 'UI',
     'description' => 'If set, automatically log users out of the backoffice after this many minutes.',
@@ -5788,6 +6115,20 @@ and customer address. Include units.',
     'type'        => 'checkbox',
   },
 
+  {
+    'key'         => 'cust_main-default_commercial',
+    'section'     => 'UI',
+    'description' => 'Default for new customers is commercial rather than residential.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'default_appointment_length',
+    'section'     => 'UI',
+    'description' => 'Default appointment length, in minutes (30 minute granularity).',
+    'type'        => 'text',
+  },
+
   { 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" },
@@ -5830,6 +6171,15 @@ and customer address. Include units.',
   { key => "vonage-password", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
   { key => "vonage-fromnumber", section => "deprecated", description => "<b>DEPRECATED</b>", type => "text" },
 
+  # for internal use only; test databases should declare this option and
+  # everyone else should pretend it doesn't exist
+  #{
+  #  'key'         => 'no_random_ids',
+  #  'section'     => '',
+  #  'description' => 'Replace random identifiers in UI code with a static string, for repeatable testing. Don\'t use in production.',
+  #  'type'        => 'checkbox',
+  #},
+
 );
 
 1;