SureTax, #31639, #33015, #34598
[freeside.git] / FS / FS / cust_credit.pm
index 156ba5f..f63d86f 100644 (file)
@@ -132,11 +132,27 @@ sub cust_unlinked_msg {
   ' (cust_credit.crednum '. $self->crednum. ')';
 }
 
-=item insert
+=item insert [ OPTION => VALUE ... ]
 
 Adds this credit to the database ("Posts" the credit).  If there is an error,
 returns the error, otherwise returns false.
 
+Ooptions are passed as a list of keys and values.  Available options:
+
+=over 4
+
+=item reason_type
+
+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.
+They will have their crednum set and will be inserted along with this credit.
+
+=back
+
 =cut
 
 sub insert {
@@ -156,16 +172,23 @@ sub insert {
   my $cust_main = qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
   my $old_balance = $cust_main->balance;
 
-  unless ($self->reasonnum) {
-    my $result = $self->reason( $self->getfield('reason'),
-                                exists($options{ 'reason_type' })
-                                  ? ('reason_type' => $options{ 'reason_type' })
-                                  : (),
-                              );
-    unless($result) {
+  if (!$self->reasonnum) {
+    my $reason_text = $self->get('reason')
+      or return "reason text or existing reason required";
+    my $reason_type = $options{'reason_type'}
+      or return "reason type required";
+
+    local $@;
+    my $reason = FS::reason->new_or_existing(
+      reason => $reason_text,
+      type   => $reason_type,
+      class  => 'R',
+    );
+    if ($@) {
       $dbh->rollback if $oldAutoCommit;
-      return "failed to set reason for $me"; #: ". $dbh->errstr;
+      return "failed to set credit reason: $@";
     }
+    $self->set('reasonnum', $reason->reasonnum);
   }
 
   $self->setfield('reason', '');
@@ -176,6 +199,17 @@ sub insert {
     return "error inserting $self: $error";
   }
 
+  if ( $options{'cust_credit_source_bill_pkg'} ) {
+    foreach my $ccsbr ( @{ $options{'cust_credit_source_bill_pkg'} } ) {
+      $ccsbr->crednum( $self->crednum );
+      $error = $ccsbr->insert;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "error inserting $ccsbr: $error";
+      }
+    }
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 
   #false laziness w/ cust_pay::insert
@@ -248,7 +282,7 @@ sub delete {
     my $cust_main = $self->cust_main;
 
     my $error = send_email(
-      'from'    => $conf->config('invoice_from', $self->cust_main->agentnum),
+      'from'    => $conf->invoice_from_full($self->cust_main->agentnum),
                                  #invoice_from??? well as good as any
       'to'      => $conf->config('deletecredits'),
       'subject' => 'FREESIDE NOTIFICATION: Credit deleted',
@@ -348,13 +382,18 @@ adds a record of the voided credit to the cust_credit_void table.
 
 =cut
 
-# yes, false laziness with cust_pay and cust_bill
-# but frankly I don't have time to fix it now
-
 sub void {
   my $self = shift;
   my $reason = shift;
 
+  unless (ref($reason) || !$reason) {
+    $reason = FS::reason->new_or_existing(
+      'class'  => 'X',
+      'type'   => 'Void credit',
+      'reason' => $reason
+    );
+  }
+
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
   local $SIG{QUIT} = 'IGNORE';
@@ -369,7 +408,7 @@ sub void {
   my $cust_credit_void = new FS::cust_credit_void ( {
       map { $_ => $self->get($_) } $self->fields
     } );
-  $cust_credit_void->set('void_reason', $reason);
+  $cust_credit_void->set('void_reasonnum', $reason->reasonnum);
   my $error = $cust_credit_void->insert;
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
@@ -519,7 +558,7 @@ sub _upgrade_data {  # class method
   $class->_upgrade_otaker(%opts);
 
   if ( !FS::upgrade_journal->is_done('cust_credit__tax_link')
-      and !$conf->exists('enable_taxproducts') ) {
+      and !$conf->config('tax_data_vendor') ) {
     # RT#25458: fix credit line item applications that should refer to a 
     # specific tax allocation
     my @cust_credit_bill_pkg = qsearch({
@@ -679,11 +718,9 @@ Example:
     'apply'             => 1, #0 leaves the credit unapplied
 
     #the credit
-    'newreasonnum'      => scalar($cgi->param('newreasonnum')),
-    'newreasonnum_type' => scalar($cgi->param('newreasonnumT')),
     map { $_ => scalar($cgi->param($_)) }
       #fields('cust_credit')  
-      qw( custnum _date amount reason reasonnum addlinfo ), #pkgnum eventnum
+      qw( custnum _date amount reasonnum addlinfo ), #pkgnum eventnum
 
   );
 
@@ -725,26 +762,11 @@ sub credit_lineitems {
   #});
 
   my $error = '';
-  if ($arg{reasonnum} == -1) {
-
-    $error = 'Enter a new reason (or select an existing one)'
-      unless $arg{newreasonnum} !~ /^\s*$/;
-    my $reason = new FS::reason {
-                   'reason'      => $arg{newreasonnum},
-                   'reason_type' => $arg{newreasonnum_type},
-                 };
-    $error ||= $reason->insert;
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return "Error inserting reason: $error";
-    }
-    $arg{reasonnum} = $reason->reasonnum;
-  }
 
   my $cust_credit = new FS::cust_credit ( {
     map { $_ => $arg{$_} }
       #fields('cust_credit')
-      qw( custnum _date amount reason reasonnum addlinfo ), #pkgnum eventnum
+      qw( custnum _date amount reasonnum addlinfo ), #pkgnum eventnum
   } );
   $error = $cust_credit->insert;
   if ( $error ) {
@@ -830,16 +852,16 @@ sub credit_lineitems {
 
   foreach my $invnum ( sort { $a <=> $b } keys %cust_credit_bill ) {
 
-    my $arrayref_or_error =
-      $cust_main->calculate_taxes(
+    local $@;
+    my $arrayref_or_error = eval { $cust_main->calculate_taxes(
         $cust_bill_pkg{$invnum}, # list of taxable items that we're crediting
         $taxlisthash{$invnum},   # list of tax-item bindings
         $cust_bill_pkg{$invnum}->[0]->cust_bill->_date, # invoice time
-      );
+      ) };
 
-    unless ( ref( $arrayref_or_error ) ) {
+    if ( $@ ) {
       $dbh->rollback if $oldAutoCommit;
-      return "Error calculating taxes: $arrayref_or_error";
+      return "Error calculating taxes: $@";
     }
     
     my %tax_links; # {tax billpkgnum}{nontax billpkgnum}