summaryrefslogtreecommitdiff
path: root/FS/FS/FeeOrigin_Mixin.pm
blob: 8bd9acd2c9600d68eea60a61a444061ed574d250 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package FS::FeeOrigin_Mixin;

use strict;
use base qw( FS::Record );
use FS::Record qw( qsearch qsearchs );
use FS::part_fee;
use FS::cust_bill_pkg;

# is there a nicer idiom for this?
our @subclasses = qw( FS::cust_event_fee FS::cust_pkg_reason_fee );
use FS::cust_event_fee;
use FS::cust_pkg_reason_fee;

=head1 NAME

FS::FeeOrigin_Mixin - Common interface for fee origin records

=head1 SYNOPSIS

  use FS::cust_event_fee;

  $record = new FS::cust_event_fee \%hash;
  $record = new FS::cust_event_fee { 'column' => 'value' };

  $error = $record->insert;

  $error = $new_record->replace($old_record);

  $error = $record->delete;

  $error = $record->check;

=head1 DESCRIPTION

An FS::FeeOrigin_Mixin object associates the timestamped event that triggered 
a fee (which may be a billing event, or something else like a package
suspension) to the resulting invoice line item (L<FS::cust_bill_pkg> object).
The following fields are required:

=over 4

=item billpkgnum - key of the cust_bill_pkg record representing the fee 
on an invoice.  This is a unique column but can be NULL to indicate a fee that
hasn't been billed yet.  In that case it will be billed the next time billing
runs for the customer.

=item feepart - key of the fee definition (L<FS::part_fee>).

=item nextbill - 'Y' if the fee should be charged on the customer's next bill,
rather than causing a bill to be produced immediately.

=back

=head1 CLASS METHODS

=over 4

=item by_cust CUSTNUM[, PARAMS]

Finds all cust_event_fee records belonging to the customer CUSTNUM.

PARAMS can be additional params to pass to qsearch; this really only works
for 'hashref' and 'order_by'.

=cut

# invoke for all subclasses, and return the results as a flat list

sub by_cust {
  my $class = shift;
  my @args = @_;
  return map { $_->_by_cust(@args) } @subclasses;
}

=back

=head1 INTERFACE

=over 4

=item _by_cust CUSTNUM[, PARAMS]

The L</by_cust> search method. Each subclass must implement this.

=item cust_bill

If the fee origin generates a fee based on past invoices (for example, an
invoice event that charges late fees), this method should return the
L<FS::cust_bill> object that will be the basis for the fee. If this returns
nothing, then then fee will be based on the rest of the invoice where it
appears.

=item cust_pkg

If the fee origin generates a fee limited in scope to one package (for
example, a package reconnection fee event), this method should return the
L<FS::cust_pkg> object the fee applies to. If it's a percentage fee, this
determines which charges it's a percentage of; otherwise it just affects the
fee description appearing on the invoice.

Currently not tested in combination with L</cust_bill>; be careful.

=cut

# stubs

sub _by_cust { my $class = shift; die "'$class' must provide _by_cust method" }

sub cust_bill { '' }

sub cust_pkg { '' }

# still necessary in 4.x; can't FK the billpkgnum because of voids
sub cust_bill_pkg {
  my $self = shift;
  $self->billpkgnum ? FS::cust_bill_pkg->by_key($self->billpkgnum) : '';
}

=head1 BUGS

=head1 SEE ALSO

L<FS::cust_event_fee>, L<FS::cust_pkg_reason_fee>, L<FS::cust_bill_pkg>, 
L<FS::part_fee>

=cut

1;