sales commission events on invoices, #25847
[freeside.git] / FS / FS / part_event / Action / Mixin / credit_pkg.pm
1 package FS::part_event::Action::Mixin::credit_pkg;
2
3 use strict;
4
5 # credit_pkg: calculates a credit amount that is some percentage of the 
6 # package charge / cost / margin / some other amount of a package
7 #
8 # also provides an option field for the percentage, unless the action knows
9 # how to calculate its own percentage somehow (has a _calc_credit_percent)
10
11 sub eventtable_hashref {
12   { 'cust_pkg' => 1 };
13 }
14
15 sub option_fields {
16   my $class = shift;
17   my @fields = (
18     'reasonnum' => { 'label'        => 'Credit reason',
19                      'type'         => 'select-reason',
20                      'reason_class' => 'R',
21                    },
22     'percent'   => { 'label'   => 'Percent',
23                      'type'    => 'input-percentage',
24                      'default' => '100',
25                    },
26     'what' => {
27       'label'   => 'Of',
28       'type'    => 'select',
29       #add additional ways to specify in the package def
30       'options' => [qw(
31         base_recur_permonth cust_bill_pkg_recur recur_cost_permonth recur_margin_permonth
32         unit_setup setup_cost setup_margin
33       )],
34       'labels'  => {
35         'base_recur_permonth' => 'Base monthly fee',
36         'cust_bill_pkg_recur' => 'Actual invoiced amount of most recent'.
37                                  ' recurring charge',
38         'recur_cost_permonth' => 'Monthly cost',
39         'unit_setup'          => 'Setup fee',
40         'setup_cost'          => 'Setup cost',
41         'setup_margin'        => 'Setup margin (fee minus cost)',
42         'recur_margin_permonth' => 'Monthly margin (fee minus cost)',
43       },
44     },
45   );
46   if ($class->can('_calc_credit_percent')) {
47     splice @fields, 2, 2; #remove the percentage option
48   }
49   @fields;
50 }
51
52 # arguments:
53 # 1. cust_pkg
54 # 2. recipient of the credit (passed through to _calc_credit_percent)
55
56 sub _calc_credit {
57   my $self = shift;
58   my $cust_pkg = shift;
59
60   my $cust_main = $self->cust_main($cust_pkg);
61
62   my $part_pkg = $cust_pkg->part_pkg;
63
64   my $what = $self->option('what');
65
66   #false laziness w/Condition/cust_payments_pkg.pm
67   if ( $what =~ /_permonth$/ ) { #huh.  yuck.
68     if ( $part_pkg->freq !~ /^\d+$/ ) {
69       die 'WARNING: Not crediting for package '. $cust_pkg->pkgnum.
70           ' ( customer '. $cust_pkg->custnum. ')'.
71           ' - credits not (yet) available for '.
72           ' packages with '. $part_pkg->freq_pretty. ' frequency';
73     }
74   }
75
76   my $percent;
77   if ( $self->can('_calc_credit_percent') ) {
78     $percent = $self->_calc_credit_percent($cust_pkg, @_);
79   } else {
80     $percent = $self->option('percent') || 0;
81   }
82
83   my @arg = ($what eq 'setup_cost') ? () : ($cust_pkg);
84
85   sprintf('%.2f', $part_pkg->$what(@arg) * $percent / 100 );
86
87 }
88
89 1;