summaryrefslogtreecommitdiff
path: root/FS/FS
diff options
context:
space:
mode:
authorJonathan Prykop <jonathan@freeside.biz>2015-09-10 21:33:37 -0500
committerJonathan Prykop <jonathan@freeside.biz>2015-09-14 23:05:54 -0500
commit205cf3b843285a5858f1d6387386381564a5deca (patch)
tree2bf54867b4a4105c610147d3f28cfab99b0d3a31 /FS/FS
parentb78bb7aeaa27daab707106217b33e4096e985262 (diff)
RT#33410: Package GB add-ons
Diffstat (limited to 'FS/FS')
-rw-r--r--FS/FS/cust_pkg.pm12
-rw-r--r--FS/FS/cust_pkg_usageprice.pm5
-rw-r--r--FS/FS/part_pkg/sqlradacct_hour.pm15
-rw-r--r--FS/FS/part_pkg_usageprice.pm44
4 files changed, 68 insertions, 8 deletions
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index c5a3d2e..0ef7aa0 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -2296,9 +2296,15 @@ sub change {
}
}
- # transfer usage pricing add-ons, if we're not changing pkgpart
- if ( $same_pkgpart ) {
- foreach my $old_cust_pkg_usageprice ($self->cust_pkg_usageprice) {
+ # transfer usage pricing add-ons, if we're not changing pkgpart or if they were specified
+ if ( $same_pkgpart || $opt->{'cust_pkg_usageprice'}) {
+ my @old_cust_pkg_usageprice;
+ if ($opt->{'cust_pkg_usageprice'}) {
+ @old_cust_pkg_usageprice = @{ $opt->{'cust_pkg_usageprice'} };
+ } else {
+ @old_cust_pkg_usageprice = $self->cust_pkg_usageprice;
+ }
+ foreach my $old_cust_pkg_usageprice (@old_cust_pkg_usageprice) {
my $new_cust_pkg_usageprice = new FS::cust_pkg_usageprice {
'pkgnum' => $cust_pkg->pkgnum,
'usagepricepart' => $old_cust_pkg_usageprice->usagepricepart,
diff --git a/FS/FS/cust_pkg_usageprice.pm b/FS/FS/cust_pkg_usageprice.pm
index 5b6b18c..29e6278 100644
--- a/FS/FS/cust_pkg_usageprice.pm
+++ b/FS/FS/cust_pkg_usageprice.pm
@@ -163,6 +163,11 @@ sub apply {
#this has no multiplication involved, its just a set only
#} elsif ( $target eq 'svc_conferencing.confqualitynum' ) {
+
+ } elsif ( $target eq 'sqlradacct_hour.recur_included_total' ) {
+
+ $error = "Cannot call apply on target $target";
+
}
if ( $error ) {
diff --git a/FS/FS/part_pkg/sqlradacct_hour.pm b/FS/FS/part_pkg/sqlradacct_hour.pm
index 79e64fb..206bea0 100644
--- a/FS/FS/part_pkg/sqlradacct_hour.pm
+++ b/FS/FS/part_pkg/sqlradacct_hour.pm
@@ -105,7 +105,18 @@ sub calc_recur {
'AcctOutputOctets' )
/ BU;
- my $total = $input + $output - $self->option('recur_included_total');
+ my $included_total = $self->option('recur_included_total') || 0;
+ my $addoncharge = 0;
+ foreach my $cust_pkg_usageprice ($cust_pkg->cust_pkg_usageprice) {
+ my $part_pkg_usageprice = $cust_pkg_usageprice->part_pkg_usageprice;
+ $included_total += $cust_pkg_usageprice->quantity * $part_pkg_usageprice->amount;
+ $addoncharge += $cust_pkg_usageprice->price;
+ }
+ my $raw_total = $input + $output;
+ push(@$details,sprintf( "%.3f %ss included, %.3f %ss used", $included_total, BA, $raw_total, BA ))
+ if $included_total;
+
+ my $total = $input + $output - $included_total;
$total = 0 if $total < 0;
$input = $input - $self->option('recur_included_input');
$input = 0 if $input < 0;
@@ -153,7 +164,7 @@ sub calc_recur {
sprintf('%.1f', $hours). " hours: $hourscharge";
}
- my $charges = $hourscharge + $inputcharge + $outputcharge + $totalcharge;
+ my $charges = $hourscharge + $inputcharge + $outputcharge + $totalcharge + $addoncharge;
if ( $self->option('global_cap') && $charges > $self->option('global_cap') ) {
$charges = $self->option('global_cap');
push @$details, "Usage charges capped at: $charges";
diff --git a/FS/FS/part_pkg_usageprice.pm b/FS/FS/part_pkg_usageprice.pm
index 9c3b1be..b33904e 100644
--- a/FS/FS/part_pkg_usageprice.pm
+++ b/FS/FS/part_pkg_usageprice.pm
@@ -111,13 +111,46 @@ sub check {
|| $self->ut_enum('action', [ 'increment', 'set' ])
|| $self->ut_enum('target', [ 'svc_acct.totalbytes', 'svc_acct.seconds',
'svc_conferencing.participants',
- 'svc_conferencing.confqualitynum'
+# 'svc_conferencing.confqualitynum',
+ 'sqlradacct_hour.recur_included_total'
]
)
|| $self->ut_text('amount')
;
return $error if $error;
+ #Check target against package
+ #UI doesn't currently prevent these from happing,
+ #so keep error messages informative
+ my $part_pkg = $self->part_pkg;
+ my $target = $self->target;
+ my $label = $self->target_info->{'label'};
+ my ($needs_svcdb, $needs_plan);
+ if ( $target =~ /^svc_acct.(\w+)$/ ) {
+ $needs_svcdb = 'svc_acct';
+ } elsif ( $target eq 'svc_conferencing.participants' ) {
+ $needs_svcdb = 'svc_conferencing';
+ } elsif ( $target =~ /^sqlradacct_hour.(\w+)$/ ) {
+ $needs_plan = 'sqlradacct_hour';
+ }
+ if ($needs_svcdb) {
+ my $has_svcdb = 0;
+ foreach my $pkg_svc ($part_pkg->pkg_svc) {
+ next unless $pkg_svc->quantity;
+ my $svcdb = $pkg_svc->part_svc->svcdb;
+ $has_svcdb = 1
+ if $svcdb eq $needs_svcdb;
+ last if $has_svcdb;
+ }
+ return "Usage pricing add-on \'$label\' can only be used on packages with at least one $needs_svcdb service.\n"
+ unless $has_svcdb;
+ }
+ if ($needs_plan) {
+ return "Usage pricing add-on \'$label\' can only be used on packages with pricing plan \'" .
+ FS::part_pkg->plan_info->{$needs_plan}->{'shortname'} . "\'\n"
+ unless ref($part_pkg) eq 'FS::part_pkg::' . $needs_plan;
+ }
+
$self->SUPER::check;
}
@@ -147,10 +180,10 @@ sub targets {
#'svc_acct.totalbytes' => { label => 'Megabytes',
# multiplier => 1048576,
# },
- 'svc_acct.totalbytes' => { label => 'Gigabytes',
+ 'svc_acct.totalbytes' => { label => 'Total Gigabytes',
multiplier => 1073741824,
},
- 'svc_acct.seconds' => { label => 'Hours',
+ 'svc_acct.seconds' => { label => 'Total Hours',
multiplier => 3600,
},
'svc_conferencing.participants' => { label => 'Conference Participants',
@@ -160,6 +193,11 @@ sub targets {
# and then value comes from a select, not a text field
# 'svc_conferencing.confqualitynum' => { label => 'Conference Quality',
# },
+
+ # this bypasses usual apply methods, handled entirely in sqlradacct_hour
+ 'sqlradacct_hour.recur_included_total' => { label => 'Included Gigabytes',
+ multiplier => 1 }, #recur_included_total is stored in GB
+
;
\%targets;