summaryrefslogtreecommitdiff
path: root/FS/FS
diff options
context:
space:
mode:
authorjeff <jeff>2008-05-14 18:07:23 +0000
committerjeff <jeff>2008-05-14 18:07:23 +0000
commite71dc3bc03c667b0e02991a019aec599f3ca7377 (patch)
tree41f6e3bd310453de5ca0d24daba4d9d5c67b4702 /FS/FS
parent0677db2866105b5a37e2a3b426999b84ab35f4b7 (diff)
correct tax selection and *actually* handle fee based taxes
Diffstat (limited to 'FS/FS')
-rw-r--r--FS/FS/cust_bill_pkg.pm12
-rw-r--r--FS/FS/part_pkg.pm52
-rw-r--r--FS/FS/part_pkg/voip_cdr.pm7
-rw-r--r--FS/FS/tax_rate.pm18
4 files changed, 82 insertions, 7 deletions
diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm
index 86527a8..1cb9826 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 c3e76d5..0d77ed9 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<FS::part_pkg_taxrate> 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<FS::Record>, L<FS::cust_pkg>, L<FS::type_pkgs>, L<FS::pkg_svc>, L<Safe>.
diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm
index f7db685..c4827c9 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 268edca..18f2e11 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];
}