package fees and usage-based fees, #27687, #25899
[freeside.git] / FS / FS / part_fee_usage.pm
1 package FS::part_fee_usage;
2
3 use strict;
4 use base qw( FS::Record );
5 use FS::Record qw( qsearch qsearchs );
6 use FS::part_fee;
7 use FS::usage_class;
8 use FS::Conf;
9
10 =head1 NAME
11
12 FS::part_fee_usage - Object methods for part_fee_usage records
13
14 =head1 SYNOPSIS
15
16   use FS::part_fee_usage;
17
18   $record = new FS::part_fee_usage \%hash;
19   $record = new FS::part_fee_usage { 'column' => 'value' };
20
21   $error = $record->insert;
22
23   $error = $new_record->replace($old_record);
24
25   $error = $record->delete;
26
27   $error = $record->check;
28
29 =head1 DESCRIPTION
30
31 An FS::part_fee_usage object is the part of a processing fee definition 
32 (L<FS::part_fee>) that applies to a specific telephone usage class 
33 (L<FS::usage_class>).  FS::part_fee_usage inherits from
34 FS::Record.  The following fields are currently supported:
35
36 =over 4
37
38 =item feepartusagenum - primary key
39
40 =item feepart - foreign key to L<FS::part_pkg>
41
42 =item classnum - foreign key to L<FS::usage_class>
43
44 =item amount - fixed amount to charge per usage record
45
46 =item percent - percentage of rated price to charge per usage record
47
48 =back
49
50 =head1 METHODS
51
52 =over 4
53
54 =cut
55
56 sub table { 'part_fee_usage'; }
57
58 sub check {
59   my $self = shift;
60
61   $self->set('amount', 0)  unless ($self->amount || 0) > 0;
62   $self->set('percent', 0) unless ($self->percent || 0) > 0;
63
64   my $error = 
65     $self->ut_numbern('feepartusagenum')
66     || $self->ut_foreign_key('feepart', 'part_fee', 'feepart')
67     || $self->ut_foreign_key('classnum', 'usage_class', 'classnum')
68     || $self->ut_money('amount')
69     || $self->ut_float('percent')
70   ;
71   return $error if $error;
72
73   $self->SUPER::check;
74 }
75
76 # silently discard records with percent = 0 and amount = 0
77
78 sub insert {
79   my $self = shift;
80   if ( $self->amount > 0 or $self->percent > 0 ) {
81     return $self->SUPER::insert;
82   }
83   '';
84 }
85
86 sub replace {
87   my ($new, $old) = @_;
88   $old ||= $new->replace_old;
89   if ( $new->amount > 0 or $new->percent > 0 ) {
90     return $new->SUPER::replace($old);
91   } elsif ( $old->feepartusagenum ) {
92     return $old->delete;
93   }
94   '';
95 }
96   
97 =item explanation
98
99 Returns a string describing how this fee is calculated.
100
101 =cut
102
103 sub explanation {
104   my $self = shift;
105   my $string = '';
106   my $money = (FS::Conf->new->config('money_char') || '$') . '%.2f';
107   my $percent = '%.1f%%';
108   if ( $self->amount > 0 ) {
109     $string = sprintf($money, $self->amount);
110   }
111   if ( $self->percent > 0 ) {
112     if ( $string ) {
113       $string .= ' plus ';
114     }
115     $string .= sprintf($percent, $self->percent);
116     $string .= ' of the rated charge';
117   }
118   $string .= ' per '.  $self->usage_class->classname . ' call';
119
120   return $string;
121 }
122
123 # stubs, remove under 4.x
124
125 sub part_fee {
126   my $self = shift;
127   FS::part_fee->by_key($self->feepart);
128 }
129
130 sub usage_class {
131   my $self = shift;
132   FS::usage_class->by_key($self->classnum);
133 }
134
135 =back
136
137 =head1 SEE ALSO
138
139 L<FS::Record>, schema.html from the base documentation.
140
141 =cut
142
143 1;
144