stray closing /TABLE in the no-ticket case
[freeside.git] / FS / FS / reason_Mixin.pm
index af9aa50..a1b32f2 100644 (file)
@@ -14,20 +14,16 @@ our $me = '[FS::reason_Mixin]';
 =item reason
 
 Returns the text of the associated reason (see L<FS::reason>) for this credit /
-voided payment / voided invoice.
+voided payment / voided invoice. This can no longer be used to set the
+(deprecated) free-text "reason" field; see L<FS::reason/new_or_existing>.
 
 =cut
 
 sub reason {
   my $self = shift;
 
-  my $reason_text;
-  if ( $self->reasonnum ) {
-    my $reason = FS::reason->by_key($self->reasonnum);
-    $reason_text = $reason->reason;
-  } else { # in case one of these somehow still exists
-    $reason_text = $self->get('reason');
-  }
+  my $reason_text = $self->reason_only;
+
   if ( $self->get('addlinfo') ) {
     $reason_text .= ' ' . $self->get('addlinfo');
   }
@@ -35,15 +31,55 @@ sub reason {
   return $reason_text;
 }
 
-# it was a mistake to allow setting the reason this way; use 
-# FS::reason->new_or_existing
+=item reason_only
+
+Returns only the text of the associated reason,
+absent any addlinfo that is included by L</reason>.
+(Currently only affects credit and credit void reasons.)
+
+=cut
+
+# a bit awkward, but much easier to invoke this in the few reports
+# that need separate fields than to update every place
+# that displays them together
+
+sub reason_only {
+  my $self = shift;
+  if ( $self->reasonnum ) {
+    my $reason = FS::reason->by_key($self->reasonnum);
+    return $reason->reason;
+  } else { # in case one of these somehow still exists
+    return $self->get('reason');
+  }
+}
+
 # Used by FS::Upgrade to migrate reason text fields to reasonnum.
+# Note that any new tables that get reasonnum fields do NOT need to be
+# added here unless they have previously had a free-text "reason" field.
+
 sub _upgrade_reasonnum {    # class method
     my $class = shift;
     my $table = $class->table;
 
+    my $reason_class;
+    if ( $table =~ /^cust_bill/ ) { # also includes cust_bill_pkg
+      $reason_class = 'I';
+    } elsif ( $table =~ /^cust_pay/ ) {
+      $reason_class = 'P';
+    } elsif ( $table eq 'cust_refund' ) {
+      $reason_class = 'F';
+    } elsif ( $table =~ /^cust_credit/ ) {
+      $reason_class = 'R';
+    } else {
+      die "don't know the reason class to use for upgrading $table";
+    }
+
     for my $fieldname (qw(reason void_reason)) {
+
+        if ( $table =~ /^cust_credit/ and $fieldname eq 'void_reason' ) {
+            $reason_class = 'X';
+        }
+
         if (   defined dbdef->table($table)->column($fieldname)
             && defined dbdef->table($table)->column( $fieldname . 'num' ) )
         {
@@ -58,25 +94,23 @@ sub _upgrade_reasonnum {    # class method
                 }
             );
 
-            if (
-                scalar(
-                    grep { $_->getfield($fieldname) =~ /\S/ }
-                      @legacy_reason_records
-                )
-              )
-            {
+            if ( @legacy_reason_records ) {
+
                 warn "$me Found unmigrated reasons\n" if $DEBUG;
 
                 my $reason_type =
-                  _upgrade_get_legacy_reason_type( $class, $table );
-                my $noreason = _upgrade_get_no_reason( $class, $reason_type );
+                  $class->_upgrade_get_legacy_reason_type( $reason_class );
+                # XXX "noreason" does not actually work, because we limited to
+                # "reason is not null" above. Records where the reason string
+                # is null will end up with a reasonnum of null also.
+                my $noreason = $class->_upgrade_get_no_reason( $reason_type );
 
                 foreach my $record_to_upgrade (@legacy_reason_records) {
                     my $reason = $record_to_upgrade->getfield($fieldname);
                     warn "Contemplating reason $reason\n" if $DEBUG > 1;
                     if ( $reason =~ /\S/ ) {
                         my $reason =
-                          _upgrade_get_reason( $class, $reason, $reason_type );
+                          $class->_upgrade_get_reason( $reason, $reason_type );
                         $record_to_upgrade->set( $fieldname . 'num',
                             $reason->reasonnum );
                     }
@@ -99,15 +133,14 @@ sub _upgrade_reasonnum {    # class method
     }
 }
 
+# internal methods for upgrade
+
 # _upgrade_get_legacy_reason_type is class method supposed to be used only
 # within the reason_Mixin class which will either find or create a reason_type
 sub _upgrade_get_legacy_reason_type {
  
     my $class = shift;
-    my $table = shift;
-
-    my $reason_class =
-      ( $table =~ /void/ ) ? 'X' : 'F';    # see FS::reason_type (%class_name)
+    my $reason_class = shift;
     my $reason_type_params = { 'class' => $reason_class, 'type' => 'Legacy' };
     my $reason_type = qsearchs( 'reason_type', $reason_type_params );
     unless ($reason_type) {
@@ -126,7 +159,7 @@ sub _upgrade_get_no_reason {
 
     my $class       = shift;
     my $reason_type = shift;
-    return _upgrade_get_reason( $class, '(none)', $reason_type );
+    return $class->_upgrade_get_reason( '(none)', $reason_type );
 }
 
 # _upgrade_get_reason is class method supposed to be used only within the