RT#25563: Better handling of commissions which do not have rates configured [more...
[freeside.git] / FS / FS / part_event / Action / Mixin / credit_pkg.pm
index 9dcd701..2842218 100644 (file)
@@ -2,12 +2,19 @@ package FS::part_event::Action::Mixin::credit_pkg;
 
 use strict;
 
+# credit_pkg: calculates a credit amount that is some percentage of the 
+# package charge / cost / margin / some other amount of a package
+#
+# also provides an option field for the percentage, unless the action knows
+# how to calculate its own percentage somehow (has a _calc_credit_percent)
+
 sub eventtable_hashref {
   { 'cust_pkg' => 1 };
 }
 
 sub option_fields {
-  ( 
+  my $class = shift;
+  my @fields = (
     'reasonnum' => { 'label'        => 'Credit reason',
                      'type'         => 'select-reason',
                      'reason_class' => 'R',
@@ -16,24 +23,43 @@ sub option_fields {
                      'type'    => 'input-percentage',
                      'default' => '100',
                    },
-    'what' => { 'label'   => 'Of',
-                'type'    => 'select',
-                #add additional ways to specify in the package def
-                'options' => [ qw( base_recur_permonth unit_setup recur_cost_permonth setup_cost ) ],
-                'labels'  => { 'base_recur_permonth' => 'Base monthly fee',
-                               'unit_setup'          => 'Setup fee',
-                               'recur_cost_permonth' => 'Monthly cost',
-                               'setup_cost'          => 'Setup cost',
-                             },
-              },
+    'what' => {
+      'label'   => 'Of',
+      'type'    => 'select',
+      #add additional ways to specify in the package def
+      'options' => [qw(
+        base_recur_permonth cust_bill_pkg_recur recur_cost_permonth recur_margin_permonth
+        unit_setup setup_cost setup_margin
+      )],
+      'labels'  => {
+        'base_recur_permonth' => 'Base monthly fee',
+        'cust_bill_pkg_recur' => 'Actual invoiced amount of most recent'.
+                                 ' recurring charge',
+        'recur_cost_permonth' => 'Monthly cost',
+        'unit_setup'          => 'Setup fee',
+        'setup_cost'          => 'Setup cost',
+        'setup_margin'        => 'Setup margin (fee minus cost)',
+        'recur_margin_permonth' => 'Monthly margin (fee minus cost)',
+      },
+    },
   );
-
+  if ($class->can('_calc_credit_percent')) {
+    splice @fields, 2, 2; #remove the percentage option
+  }
+  @fields;
 }
 
-#my %no_cust_pkg = ( 'setup_cost' => 1 );
+# arguments:
+# 1. cust_pkg
+# 2. recipient of the credit (passed through to _calc_credit_percent)
+# 3. optional scalar reference for recording a warning message
 
 sub _calc_credit {
-  my( $self, $cust_pkg ) = @_;
+  my $self = shift;
+  my $cust_pkg = shift;
+  my $who = shift;
+  my $warnref = shift;
+  my $warning = '';
 
   my $cust_main = $self->cust_main($cust_pkg);
 
@@ -51,18 +77,21 @@ sub _calc_credit {
     }
   }
 
-  my $percent = $self->_calc_credit_percent($cust_pkg);
+  my $percent;
+  if ( $self->can('_calc_credit_percent') ) {
+    $percent = $self->_calc_credit_percent($cust_pkg, $who) || 0;
+    $warning = 'Percent calculated to zero ' unless $percent+0;
+  } else {
+    $percent = $self->option('percent') || 0;
+    $warning = 'Percent set to zero ' unless $percent+0;
+  }
 
-  #my @arg = $no_cust_pkg{$what} ? () : ($cust_pkg);
   my @arg = ($what eq 'setup_cost') ? () : ($cust_pkg);
+  my $charge = $part_pkg->$what(@arg) || 0;
+  $warning .= "$what is zero" unless $charge+0;
 
-  sprintf('%.2f', $part_pkg->$what(@arg) * $percent / 100 );
-
-}
-
-sub _calc_credit_percent {
-  my( $self, $cust_pkg ) = @_;
-  $self->option('percent');
+  $$warnref .= $warning if ref($warnref);
+  return sprintf('%.2f', $charge * $percent / 100 );
 }
 
 1;