X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FConf.pm;h=58c966f8428842410a30460a6106d6d102d09c57;hb=4d00ce5afd7047c000a917f0fbd25ef7a7934f97;hp=f9aa0e66f1e8fc020236a7148d769b50f7fe9bb8;hpb=f39624dd22a91495798f253aa5f122e05a77bc41;p=freeside.git diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index f9aa0e66f..58c966f84 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -11,12 +11,11 @@ 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%%%'; @@ -113,14 +112,6 @@ 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 }; @@ -155,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; @@ -179,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) : ''; @@ -194,7 +183,6 @@ is undefined. sub exists { my $self = shift; - return $self->_usecompat('exists', @_) if use_confcompat; #my($name, $agentnum)=@_; @@ -209,7 +197,6 @@ sub exists { sub config_bool { my $self = shift; - return $self->_usecompat('exists', @_) if use_confcompat; my($name,$agentnum,$agentonly) = @_; @@ -264,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") ) { @@ -284,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") ) { @@ -327,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) ) { @@ -348,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; @@ -393,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); @@ -407,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}}) ) { @@ -434,7 +415,6 @@ sub delete { sub delete_bool { my $self = shift; - return $self->_usecompat('delete', @_) if use_confcompat; my($name, $agentnum) = @_; @@ -465,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"); @@ -474,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) 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 @@ -606,7 +527,6 @@ FS::ConfItem objects. See L. sub config_items { my $self = shift; - return $self->_usecompat('config_items', @_) if use_confcompat; ( @config_items, $self->_orbase_items(@_) ); } @@ -642,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 } @@ -697,10 +605,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 ); @@ -1396,6 +1306,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 billing documentation for details.', @@ -1583,6 +1502,15 @@ 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 HTML invoice as the email body, unless invoice_email_pdf_note is set.', @@ -2387,6 +2315,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', ], }, @@ -2543,55 +2472,91 @@ and customer address. Include units.', { 'key' => 'enable_taxclasses', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Enable per-package tax classes', 'type' => 'checkbox', }, { 'key' => 'require_taxclasses', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Require a taxclass to be entered for every package', 'type' => 'checkbox', }, { - 'key' => 'enable_taxproducts', - 'section' => 'billing', + 'key' => 'tax_data_vendor', + 'section' => 'taxation', 'description' => 'Tax data vendor you are using.', 'type' => 'select', - 'select_enum' => [ 'cch', 'billsoft', 'avalara' ], + 'select_enum' => [ '', 'cch', 'billsoft', 'avalara', 'suretax' ], }, { 'key' => 'taxdatadirectdownload', - 'section' => 'billing', #well - 'description' => 'Enable downloading tax data directly from the vendor site. at least three lines: URL, username, and password.j', + 'section' => 'taxation', + 'description' => 'Enable downloading tax data directly from CCH. at least three lines: URL, username, and password.j', 'type' => 'textarea', }, { 'key' => 'ignore_incalculable_taxes', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Prefer to invoice without tax over not billing at all', 'type' => 'checkbox', }, { 'key' => 'billsoft-company_code', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Billsoft tax service company code (3 letters)', 'type' => 'text', }, { 'key' => 'avalara-taxconfig', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Avalara tax service configuration. Four lines: company code, account number, license key, test mode (1 to enable).', 'type' => 'textarea', }, { + 'key' => 'suretax-hostname', + 'section' => 'taxation', + 'description' => 'SureTax server name; defaults to the test server.', + 'type' => 'text', + }, + + { + 'key' => 'suretax-client_number', + 'section' => 'taxation', + 'description' => 'SureTax tax service client ID.', + 'type' => 'text', + }, + { + 'key' => 'suretax-validation_key', + 'section' => 'taxation', + 'description' => 'SureTax validation key (UUID).', + 'type' => 'text', + }, + { + 'key' => 'suretax-business_unit', + 'section' => 'taxation', + 'description' => 'SureTax client business unit name; optional.', + 'type' => 'text', + 'per_agent' => 1, + }, + { + 'key' => 'suretax-regulatory_code', + 'section' => 'taxation', + 'description' => 'SureTax client regulatory status.', + 'type' => 'select', + 'select_enum' => [ '', 'ILEC', 'IXC', 'CLEC', 'VOIP', 'ISP', 'Wireless' ], + 'per_agent' => 1, + }, + + + { 'key' => 'welcome_msgnum', 'section' => 'notification', 'description' => 'Template to use for welcome messages when a svc_acct record is created.', @@ -2690,6 +2655,13 @@ and customer address. Include units.', }, { + 'key' => 'payment_history_msgnum', + 'section' => 'notification', + 'description' => 'Template to use for sending payment history to customer', + %msg_template_options, + }, + + { 'key' => 'payby', 'section' => 'billing', 'description' => 'Available payment types.', @@ -3770,14 +3742,14 @@ and customer address. Include units.', { 'key' => 'tax-ship_address', - 'section' => 'billing', + 'section' => 'taxation', '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', + 'section' => 'taxation', '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).', 'type' => 'checkbox', }, @@ -4559,7 +4531,7 @@ and customer address. Include units.', { 'key' => 'tax_district_method', - 'section' => 'UI', + 'section' => 'taxation', 'description' => 'The method to use to look up tax district codes.', 'type' => 'select', #'select_hash' => [ FS::Misc::Geo::get_district_methods() ], @@ -5320,7 +5292,7 @@ and customer address. Include units.', { 'key' => 'tax-cust_exempt-groups', - 'section' => 'billing', + 'section' => 'taxation', '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', }, @@ -5334,7 +5306,7 @@ and customer address. Include units.', { 'key' => 'tax-cust_exempt-groups-num_req', - 'section' => 'billing', + 'section' => 'taxation', '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', @@ -5362,7 +5334,7 @@ and customer address. Include units.', { 'key' => 'enable_tax_adjustments', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Enable the ability to add manual tax adjustments.', 'type' => 'checkbox', }, @@ -5815,7 +5787,7 @@ and customer address. Include units.', { 'key' => 'cust_class-tax_exempt', - 'section' => 'billing', + 'section' => 'taxation', 'description' => 'Control the tax exemption flag per customer class rather than per indivual customer.', 'type' => 'checkbox', }, @@ -6003,6 +5975,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 => "DEPRECATED", type => "text" }, { key => "apachemachine", section => "deprecated", description => "DEPRECATED", type => "text" }, { key => "apachemachines", section => "deprecated", description => "DEPRECATED", type => "text" },