Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / FS / cust_bill_pkg.pm
index a83af13..572fe79 100644 (file)
@@ -201,16 +201,50 @@ sub insert {
 
   my $tax_location = $self->get('cust_bill_pkg_tax_location');
   if ( $tax_location ) {
-    foreach my $cust_bill_pkg_tax_location ( @$tax_location ) {
-      $cust_bill_pkg_tax_location->billpkgnum($self->billpkgnum);
-      $error = $cust_bill_pkg_tax_location->insert;
-      if ( $error ) {
-        $dbh->rollback if $oldAutoCommit;
-        return "error inserting cust_bill_pkg_tax_location: $error";
+    foreach my $link ( @$tax_location ) {
+      next if $link->billpkgtaxlocationnum; # don't try to double-insert
+      # This cust_bill_pkg can be linked on either side (i.e. it can be the
+      # tax or the taxed item).  If the other side is already inserted, 
+      # then set billpkgnum to ours, and insert the link.  Otherwise,
+      # set billpkgnum to ours and pass the link off to the cust_bill_pkg
+      # on the other side, to be inserted later.
+
+      my $tax_cust_bill_pkg = $link->get('tax_cust_bill_pkg');
+      if ( $tax_cust_bill_pkg && $tax_cust_bill_pkg->billpkgnum ) {
+        $link->set('billpkgnum', $tax_cust_bill_pkg->billpkgnum);
+        # break circular links when doing this
+        $link->set('tax_cust_bill_pkg', '');
       }
-    }
+      my $taxable_cust_bill_pkg = $link->get('taxable_cust_bill_pkg');
+      if ( $taxable_cust_bill_pkg && $taxable_cust_bill_pkg->billpkgnum ) {
+        $link->set('taxable_billpkgnum', $taxable_cust_bill_pkg->billpkgnum);
+        # XXX if we ever do tax-on-tax for these, this will have to change
+        # since pkgnum will be zero
+        $link->set('pkgnum', $taxable_cust_bill_pkg->pkgnum);
+        $link->set('locationnum', 
+          $taxable_cust_bill_pkg->cust_pkg->tax_locationnum);
+        $link->set('taxable_cust_bill_pkg', '');
+      }
+
+      if ( $link->billpkgnum and $link->taxable_billpkgnum ) {
+        $error = $link->insert;
+        if ( $error ) {
+          $dbh->rollback if $oldAutoCommit;
+          return "error inserting cust_bill_pkg_tax_location: $error";
+        }
+      } else { # handoff
+        my $other;
+        $other = $link->billpkgnum ? $link->get('taxable_cust_bill_pkg')
+                                   : $link->get('tax_cust_bill_pkg');
+        my $link_array = $other->get('cust_bill_pkg_tax_location') || [];
+        push @$link_array, $link;
+        $other->set('cust_bill_pkg_tax_location' => $link_array);
+      }
+    } #foreach my $link
   }
 
+  # someday you will be as awesome as cust_bill_pkg_tax_location...
+  # but not today
   my $tax_rate_location = $self->get('cust_bill_pkg_tax_rate_location');
   if ( $tax_rate_location ) {
     foreach my $cust_bill_pkg_tax_rate_location ( @$tax_rate_location ) {
@@ -400,7 +434,13 @@ sub check {
       || $self->ut_snumber('pkgnum')
       || $self->ut_number('invnum')
       || $self->ut_money('setup')
+      || $self->ut_moneyn('unitsetup')
+      || $self->ut_currencyn('setup_billed_currency')
+      || $self->ut_moneyn('setup_billed_amount')
       || $self->ut_money('recur')
+      || $self->ut_moneyn('unitrecur')
+      || $self->ut_currencyn('recur_billed_currency')
+      || $self->ut_moneyn('recur_billed_amount')
       || $self->ut_numbern('sdate')
       || $self->ut_numbern('edate')
       || $self->ut_textn('itemdesc')
@@ -1070,16 +1110,12 @@ sub upgrade_tax_location {
     delete @hash{qw(censustract censusyear latitude longitude coord_auto)};
 
     $hash{custnum} = $h_cust_main->custnum;
-    my $tax_loc = qsearchs('cust_location', \%hash) # unlikely
-                  || FS::cust_location->new({ %hash });
-    if ( !$tax_loc->locationnum ) {
-      $tax_loc->disabled('Y');
-      my $error = $tax_loc->insert;
-      if ( $error ) {
-        warn "couldn't create historical location record for cust#".
-        $h_cust_main->custnum.": $error\n";
-        next INVOICE;
-      }
+    my $tax_loc = FS::cust_location->new(\%hash);
+    my $error = $tax_loc->find_or_insert || $tax_loc->disable_if_unused;
+    if ( $error ) {
+      warn "couldn't create historical location record for cust#".
+      $h_cust_main->custnum.": $error\n";
+      next INVOICE;
     }
     my $exempt_cust = 1 if $h_cust_main->tax;
 
@@ -1310,9 +1346,10 @@ sub upgrade_tax_location {
                        );
           $cents_remaining -= $part;
           push @tax_links, {
-            taxnum => $taxdef->taxnum,
-            pkgnum => $nontax->pkgnum,
-            cents  => $part,
+            taxnum      => $taxdef->taxnum,
+            pkgnum      => $nontax->pkgnum,
+            billpkgnum  => $nontax->billpkgnum,
+            cents       => $part,
           };
         } #foreach $nontax
       } #foreach $taxclass
@@ -1355,6 +1392,7 @@ sub upgrade_tax_location {
             taxnum      => $_->{taxnum},
             pkgnum      => $_->{pkgnum},
             amount      => sprintf('%.2f', $_->{cents} / 100),
+            taxable_billpkgnum => $_->{billpkgnum},
         });
         my $error = $link->insert;
         if ( $error ) {
@@ -1443,6 +1481,9 @@ sub _upgrade_data {
   # Then mark the upgrade as done, so that we don't queue the job twice
   # and somehow run two of them concurrently.
   FS::upgrade_journal->set_done($upgrade);
+  # This upgrade now does the job of assigning taxable_billpkgnums to 
+  # cust_bill_pkg_tax_location, so set that task done also.
+  FS::upgrade_journal->set_done('tax_location_taxable_billpkgnum');
 }
 
 =back