eliminate some false laziness in FS::Misc::send_email vs. msg_template/email.pm send_...
[freeside.git] / FS / FS / cust_credit.pm
index 3fea561..ad888f9 100644 (file)
@@ -140,12 +140,12 @@ Ooptions are passed as a list of keys and values.  Available options:
 
 =item reason_type
 
-L<FS::reason_type|Reason> type for newly-inserted reason
+L<FS::reason_type> Reason type for newly-inserted reason
 
 =item cust_credit_source_bill_pkg
 
 An arrayref of
-L<FS::cust_credit_source_bill_pkg|FS::cust_credit_source_bilL_pkg> objects.
+L<FS::cust_credit_source_bill_pkg> objects.
 They will have their crednum set and will be inserted along with this credit.
 
 =back
@@ -167,6 +167,10 @@ sub insert {
   my $dbh = dbh;
 
   my $cust_main = qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
+  unless ( $cust_main ) {
+    $dbh->rollback if $oldAutoCommit;
+    return "Unknown custnum ". $self->custnum;
+  }
   my $old_balance = $cust_main->balance;
 
   if (!$self->reasonnum) {
@@ -728,10 +732,12 @@ sub calculate_tax_adjustment {
     if ($recur) {
       $recur -= $cust_bill_pkg->credited('', '', setuprecur => 'recur') || 0;
     }
+    # Skip line items that have been completely credited.
+    next if ($setup + $recur) == 0;
     my $setup_ratio = $setup / ($setup + $recur);
 
-    # Calculate the fraction of tax to credit: it's the fraction of this charge
-    # (either setup or recur) that's being credited.
+    # Calculate the fraction of tax to credit: it's the fraction of this
+    # charge (either setup or recur) that's being credited.
     my $charged = ($setuprecur eq 'setup') ? $setup : $recur;
     next if $charged == 0; # shouldn't happen, but still...
 
@@ -798,6 +804,7 @@ Example:
     'setuprecurs'       => \@setuprecurs,
     'amounts'           => \@amounts,
     'apply'             => 1, #0 leaves the credit unapplied
+    'set_source'        => 1, #creates credit source records for the line items
 
     #the credit
     map { $_ => scalar($cgi->param($_)) }
@@ -862,6 +869,8 @@ sub credit_lineitems {
     $arg{amount} = sprintf('%.2f', $tax_adjust{subtotal} + $tax_adjust{taxtotal});
   }
 
+  my $set_source = $arg{set_source};
+
   # create the credit
   my $cust_credit = new FS::cust_credit ( {
     map { $_ => $arg{$_} }
@@ -885,6 +894,7 @@ sub credit_lineitems {
   my %cust_bill_pkg = ();
   my %cust_credit_bill_pkg = ();
   my %unapplied_payments = (); #invoice numbers, and then billpaynums
+  my %currency;
 
   # little private function to unapply payments from a cust_bill_pkg until
   # there's a specified amount of unpaid balance on it.
@@ -896,7 +906,7 @@ sub credit_lineitems {
     my $invnum = $cust_bill_pkg->invnum;
 
     $need_to_unapply -= $cust_bill_pkg->owed($setuprecur);
-    next if $need_to_unapply < 0.005;
+    return if $need_to_unapply < 0.005;
 
     my $error;
     # then unapply payments one at a time (partially if need be) until the
@@ -957,6 +967,17 @@ sub credit_lineitems {
     # unapply payments if necessary
     $error = &{$unapply_sub}($cust_bill_pkg, $setuprecur, $amount);
 
+    if ( $set_source ) {
+      $currency{$invnum} ||= $cust_bill_pkg->cust_bill->currency;
+      my $source = FS::cust_credit_source_bill_pkg->new({
+        'crednum'     => $cust_credit->crednum,
+        'billpkgnum'  => $billpkgnum,
+        'amount'      => $amount,
+        'currency'    => $currency{invnum},
+      });
+      $error ||= $source->insert;
+    }
+
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return "Error unapplying payment: $error";
@@ -994,6 +1015,19 @@ sub credit_lineitems {
       };
 
     $error = &{$unapply_sub}($cust_bill_pkg, 'setup', $amount);
+
+    # I guess it's correct to do this for taxes also?
+    if ( $set_source ) {
+      $currency{$invnum} ||= $cust_bill_pkg->cust_bill->currency;
+      my $source = FS::cust_credit_source_bill_pkg->new({
+        'crednum'     => $cust_credit->crednum,
+        'billpkgnum'  => $billpkgnum,
+        'amount'      => $amount,
+        'currency'    => $currency{invnum},
+      });
+      $error ||= $source->insert;
+    }
+
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return "Error unapplying payment: $error";