summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/cust_main/Billing.pm34
-rw-r--r--FS/FS/part_pkg_link.pm10
2 files changed, 31 insertions, 13 deletions
diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm
index df7e17f81..0bc0fbd39 100644
--- a/FS/FS/cust_main/Billing.pm
+++ b/FS/FS/cust_main/Billing.pm
@@ -1133,19 +1133,39 @@ sub _make_lines {
# its frequency
my $main_pkg_freq = $main_pkg->part_pkg->freq;
my $supp_pkg_freq = $part_pkg->freq;
- my $ratio = $supp_pkg_freq / $main_pkg_freq;
- if ( $ratio != int($ratio) ) {
+ if ( $supp_pkg_freq == 0 or $main_pkg_freq == 0 ) {
# the UI should prevent setting up packages like this, but just
# in case
- return "supplemental package period is not an integer multiple of main package period";
+ return "unable to calculate supplemental package period ratio";
}
- $next_bill = $sdate;
- for (1..$ratio) {
- $next_bill = $part_pkg->add_freq( $next_bill, $main_pkg_freq );
+ my $ratio = $supp_pkg_freq / $main_pkg_freq;
+ if ( $ratio == int($ratio) ) {
+ # simple case: main package is X months, supp package is X*A months,
+ # advance supp package to where the main package will be in A cycles.
+ $next_bill = $sdate;
+ for (1..$ratio) {
+ $next_bill = $part_pkg->add_freq( $next_bill, $main_pkg_freq );
+ }
+ } else {
+ # harder case: main package is X months, supp package is Y months.
+ # advance supp package by Y months. then if they're within half a
+ # month of each other, resync them. this may result in the period
+ # not being exactly Y months.
+ $next_bill = $part_pkg->add_freq( $sdate, $supp_pkg_freq );
+ my $main_next_bill = $main_pkg->bill;
+ if ( $main_pkg->bill <= $time ) {
+ # then the main package has not yet been billed on this cycle;
+ # predict what its bill date will be.
+ $main_next_bill =
+ $part_pkg->add_freq( $main_next_bill, $main_pkg_freq );
+ }
+ if ( abs($main_next_bill - $next_bill) < 86400*15 ) {
+ $next_bill = $main_next_bill;
+ }
}
} else {
- # the normal case
+ # the normal case, not a supplemental package
$next_bill = $part_pkg->add_freq($sdate, $options{freq_override} || 0);
return "unparsable frequency: ". $part_pkg->freq
if $next_bill == -1;
diff --git a/FS/FS/part_pkg_link.pm b/FS/FS/part_pkg_link.pm
index ce071ef17..5fe6f2f01 100644
--- a/FS/FS/part_pkg_link.pm
+++ b/FS/FS/part_pkg_link.pm
@@ -250,12 +250,10 @@ sub check {
my $dst_pkg = $self->dst_pkg;
if ( $src_pkg->freq eq '0' and $dst_pkg->freq ne '0' ) {
return "One-time charges can't have supplemental packages."
- } elsif ( $dst_pkg->freq ne '0' ) {
- my $ratio = $dst_pkg->freq / $src_pkg->freq;
- if ($ratio != int($ratio)) {
- return "Supplemental package period (pkgpart ".$dst_pkg->pkgpart.
- ") must be an integer multiple of main package period.";
- }
+ } elsif ( $dst_pkg->freq == 0 ) {
+ return "The billing period of a supplemental package must be a whole number of months.";
+ } elsif ( $src_pkg->freq == 0 ) {
+ return "To have supplemental packages, the billing period of a package must be a whole number of months.";
}
}