From e71dc3bc03c667b0e02991a019aec599f3ca7377 Mon Sep 17 00:00:00 2001 From: jeff Date: Wed, 14 May 2008 18:07:23 +0000 Subject: [PATCH] correct tax selection and *actually* handle fee based taxes --- FS/FS/cust_bill_pkg.pm | 12 +++++++++++ FS/FS/part_pkg.pm | 52 ++++++++++++++++++++++++++++++++++++++++------ FS/FS/part_pkg/voip_cdr.pm | 7 +++++++ FS/FS/tax_rate.pm | 18 +++++++++++++++- 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index 86527a886..1cb982681 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -309,6 +309,18 @@ sub cust_credit_bill_pkg { ); } +=item units + +Returns the number of billing units (for tax purposes) represented by this, +line item. + +=cut + +sub units { + my $self = shift; + $self->part_pkg->calc_units($self->cust_pkg); +} + =back =head1 BUGS diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index c3e76d5bd..0d77ed92e 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -416,6 +416,11 @@ sub check { || $self->ut_enum('disabled', [ '', 'Y' ] ) || $self->ut_floatn('pay_weight') || $self->ut_floatn('credit_weight') + || $self->ut_numbern('taxproductnum') + || $self->ut_foreign_keyn('taxproductnum', + 'part_pkg_taxproduct', + 'taxproductnum' + ) || $self->ut_agentnum_acl('agentnum', 'Edit global package definitions') || $self->SUPER::check ; @@ -808,25 +813,57 @@ specified by GEOCODE (see L and ). =cut +sub _expand_cch_taxproductnum { + my $self = shift; + my $part_pkg_taxproduct = + qsearchs( 'part_pkg_taxproduct', + { 'taxproductnum' => $self->taxproductnum } + ); + my ($a,$b,$c,$d) = ( $part_pkg_taxproduct + ? ( split ':', $part_pkg_taxproduct->taxproduct ) + : () + ); + my $extra_sql = "AND ( taxproduct = '$a:$b:$c:$d' + OR taxproduct = '$a:$b:$c:' + OR taxproduct = '$a:$b:".":$d' + OR taxproduct = '$a:$b:".":' )"; + map { $_->taxproductnum } qsearch( { 'table' => 'part_pkg_taxproduct', + 'hashref' => { 'data_vendor'=>'cch' }, + 'extra_sql' => $extra_sql, + } ); + +} + sub part_pkg_taxrate { my $self = shift; my ($data_vendor, $geocode) = @_; my $dbh = dbh; + my $extra_sql = 'WHERE part_pkg_taxproduct.data_vendor = '. + dbh->quote($data_vendor); + # CCH oddness in m2m - my $extra_sql = 'AND ('. + $extra_sql .= ' AND ('. join(' OR ', map{ 'geocode = '. $dbh->quote(substr($geocode, 0, $_)) } qw(10 5 2) ). ')'; - my $order_by = 'ORDER BY taxclassnum, length(geocode) desc'; - my $select = 'DISTINCT ON(taxclassnum) *'; + # much more CCH oddness in m2m -- this is kludgy + $extra_sql .= ' AND ('. + join(' OR ', map{ "taxproductnum = $_" } $self->_expand_cch_taxproductnum). + ')'; + my $addl_from = 'LEFT JOIN part_pkg_taxproduct USING ( taxproductnum )'; + my $order_by = 'ORDER BY taxclassnum, length(geocode) desc, length(taxproduct) desc'; + my $select = 'DISTINCT ON(taxclassnum) *, taxproduct'; + + # should qsearch preface columns with the table to facilitate joins? qsearch( { 'table' => 'part_pkg_taxrate', - 'select' => 'distinct on(taxclassnum) *', - 'hashref' => { 'data_vendor' => $data_vendor, - 'taxproductnum' => $self->taxproductnum, + 'select' => $select, + 'hashref' => { # 'data_vendor' => $data_vendor, + # 'taxproductnum' => $self->taxproductnum, }, + 'addl_from' => $addl_from, 'extra_sql' => $extra_sql, 'order_by' => $order_by, } ); @@ -891,6 +928,7 @@ sub _calc_eval { sub calc_remain { 0; } sub calc_cancel { 0; } +sub calc_units { 0; } =back @@ -1059,6 +1097,8 @@ FS::cust_bill. hmm.). now they're deprecated and need to go. plandata should go +part_pkg_taxrate is Pg specific + =head1 SEE ALSO L, L, L, L, L. diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index f7db685a0..c4827c9c5 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -424,5 +424,12 @@ sub base_recur { $self->option('recur_fee'); } +# This equates svc_phone records; perhaps svc_phone should have a field +# to indicate it represents a line +sub calc_units { + my($self, $cust_pkg ) = @_; + scalar(grep { $_->part_svc->svcdb eq 'svc_phone' } $cust_pkg->cust_svc); +} + 1; diff --git a/FS/FS/tax_rate.pm b/FS/FS/tax_rate.pm index 268edcae0..18f2e110e 100644 --- a/FS/FS/tax_rate.pm +++ b/FS/FS/tax_rate.pm @@ -349,6 +349,10 @@ sub taxline { my $self = shift; my @cust_bill_pkg = @_; + warn "calculating taxes for ". $self->taxnum. " on ". + join (",", map { $_->pkgnum } @cust_bill_pkg) + if $DEBUG; + if ($self->passflag eq 'N') { return "fatal: can't (yet) handle taxes not passed to the customer"; } @@ -386,7 +390,16 @@ sub taxline { my $taxable_units = 0; unless ($self->recurtax =~ /^Y$/i) { - $taxable_units += $_->units foreach @cust_bill_pkg; + if ($self->unittype == 0) { + $taxable_units += $_->units foreach @cust_bill_pkg; + }elsif ($self->unittype == 1) { + return qq!fatal: can't (yet) handle fee with minute unit type!; + }elsif ($self->unittype == 2) { + $taxable_units = 1; + }else { + return qq!fatal: can't (yet) handle unknown unit type in tax!. + $self->taxnum; + } } # @@ -399,6 +412,9 @@ sub taxline { $amount += $taxable_charged * $self->tax; $amount += $taxable_units * $self->fee; + warn "calculated taxes as [ $name, $amount ]\n" + if $DEBUG; + return [$name, $amount]; } -- 2.11.0