RT#34289: Flag service fields as mandatory [fieldname bug fix]
[freeside.git] / FS / FS / Conf.pm
index 855c9f4..f80f2d5 100644 (file)
@@ -1,7 +1,9 @@
 package FS::Conf;
 
 use strict;
-use vars qw($base_dir @config_items @base_items @card_types $DEBUG $conf_cache);
+use vars qw( $base_dir @config_items @base_items @card_types $DEBUG
+             $conf_cache $conf_cache_enabled
+           );
 use Carp;
 use IO::File;
 use File::Basename;
@@ -9,18 +11,19 @@ use MIME::Base64;
 use Locale::Currency;
 use FS::ConfItem;
 use FS::ConfDefaults;
-use FS::Conf_compat17;
 use FS::Locales;
 use FS::payby;
 use FS::conf;
 use FS::Record qw(qsearch qsearchs);
-use FS::UID qw(dbh datasrc use_confcompat);
+use FS::UID qw(dbh datasrc);
 use FS::Misc::Invoicing qw( spool_formats );
 
 $base_dir = '%%%FREESIDE_CONF%%%';
 
 $DEBUG = 0;
 
+$conf_cache_enabled = 0;
+
 =head1 NAME
 
 FS::Conf - Freeside configuration values
@@ -109,18 +112,12 @@ specific value(s) is returned.
 
 =cut
 
