X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Ftax_rate.pm;h=4516004321039a72e0620a5c371d0f2ce100b335;hp=a5a623d948a427e7017639e1947cdef1f41d38f9;hb=e9e0cf0989259b94d9758eceff448666a2e5a5cc;hpb=94c1d035193d1eabb1820e62bce96438f11f870a diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index a5a623d94..451600432 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -1,7 +1,8 @@ package FS::tax_rate; +use base qw( FS::Record ); use strict; -use vars qw( @ISA $DEBUG $me +use vars qw( $DEBUG $me %tax_unittypes %tax_maxtypes %tax_basetypes %tax_authorities %tax_passtypes %GetInfoType $keep_cch_files ); use Date::Parse; @@ -11,6 +12,7 @@ use Storable qw( thaw nfreeze ); use IO::File; use File::Temp; use Text::CSV_XS; +use URI::Escape; use LWP::UserAgent; use HTTP::Request; use HTTP::Response; @@ -29,10 +31,6 @@ use FS::part_pkg_taxproduct; use FS::cust_main; use FS::Misc qw( csv_from_fixed ); -use URI::Escape; - -@ISA = qw( FS::Record ); - $DEBUG = 0; $me = '[FS::tax_rate]'; $keep_cch_files = 0; @@ -215,7 +213,7 @@ sub check { $self->ut_numbern('taxnum') || $self->ut_text('geocode') || $self->ut_textn('data_vendor') - || $self->ut_textn('location') + || $self->ut_cch_textn('location') || $self->ut_foreign_key('taxclassnum', 'tax_class', 'taxclassnum') || $self->ut_snumbern('effective_date') || $self->ut_float('tax') @@ -245,6 +243,18 @@ sub check { } +#ut_text / ut_textn w/ ` added cause now that's in the data +sub ut_cch_textn { + my($self,$field)=@_; + $self->getfield($field) + =~ /^([\wô \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]\<\>\`]*)$/ + or return gettext('illegal_or_empty_text'). " $field: ". + $self->getfield($field); + $self->setfield($field,$1); + ''; + +} + =item taxclass_description Returns the human understandable value associated with the related @@ -361,7 +371,7 @@ sub passtype_name { $tax_passtypes{$self->passtype}; } -=item taxline TAXABLES, [ OPTIONSHASH ] +=item taxline TAXABLES Returns a listref of a name and an amount of tax calculated for the list of packages/amounts referenced by TAXABLES. If an error occurs, a message @@ -371,13 +381,13 @@ is returned as a scalar. sub taxline { my $self = shift; + # this used to accept a hash of options but none of them did anything + # so it's been removed. my $taxables; - my %opt = (); if (ref($_[0]) eq 'ARRAY') { $taxables = shift; - %opt = @_; }else{ $taxables = [ @_ ]; #exemptions would be broken in this case @@ -413,7 +423,7 @@ sub taxline { } my $maxtype = $self->maxtype || 0; - if ($maxtype != 0 && $maxtype != 9) { + if ($maxtype != 0 && $maxtype != 1 && $maxtype != 9) { return $self->_fatal_or_null( 'tax with "'. $self->maxtype_name. '" threshold' ); @@ -476,12 +486,12 @@ sub taxline { } - # - # XXX insert exemption handling here + # XXX handle excessrate (use_excessrate) / excessfee / + # taxbase/feebase / taxmax/feemax + # and eventually exemptions # # the tax or fee is applied to taxbase or feebase and then # the excessrate or excess fee is applied to taxmax or feemax - # $amount += $taxable_charged * $self->tax; $amount += $taxable_units * $self->fee; @@ -514,10 +524,10 @@ sub _fatal_or_null { } } -=item tax_on_tax CUST_MAIN +=item tax_on_tax CUST_LOCATION Returns a list of taxes which are candidates for taxing taxes for the -given customer (see L) +given service location (see L) =cut @@ -525,13 +535,13 @@ given customer (see L) sub tax_on_tax { #akshun my $self = shift; - my $cust_main = shift; + my $cust_location = shift; warn "looking up taxes on tax ". $self->taxnum. " for customer ". - $cust_main->custnum + $cust_location->custnum if $DEBUG; - my $geocode = $cust_main->geocode($self->data_vendor); + my $geocode = $cust_location->geocode($self->data_vendor); # CCH oddness in m2m my $dbh = dbh; @@ -785,7 +795,8 @@ sub batch_import { } - for (grep { !exists($delete{$_}) } keys %insert) { + my @replace = grep { exists($delete{$_}) } keys %insert; + for (@replace) { if ( $job ) { # progress bar if ( time - $min_sec > $last ) { my $error = $job->update_statustext( @@ -799,20 +810,35 @@ sub batch_import { } } - my $tax_rate = new FS::tax_rate( $insert{$_} ); - my $error = $tax_rate->insert; + my $old = qsearchs( 'tax_rate', $delete{$_} ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - my $hashref = $insert{$_}; - $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); - return "can't insert tax_rate for $line: $error"; + if ( $old ) { + + my $new = new FS::tax_rate({ $old->hash, %{$insert{$_}}, 'manual' => '' }); + $new->taxnum($old->taxnum); + my $error = $new->replace($old); + + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + my $hashref = $insert{$_}; + $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); + return "can't replace tax_rate for $line: $error"; + } + + $imported++; + + } else { + + $old = delete $delete{$_}; + warn "WARNING: can't find tax_rate to replace (inserting instead and continuing) for: ". + #join(" ", map { "$_ => ". $old->{$_} } @fields); + join(" ", map { "$_ => ". $old->{$_} } keys(%$old) ); } $imported++; } - for (grep { exists($delete{$_}) } keys %insert) { + for (grep { !exists($delete{$_}) } keys %insert) { if ( $job ) { # progress bar if ( time - $min_sec > $last ) { my $error = $job->update_statustext( @@ -826,27 +852,17 @@ sub batch_import { } } - my $old = qsearchs( 'tax_rate', $delete{$_} ); - unless ($old) { - $dbh->rollback if $oldAutoCommit; - $old = $delete{$_}; - return "can't find tax_rate to replace for: ". - #join(" ", map { "$_ => ". $old->{$_} } @fields); - join(" ", map { "$_ => ". $old->{$_} } keys(%$old) ); - } - my $new = new FS::tax_rate({ $old->hash, %{$insert{$_}}, 'manual' => '' }); - $new->taxnum($old->taxnum); - my $error = $new->replace($old); + my $tax_rate = new FS::tax_rate( $insert{$_} ); + my $error = $tax_rate->insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; my $hashref = $insert{$_}; $line = join(", ", map { "$_ => ". $hashref->{$_} } keys(%$hashref) ); - return "can't replace tax_rate for $line: $error"; + return "can't insert tax_rate for $line: $error"; } $imported++; - $imported++; } for (grep { !exists($insert{$_}) } keys %delete) { @@ -961,7 +977,7 @@ sub _perform_batch_import { my $file = lc($name). 'file'; unless ($files{$file}) { - $error = "No $name supplied"; + #$error = "No $name supplied"; next; } next if $name eq 'DETAIL' && $format =~ /update/; @@ -978,7 +994,7 @@ sub _perform_batch_import { unlink $filename or warn "Can't delete $filename: $!" unless $keep_cch_files; push @insert_list, $name, $insertname, $import_sub, $format; - if ( $name eq 'GEOCODE' ) { #handle this whole ordering issue better + if ( $name eq 'GEOCODE' || $name eq 'CODE' ) { #handle this whole ordering issue better unshift @predelete_list, $name, $deletename, $import_sub, $format; } else { unshift @delete_list, $name, $deletename, $import_sub, $format; @@ -996,10 +1012,17 @@ sub _perform_batch_import { 'DETAIL', "$dir/".$files{detailfile}, \&FS::tax_rate::batch_import, $format if $format =~ /update/; + my %addl_param = (); + if ( $param->{'delete_only'} ) { + $addl_param{'delete_only'} = $param->{'delete_only'}; + @insert_list = () + } + $error ||= _perform_cch_tax_import( $job, [ @predelete_list ], [ @insert_list ], [ @delete_list ], + \%addl_param, ); @@ -1024,7 +1047,8 @@ sub _perform_batch_import { sub _perform_cch_tax_import { - my ( $job, $predelete_list, $insert_list, $delete_list ) = @_; + my ( $job, $predelete_list, $insert_list, $delete_list, $addl_param ) = @_; + $addl_param ||= {}; my $error = ''; foreach my $list ($predelete_list, $insert_list, $delete_list) { @@ -1033,7 +1057,11 @@ sub _perform_cch_tax_import { my $fmt = "$format-update"; $fmt = $format. ( lc($name) eq 'zip' ? '-zip' : '' ); open my $fh, "< $file" or $error ||= "Can't open $name file $file: $!"; - $error ||= &{$method}({ 'filehandle' => $fh, 'format' => $fmt }, $job); + my $param = { 'filehandle' => $fh, + 'format' => $fmt, + %$addl_param, + }; + $error ||= &{$method}($param, $job); close $fh; } } @@ -2102,8 +2130,7 @@ EOF =head1 SEE ALSO -L, L, L, schema.html from the base -documentation. +L, L, L =cut