default appointment length, RT#33556
[freeside.git] / FS / FS / Conf.pm
index ac366d9..6a4d19b 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
@@ -717,6 +733,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',
@@ -1233,9 +1266,24 @@ 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'    => sub { $_[0] =~
+                             /^[^@]+\@[[:alnum:]-]+(\.[[:alnum:]-]+)+$/
+                             ? '' : 'Invalid email address';
+                         }
+  },
+
+  {
+    '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.'
+                           : '' }
   },
 
   {
@@ -1532,6 +1580,13 @@ and customer address. Include units.',
   },
 
   {
+    '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 HTML invoice as the body of emailed PDF invoices.',
@@ -1684,9 +1739,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,
   },
   
@@ -2760,6 +2822,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.',
@@ -3009,7 +3078,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 : '';
@@ -3865,7 +3934,7 @@ 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',
   },
 
@@ -4308,8 +4377,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',
   },
 
   {
@@ -4378,6 +4461,7 @@ 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',
@@ -4596,6 +4680,16 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'part_pkg-delay_cancel-days',
+    'section'     => '',
+    'description' => 'Expire packages in this many days when using delay_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.',
@@ -5870,6 +5964,13 @@ and customer address. Include units.',
     '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" },