-sub _usecompat {
-  my ($self, $method) = (shift, shift);
-  carp "NO CONFIGURATION RECORDS FOUND -- USING COMPATIBILITY MODE"
-    if use_confcompat;
-  my $compat = new FS::Conf_compat17 ("$base_dir/conf." . datasrc);
-  $compat->$method(@_);
-}
-
 sub _config {
   my($self,$name,$agentnum,$agentonly)=@_;
   my $hashref = { 'name' => $name };
   local $FS::Record::conf = undef;  # XXX evil hack prevents recursion
+  $conf_cache = undef unless $conf_cache_enabled; # use cache only when it is
+                                                  # safe to do so
   my $cv;
   my @a = (
     ($agentnum || ()),
@@ -137,7 +134,8 @@ sub _config {
       my $key = join(':',$name, $a, $l);
       if (! exists $conf_cache->{$key}){
         $hashref->{locale} = $l;
-        # $conf_cache is reset in FS::UID during myconnect, so the cache is reset per connection
+        # $conf_cache is reset in FS::UID during myconnect, so the cache is
+        # reset per connection
         $conf_cache->{$key} = FS::Record::qsearchs('conf', $hashref);
       }
       return $conf_cache->{$key} if $conf_cache->{$key};
@@ -148,7 +146,6 @@ sub _config {
 
 sub config {
   my $self = shift;
-  return $self->_usecompat('config', @_) if use_confcompat;
 
   carp "FS::Conf->config(". join(', ', @_). ") called"
     if $DEBUG > 1;
@@ -172,7 +169,6 @@ Returns the exact scalar value for key.
 
 sub config_binary {
   my $self = shift;
-  return $self->_usecompat('config_binary', @_) if use_confcompat;
 
   my $cv = $self->_config(@_) or return;
   length($cv->value) ? decode_base64($cv->value) : '';
@@ -187,7 +183,6 @@ is undefined.
 
 sub exists {
   my $self = shift;
-  return $self->_usecompat('exists', @_) if use_confcompat;
 
   #my($name, $agentnum)=@_;
 
@@ -202,7 +197,6 @@ sub exists {
 
 sub config_bool {
   my $self = shift;
-  return $self->_usecompat('exists', @_) if use_confcompat;
 
   my($name,$agentnum,$agentonly) = @_;
 
@@ -257,7 +251,6 @@ KEY_SUFFIX, if it exists, otherwise for KEY
 # these to fall back to standard values
 sub config_orbase {
   my $self = shift;
-  return $self->_usecompat('config_orbase', @_) if use_confcompat;
 
   my( $name, $suffix ) = @_;
   if ( $self->exists("${name}_$suffix") ) {
@@ -277,7 +270,6 @@ config_orbase.
 
 sub key_orbase {
   my $self = shift;
-  #no compat for this...return $self->_usecompat('config_orbase', @_) if use_confcompat;
 
   my( $name, $suffix ) = @_;
   if ( $self->exists("${name}_$suffix") ) {
@@ -320,7 +312,6 @@ Creates the specified configuration key if it does not exist.
 
 sub touch {
   my $self = shift;
-  return $self->_usecompat('touch', @_) if use_confcompat;
 
   my($name, $agentnum) = @_;
   #unless ( $self->exists($name, $agentnum) ) {
@@ -341,7 +332,6 @@ Sets the specified configuration key to the given value.
 
 sub set {
   my $self = shift;
-  return $self->_usecompat('set', @_) if use_confcompat;
 
   my($name, $value, $agentnum) = @_;
   $value =~ /^(.*)$/s;
@@ -386,7 +376,6 @@ can be retrieved with config_binary.
 
 sub set_binary {
   my $self  = shift;
-  return if use_confcompat;
 
   my($name, $value, $agentnum)=@_;
   $self->set($name, encode_base64($value), $agentnum);
@@ -400,7 +389,6 @@ Deletes the specified configuration key.
 
 sub delete {
   my $self = shift;
-  return $self->_usecompat('delete', @_) if use_confcompat;
 
   my($name, $agentnum) = @_;
   if ( my $cv = FS::Record::qsearchs('conf', {name => $name, agentnum => $agentnum, locale => $self->{locale}}) ) {
@@ -427,7 +415,6 @@ sub delete {
 
 sub delete_bool {
   my $self = shift;
-  return $self->_usecompat('delete', @_) if use_confcompat;
 
   my($name, $agentnum) = @_;
 
@@ -458,7 +445,7 @@ in the directory DIR.
 sub import_config_item { 
   my ($self,$item,$dir) = @_;
   my $key = $item->key;
-  if ( -e "$dir/$key" && ! use_confcompat ) {
+  if ( -e "$dir/$key" ) {
     warn "Inserting $key\n" if $DEBUG;
     local $/;
     my $value = readline(new IO::File "$dir/$key");
@@ -467,68 +454,9 @@ sub import_config_item {
     }else{
       $self->set($key, $value);
     }
-  }else {
-    warn "Not inserting $key\n" if $DEBUG;
-  }
-}
-
-=item verify_config_item CONFITEM DIR 
-
-  Compares the item specified by the CONFITEM (see L<FS::ConfItem>) in
-the database to the legacy file value in DIR.
-
-=cut
-
-sub verify_config_item { 
-  return '' if use_confcompat;
-  my ($self,$item,$dir) = @_;
-  my $key = $item->key;
-  my $type = $item->type;
-
-  my $compat = new FS::Conf_compat17 $dir;
-  my $error = '';
-  
-  $error .= "$key fails existential comparison; "
-    if $self->exists($key) xor $compat->exists($key);
-
-  if ( $type !~ /^(binary|image)$/ ) {
-
-    {
-      no warnings;
-      $error .= "$key fails scalar comparison; "
-        unless scalar($self->config($key)) eq scalar($compat->config($key));
-    }
-
-    my (@new) = $self->config($key);
-    my (@old) = $compat->config($key);
-    unless ( scalar(@new) == scalar(@old)) { 
-      $error .= "$key fails list comparison; ";
-    }else{
-      my $r=1;
-      foreach (@old) { $r=0 if ($_ cmp shift(@new)); }
-      $error .= "$key fails list comparison; "
-        unless $r;
-    }
-
   } else {
-
-    no warnings 'uninitialized';
-    $error .= "$key fails binary comparison; "
-      unless scalar($self->config_binary($key)) eq scalar($compat->config_binary($key));
-
+    warn "Not inserting $key\n" if $DEBUG;
   }
-
-#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;
 }
 
 #item _orbase_items OPTIONS
@@ -599,7 +527,6 @@ FS::ConfItem objects.  See L<FS::ConfItem>.
 
 sub config_items {
   my $self = shift; 
-  return $self->_usecompat('config_items', @_) if use_confcompat;
 
   ( @config_items, $self->_orbase_items(@_) );
 }
@@ -635,23 +562,11 @@ to conf records in the database.
 sub init_config {
   my $dir = shift;
 
-  {
-    local $FS::UID::use_confcompat = 0;
-    my $conf = new FS::Conf;
-    foreach my $item ( $conf->config_items(dir => $dir) ) {
-      $conf->import_config_item($item, $dir);
-      my $error = $conf->verify_config_item($item, $dir);
-      return $error if $error;
-    }
-  
-    my $compat = new FS::Conf_compat17 $dir;
-    foreach my $item ( $compat->config_items ) {
-      my $error = $conf->verify_config_item($item, $dir);
-      return $error if $error;
-    }
+  my $conf = new FS::Conf;
+  foreach my $item ( $conf->config_items(dir => $dir) ) {
+    $conf->import_config_item($item, $dir);
   }
 
-  $FS::UID::use_confcompat = 0;
   '';  #success
 }
 
@@ -2690,6 +2605,13 @@ and customer address. Include units.',
     'select_enum' => [ qw(CARD DCRD CHEK DCHK CASH WEST MCRD MCHK PPAL) ],
   },
 
+  {
+    'key'         => 'banned_pay-pad',
+    'section'     => 'billing',
+    'description' => 'Padding for encrypted storage of banned credit card hashes.  If you already have new-style SHA512 entries in the banned_pay table, do not change as this will invalidate the old entries.',
+    'type'        => 'text',
+  },
+
   {
     'key'         => 'payby-default',
     'section'     => 'deprecated',
@@ -2839,6 +2761,13 @@ and customer address. Include units.',
     'type'        => 'checkbox',
   },
 
+  {
+    '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',
@@ -3946,7 +3875,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',
   },
 
@@ -4389,8 +4318,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',
   },
 
   {
@@ -4426,6 +4369,7 @@ and customer address. Include units.',
     'section'     => 'invoicing',
     'description' => 'Instead of showing payments (and credits) applied to the invoice, show those received since the previous invoice date.',
     'type'        => 'checkbox',
+                       'uscensus' => 'U.S. Census Bureau',
   },
 
   {