summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormark <mark>2010-12-24 09:49:32 +0000
committermark <mark>2010-12-24 09:49:32 +0000
commitd3ce5efd1ec0e1a715a154696e2b0aa86e51c27b (patch)
treee11f08a6fef3a0dfc59fd63c16db396e31272735
parent90393980e5f2859ee1e186fa461f48f5129e803e (diff)
part_pkg option inheritance, part 1
-rw-r--r--FS/FS/part_pkg.pm39
-rw-r--r--FS/FS/part_pkg/agent.pm13
-rw-r--r--FS/FS/part_pkg/base_delayed.pm14
-rw-r--r--FS/FS/part_pkg/base_rate.pm25
-rw-r--r--FS/FS/part_pkg/bulk.pm15
-rw-r--r--FS/FS/part_pkg/cdr_termination.pm17
-rw-r--r--FS/FS/part_pkg/flat.pm101
-rw-r--r--FS/FS/part_pkg/flat_comission.pm13
-rw-r--r--FS/FS/part_pkg/flat_comission_cust.pm29
-rw-r--r--FS/FS/part_pkg/flat_comission_pkg.pm26
-rw-r--r--FS/FS/part_pkg/flat_delayed.pm21
-rw-r--r--FS/FS/part_pkg/flat_introrate.pm28
-rw-r--r--FS/FS/part_pkg/global_Mixin.pm38
-rw-r--r--FS/FS/part_pkg/prepaid.pm17
-rw-r--r--FS/FS/part_pkg/prorate.pm80
-rw-r--r--FS/FS/part_pkg/prorate_delayed.pm22
-rw-r--r--FS/FS/part_pkg/rt_time.pm5
-rw-r--r--FS/FS/part_pkg/sesmon_hour.pm13
-rw-r--r--FS/FS/part_pkg/sesmon_minute.pm13
-rw-r--r--FS/FS/part_pkg/sql_external.pm13
-rw-r--r--FS/FS/part_pkg/sql_generic.pm13
-rw-r--r--FS/FS/part_pkg/sqlradacct_hour.pm14
-rw-r--r--FS/FS/part_pkg/subscription.pm9
-rw-r--r--FS/FS/part_pkg/usage_Mixin.pm77
-rw-r--r--FS/FS/part_pkg/voip_cdr.pm15
-rw-r--r--FS/FS/part_pkg/voip_inbound.pm16
-rw-r--r--FS/FS/part_pkg/voip_sqlradacct.pm13
27 files changed, 230 insertions, 469 deletions
diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm
index 5c67ed96a..58f70716d 100644
--- a/FS/FS/part_pkg.pm
+++ b/FS/FS/part_pkg.pm
@@ -1545,19 +1545,48 @@ foreach my $INC ( @INC ) {
next;
}
warn "got plan info from FS::part_pkg::$mod: $info\n" if $DEBUG;
- if ( exists($info->{'disabled'}) && $info->{'disabled'} ) {
- warn "skipping disabled plan FS::part_pkg::$mod" if $DEBUG;
- next;
- }
+ #if ( exists($info->{'disabled'}) && $info->{'disabled'} ) {
+ # warn "skipping disabled plan FS::part_pkg::$mod" if $DEBUG;
+ # next;
+ #}
$info{$mod} = $info;
+ $info->{'weight'} ||= 0; # quiet warnings
}
}
+# copy one level deep to allow replacement of fields and fieldorder
tie %plans, 'Tie::IxHash',
- map { $_ => $info{$_} }
+ map { my %infohash = %{ $info{$_} };
+ $_ => \%infohash }
sort { $info{$a}->{'weight'} <=> $info{$b}->{'weight'} }
keys %info;
+# inheritance of plan options
+foreach my $name (keys(%info)) {
+ if (exists($info{$name}->{'disabled'}) and $info{$name}->{'disabled'}) {
+ warn "skipping disabled plan FS::part_pkg::$name" if $DEBUG;
+ delete $plans{$name};
+ next;
+ }
+ my $parents = $info{$name}->{'inherit_fields'} || [];
+ my (%fields, %field_exists, @fieldorder);
+ foreach my $parent ($name, @$parents) {
+ %fields = ( # avoid replacing existing fields
+ %{ $info{$parent}->{'fields'} || {} },
+ %fields
+ );
+ foreach (@{ $info{$parent}->{'fieldorder'} || [] }) {
+ # avoid duplicates
+ next if $field_exists{$_};
+ $field_exists{$_} = 1;
+ # allow inheritors to remove inherited fields from the fieldorder
+ push @fieldorder, $_ if !exists($fields{$_}->{'disabled'});
+ }
+ }
+ $plans{$name}->{'fields'} = \%fields;
+ $plans{$name}->{'fieldorder'} = \@fieldorder;
+}
+
sub plan_info {
\%plans;
}
diff --git a/FS/FS/part_pkg/agent.pm b/FS/FS/part_pkg/agent.pm
index 69ecf77ca..6ab21d64f 100644
--- a/FS/FS/part_pkg/agent.pm
+++ b/FS/FS/part_pkg/agent.pm
@@ -19,16 +19,8 @@ $me = '[FS::part_pkg::agent]';
%info = (
'name' => 'Wholesale bulk billing, for master customers of an agent.',
'shortname' => 'Wholesale bulk billing for agent.',
-
+ 'inherit_fields' => [qw( prorate global_Mixin)],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
-
-
#'recur_method' => { 'name' => 'Recurring fee method',
# #'type' => 'radio',
# #'options' => \%recur_method,
@@ -49,8 +41,7 @@ $me = '[FS::part_pkg::agent]';
},
- #'fieldorder' => [qw( setup_fee recur_fee recur_method cutoff_day ) ],
- 'fieldorder' => [qw( setup_fee recur_fee cutoff_day add_full_period no_pkg_prorate ) ],
+ 'fieldorder' => [qw( cutoff_day add_full_period no_pkg_prorate ) ],
'weight' => 51,
diff --git a/FS/FS/part_pkg/base_delayed.pm b/FS/FS/part_pkg/base_delayed.pm
index df503760e..c6864a692 100644
--- a/FS/FS/part_pkg/base_delayed.pm
+++ b/FS/FS/part_pkg/base_delayed.pm
@@ -11,28 +11,18 @@ use FS::part_pkg::base_rate;
'name' => 'Free (or setup fee) for X days, then base rate'.
' (anniversary billing)',
'shortname' => 'Bulk (manual from "units" option), w/intro period',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
'free_days' => { 'name' => 'Initial free days',
'default' => 0,
},
- 'recur_fee' => { 'name' => 'Recurring base fee for this package',
- 'default' => 0,
- },
'recur_notify' => { 'name' => 'Number of days before recurring billing'.
' commences to notify customer. (0 means'.
' no warning)',
'default' => 0,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
},
- 'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee', 'recur_notify',
- 'unused_credit'
+ 'fieldorder' => [ 'free_days', 'recur_notify',
],
#'setup' => '\'my $d = $cust_pkg->bill || $time; $d += 86400 * \' + what.free_days.value + \'; $cust_pkg->bill($d); $cust_pkg_mod_flag=1; \' + what.setup_fee.value',
#'recur' => 'what.recur_fee.value',
diff --git a/FS/FS/part_pkg/base_rate.pm b/FS/FS/part_pkg/base_rate.pm
index 440e98518..678197799 100644
--- a/FS/FS/part_pkg/base_rate.pm
+++ b/FS/FS/part_pkg/base_rate.pm
@@ -12,23 +12,13 @@ use FS::part_pkg;
# XXX it multiplies recurring fee by cust_pkg option "units", how to
# express that
'shortname' => 'Bulk (manual from "units" option)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring Base fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
- 'externalid' => { 'name' => 'Optional External ID',
+ 'externalid' => { 'name' => 'Optional External ID',
'default' => '',
},
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit',
- 'externalid' ],
+ 'fieldorder' => [ qw( externalid ) ],
'weight' => 52,
);
@@ -59,13 +49,10 @@ sub base_recur {
}
sub calc_remain {
- my ($self, $cust_pkg) = @_;
- my $time = time; #should be able to pass this in for credit calculation
+ my ($self, $cust_pkg, %options) = @_;
+ my $time = $options{'time'} || time;
my $next_bill = $cust_pkg->getfield('bill') || 0;
- my $last_bill = $cust_pkg->last_bill || 0;
- return 0 if ! $self->base_recur($cust_pkg)
- || ! $self->option('unused_credit', 1)
- || ! $last_bill
+ return 0 if ! $self->base_recur($cust_pkg)
|| ! $next_bill
|| $next_bill < $time;
diff --git a/FS/FS/part_pkg/bulk.pm b/FS/FS/part_pkg/bulk.pm
index b28fd3046..0df929edf 100644
--- a/FS/FS/part_pkg/bulk.pm
+++ b/FS/FS/part_pkg/bulk.pm
@@ -12,23 +12,14 @@ $me = '[FS::part_pkg::bulk]';
%info = (
'name' => 'Bulk billing based on number of active services',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for the entire bulk package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for the entire bulk package',
- 'default' => 0,
- },
'svc_setup_fee' => { 'name' => 'Setup fee for each new service',
'default' => 0,
},
'svc_recur_fee' => { 'name' => 'Recurring fee for each service',
'default' => 0,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'summarize_svcs'=> { 'name' => 'Show a count of services on the invoice, '.
'instead of a detailed list',
'type' => 'checkbox',
@@ -38,8 +29,8 @@ $me = '[FS::part_pkg::bulk]';
'type' => 'checkbox',
},
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'svc_setup_fee', 'svc_recur_fee',
- 'unused_credit', 'summarize_svcs', 'no_prorate' ],
+ 'fieldorder' => [ 'svc_setup_fee', 'svc_recur_fee',
+ 'summarize_svcs', 'no_prorate' ],
'weight' => 50,
);
diff --git a/FS/FS/part_pkg/cdr_termination.pm b/FS/FS/part_pkg/cdr_termination.pm
index 0666d7939..840da8224 100644
--- a/FS/FS/part_pkg/cdr_termination.pm
+++ b/FS/FS/part_pkg/cdr_termination.pm
@@ -16,15 +16,8 @@ tie my %temporalities, 'Tie::IxHash',
%info = (
'name' => 'VoIP rating of CDR records for termination partners.',
'shortname' => 'VoIP/telco CDR termination',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
-
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
-
#'cdr_column' => { 'name' => 'Column from CDR records',
# 'type' => 'select',
# 'select_enum' => [qw(
@@ -49,11 +42,6 @@ tie my %temporalities, 'Tie::IxHash',
'select_options' => \%temporalities,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
-
'cutoff_day' => { 'name' => 'Billing Day (1 - 28) for prorating or '.
'subscription',
'default' => '1',
@@ -92,8 +80,7 @@ tie my %temporalities, 'Tie::IxHash',
},
#cdr_column
'fieldorder' => [qw(
- setup_fee recur_fee
- recur_temporality unused_credit recur_method cutoff_day
+ recur_temporality recur_method cutoff_day
add_full_period
output_format usage_section summarize_usage usage_mandate
)
diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm
index e8f54d124..b5e0fa023 100644
--- a/FS/FS/part_pkg/flat.pm
+++ b/FS/FS/part_pkg/flat.pm
@@ -2,8 +2,7 @@ package FS::part_pkg::flat;
use strict;
use vars qw( @ISA %info
- %usage_fields %usage_recharge_fields
- @usage_fieldorder @usage_recharge_fieldorder
+ %usage_recharge_fields @usage_recharge_fieldorder
);
use Tie::IxHash;
use List::Util qw(min); # max);
@@ -26,97 +25,16 @@ tie my %contract_years, 'Tie::IxHash', (
map { $_*12 => $_ } (1..5),
);
-%usage_fields = (
-
- 'seconds' => { 'name' => 'Time limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- },
- 'upbytes' => { 'name' => 'Upload limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'downbytes' => { 'name' => 'Download limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'totalbytes' => { 'name' => 'Transfer limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
-);
-
-%usage_recharge_fields = (
-
- 'recharge_amount' => { 'name' => 'Cost of recharge for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*(\.\d{2})?$/ },
- },
- 'recharge_seconds' => { 'name' => 'Recharge time for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- },
- 'recharge_upbytes' => { 'name' => 'Recharge upload for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'recharge_downbytes' => { 'name' => 'Recharge download for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'recharge_totalbytes' => { 'name' => 'Recharge transfer for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'usage_rollover' => { 'name' => 'Allow usage from previous period to roll '.
- ' over into current period',
- 'type' => 'checkbox',
- },
- 'recharge_reset' => { 'name' => 'Reset usage to these values on manual '.
- 'package recharge',
- 'type' => 'checkbox',
- },
-);
-
-@usage_fieldorder = qw( seconds upbytes downbytes totalbytes );
-@usage_recharge_fieldorder = qw(
- recharge_amount recharge_seconds recharge_upbytes
- recharge_downbytes recharge_totalbytes
- usage_rollover recharge_reset
-);
-
%info = (
'name' => 'Flat rate (anniversary billing)',
'shortname' => 'Anniversary',
+ 'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
-
#false laziness w/voip_cdr.pm
'recur_temporality' => { 'name' => 'Charge recurring fee for period',
'type' => 'select',
'select_options' => \%temporalities,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
#used in cust_pkg.pm so could add to any price plan
'expire_months' => { 'name' => 'Auto-add an expiration date this number of months out',
@@ -145,22 +63,16 @@ tie my %contract_years, 'Tie::IxHash', (
'type' => 'checkbox',
},
- %usage_fields,
- %usage_recharge_fields,
-
'externalid' => { 'name' => 'Optional External ID',
'default' => '',
},
},
- 'fieldorder' => [ qw( setup_fee recur_fee
- recur_temporality unused_credit
+ 'fieldorder' => [ qw( recur_temporality
expire_months adjourn_months
contract_end_months
start_1st sync_bill_date
suspend_bill unsuspend_adjust_bill
- ),
- @usage_fieldorder, @usage_recharge_fieldorder,
- qw( externalid ),
+ externalid ),
],
'weight' => 10,
);
@@ -239,12 +151,7 @@ sub calc_remain {
my $next_bill = $cust_pkg->getfield('bill') || 0;
- #my $last_bill = $cust_pkg->last_bill || 0;
- my $last_bill = $cust_pkg->get('last_bill') || 0; #->last_bill falls back to setup
-
return 0 if ! $self->base_recur($cust_pkg)
- || ! $self->option('unused_credit', 1)
- || ! $last_bill
|| ! $next_bill
|| $next_bill < $time;
diff --git a/FS/FS/part_pkg/flat_comission.pm b/FS/FS/part_pkg/flat_comission.pm
index c05e45586..ec8c8ebbc 100644
--- a/FS/FS/part_pkg/flat_comission.pm
+++ b/FS/FS/part_pkg/flat_comission.pm
@@ -10,17 +10,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Flat rate with recurring commission per (any) active package',
'shortname' => 'Commission per (any) active package',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'comission_amount' => { 'name' => 'Commission amount per month (per active package)',
'default' => 0,
},
@@ -35,7 +26,7 @@ use FS::part_pkg::flat;
'select_label' => 'type',
},
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'reason_type' ],
+ 'fieldorder' => [ 'comission_depth', 'comission_amount', 'reason_type' ],
#'setup' => 'what.setup_fee.value',
#'recur' => '\'my $error = $cust_pkg->cust_main->credit( \' + what.comission_amount.value + \' * scalar($cust_pkg->cust_main->referral_cust_pkg(\' + what.comission_depth.value+ \')), "commission" ); die $error if $error; \' + what.recur_fee.value + \';\'',
'weight' => 62,
diff --git a/FS/FS/part_pkg/flat_comission_cust.pm b/FS/FS/part_pkg/flat_comission_cust.pm
index 5db46585e..5acf73d7a 100644
--- a/FS/FS/part_pkg/flat_comission_cust.pm
+++ b/FS/FS/part_pkg/flat_comission_cust.pm
@@ -10,32 +10,9 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Flat rate with recurring commission per active customer',
'shortname' => 'Commission per active customer',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
- 'comission_amount' => { 'name' => 'Commission amount per month (per active customer)',
- 'default' => 0,
- },
- 'comission_depth' => { 'name' => 'Number of layers',
- 'default' => 1,
- },
- 'reason_type' => { 'name' => 'Reason type for commission credits',
- 'type' => 'select_table',
- 'select_table' => 'reason_type',
- 'select_hash' => { 'class' => 'R' },
- 'select_key' => 'typenum',
- 'select_label' => 'type',
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'reason_type' ],
+ 'inherit_fields' => [ 'flat_comission', 'global_Mixin' ],
+ 'fields' => { },
+ 'fieldorder' => [ ],
#'setup' => 'what.setup_fee.value',
#'recur' => '\'my $error = $cust_pkg->cust_main->credit( \' + what.comission_amount.value + \' * scalar($cust_pkg->cust_main->referral_cust_main_ncancelled(\' + what.comission_depth.value+ \')), "commission" ); die $error if $error; \' + what.recur_fee.value + \';\'',
'weight' => '60',
diff --git a/FS/FS/part_pkg/flat_comission_pkg.pm b/FS/FS/part_pkg/flat_comission_pkg.pm
index 6f5ee692c..26dd4d2fc 100644
--- a/FS/FS/part_pkg/flat_comission_pkg.pm
+++ b/FS/FS/part_pkg/flat_comission_pkg.pm
@@ -10,23 +10,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Flat rate with recurring commission per (selected) active package',
'shortname' => 'Commission per (selected) active package',
+ 'inherit_fields' => [ 'flat_comission', 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
- 'comission_amount' => { 'name' => 'Commission amount per month (per uncancelled package)',
- 'default' => 0,
- },
- 'comission_depth' => { 'name' => 'Number of layers',
- 'default' => 1,
- },
'comission_pkgpart' => { 'name' => 'Applicable packages<BR><FONT SIZE="-1">(hold <b>ctrl</b> to select multiple packages)</FONT>',
'type' => 'select_multiple',
'select_table' => 'part_pkg',
@@ -34,15 +19,8 @@ use FS::part_pkg::flat;
'select_key' => 'pkgpart',
'select_label' => 'pkg',
},
- 'reason_type' => { 'name' => 'Reason type for commission credits',
- 'type' => 'select',
- 'select_table' => 'reason_type',
- 'select_hash' => { 'class' => 'R' } ,
- 'select_key' => 'typenum',
- 'select_label' => 'type',
- },
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'comission_pkgpart', 'reason_type' ],
+ 'fieldorder' => [ 'comission_depth', 'comission_amount', 'comission_pkgpart', 'reason_type' ],
#'setup' => 'what.setup_fee.value',
#'recur' => '""; var pkgparts = ""; for ( var c=0; c < document.flat_comission_pkg.comission_pkgpart.options.length; c++ ) { if (document.flat_comission_pkg.comission_pkgpart.options[c].selected) { pkgparts = pkgparts + document.flat_comission_pkg.comission_pkgpart.options[c].value + \', \'; } } what.recur.value = \'my $error = $cust_pkg->cust_main->credit( \' + what.comission_amount.value + \' * scalar( grep { my $pkgpart = $_->pkgpart; grep { $_ == $pkgpart } ( \' + pkgparts + \' ) } $cust_pkg->cust_main->referral_cust_pkg(\' + what.comission_depth.value+ \')), "commission" ); die $error if $error; \' + what.recur_fee.value + \';\'',
#'disabled' => 1,
diff --git a/FS/FS/part_pkg/flat_delayed.pm b/FS/FS/part_pkg/flat_delayed.pm
index 33f9dd80e..b4be72bec 100644
--- a/FS/FS/part_pkg/flat_delayed.pm
+++ b/FS/FS/part_pkg/flat_delayed.pm
@@ -11,28 +11,18 @@ use FS::part_pkg::flat;
'name' => 'Free (or setup fee) for X days, then flat rate'.
' (anniversary billing)',
'shortname' => 'Anniversary, with intro period',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
'free_days' => { 'name' => 'Initial free days',
'default' => 0,
},
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
'recur_notify' => { 'name' => 'Number of days before recurring billing'.
' commences to notify customer. (0 means'.
' no warning)',
'default' => 0,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
- },
- 'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee', 'recur_notify',
- 'unused_credit'
+ },
+ 'fieldorder' => [ 'free_days', 'recur_notify',
],
#'setup' => '\'my $d = $cust_pkg->bill || $time; $d += 86400 * \' + what.free_days.value + \'; $cust_pkg->bill($d); $cust_pkg_mod_flag=1; \' + what.setup_fee.value',
#'recur' => 'what.recur_fee.value',
@@ -58,11 +48,6 @@ sub calc_remain {
return 0 if $last_bill + (86400 * $free_days) == $next_bill
&& $last_bill == $cust_pkg->setup;
- return 0 if ! $self->base_recur($cust_pkg)
- || ! $self->option('unused_credit', 1)
- || ! $last_bill
- || ! $next_bill;
-
return $self->SUPER::calc_remain($cust_pkg, %options);
}
diff --git a/FS/FS/part_pkg/flat_introrate.pm b/FS/FS/part_pkg/flat_introrate.pm
index 2d551f10f..1447730e7 100644
--- a/FS/FS/part_pkg/flat_introrate.pm
+++ b/FS/FS/part_pkg/flat_introrate.pm
@@ -2,7 +2,6 @@ package FS::part_pkg::flat_introrate;
use strict;
use vars qw(@ISA %info $DEBUG $me);
-#use FS::Record qw(qsearch qsearchs);
use FS::part_pkg::flat;
use Date::Manip qw(DateCalc UnixDate ParseDate);
@@ -11,22 +10,23 @@ use Date::Manip qw(DateCalc UnixDate ParseDate);
$me = '[' . __PACKAGE__ . ']';
$DEBUG = 0;
-(%info) = (%FS::part_pkg::flat::info);
-$info{name} = 'Introductory price for X months, then flat rate,'.
- 'relative to setup date (anniversary billing)';
-$info{shortname} = 'Anniversary, with intro price';
-$info{fields} = { %{$info{fields}} };
-$info{fields}{intro_fee} =
- { 'name' => 'Introductory recurring fee for this package',
+%info = (
+ 'name' => 'Introductory price for X months, then flat rate,'.
+ 'relative to setup date (anniversary billing)',
+ 'shortname' => 'Anniversary, with intro price',
+ 'inherit_fields' => [ 'flat', 'usage_Mixin', 'global_Mixin' ],
+ 'fields' => {
+ 'intro_fee' => { 'name' => 'Introductory recurring fee for this package',
'default' => 0,
- };
-$info{fields}{intro_duration} =
+ },
+ 'intro_duration' =>
{ 'name' => 'Duration of the introductory period, in number of months',
'default' => 0,
- };
-$info{fieldorder} = [ @{ $info{fieldorder} } ];
-splice @{$info{fieldorder}}, 1, 0, qw( intro_duration intro_fee );
-$info{weight} = 14;
+ },
+ },
+ 'fieldorder' => [ qw(intro_duration intro_fee) ],
+ 'weight' => 14,
+);
sub base_recur {
my($self, $cust_pkg, $time ) = @_;
diff --git a/FS/FS/part_pkg/global_Mixin.pm b/FS/FS/part_pkg/global_Mixin.pm
new file mode 100644
index 000000000..56f160247
--- /dev/null
+++ b/FS/FS/part_pkg/global_Mixin.pm
@@ -0,0 +1,38 @@
+package FS::part_pkg::global_Mixin;
+
+use strict;
+use vars qw(@ISA %info);
+use FS::part_pkg;
+@ISA = qw(FS::part_pkg);
+
+%info = (
+ 'disabled' => 1,
+ 'fields' => {
+ 'setup_fee' => {
+ 'name' => 'Setup fee for this package',
+ 'default' => 0,
+ },
+ 'recur_fee' => {
+ 'name' => 'Recurring fee for this package',
+ 'default' => 0,
+ },
+ 'unused_credit_cancel' => {
+ 'name' => 'Credit the customer for the unused portion of service at '.
+ 'cancellation',
+ 'type' => 'checkbox',
+ },
+ 'unused_credit_change' => {
+ 'name' => 'Credit the customer for the unused portion of service when '.
+ 'changing packages',
+ 'type' => 'checkbox',
+ },
+ },
+ 'fieldorder' => [ qw(
+ setup_fee
+ recur_fee
+ unused_credit_cancel
+ unused_credit_change
+ )],
+);
+
+1;
diff --git a/FS/FS/part_pkg/prepaid.pm b/FS/FS/part_pkg/prepaid.pm
index cff165a5d..407343bc8 100644
--- a/FS/FS/part_pkg/prepaid.pm
+++ b/FS/FS/part_pkg/prepaid.pm
@@ -21,28 +21,25 @@ tie my %overlimit_action, 'Tie::IxHash',
'name' => 'Prepaid, flat rate',
#'name' => 'Prepaid (no automatic recurring)', #maybe use it here too
'shortname' => 'Prepaid, no automatic cycle',
+ 'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'One-time setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Initial and recharge fee for this package',
- 'default' => 0,
- },
'recur_action' => { 'name' => 'Action to take upon reaching end of prepaid preiod',
'type' => 'select',
'select_options' => \%recur_action,
},
- %FS::part_pkg::flat::usage_fields,
'overlimit_action' => { 'name' => 'Action to take upon reaching a usage limit.',
'type' => 'select',
'select_options' => \%overlimit_action,
},
#XXX if you set overlimit_action to 'cancel', should also have the ability
# to select a reason
+
+ # do we need to disable these?
+ map { $_ => { 'disabled' => 1 } } (
+ qw(recharge_amount recharge_seconds recharge_upbytes recharge_downbytes
+ recharge_totalbytes usage_rollover recharge_reset) ),
},
- 'fieldorder' => [ qw( setup_fee recur_fee recur_action ),
- @FS::part_pkg::flat::usage_fieldorder, 'overlimit_action',
- ],
+ 'fieldorder' => [ qw( recur_action overlimit_action ) ],
'weight' => 25,
);
diff --git a/FS/FS/part_pkg/prorate.pm b/FS/FS/part_pkg/prorate.pm
index 4abdb8d83..367f15275 100644
--- a/FS/FS/part_pkg/prorate.pm
+++ b/FS/FS/part_pkg/prorate.pm
@@ -11,74 +11,14 @@ use FS::part_pkg::flat;
%info = (
'name' => 'First partial month pro-rated, then flat-rate (selectable billing day)',
'shortname' => 'Prorate (Nth of month billing)',
+ 'inherit_fields' => [ 'flat', 'usage_Mixin', 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
+ 'recur_temporality' => {'disabled' => 1},
+ 'sync_bill_date' => {'disabled' => 1},
'cutoff_day' => { 'name' => 'Billing Day (1 - 28)',
'default' => 1,
},
- 'seconds' => { 'name' => 'Time limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- },
- 'upbytes' => { 'name' => 'Upload limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'downbytes' => { 'name' => 'Download limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'totalbytes' => { 'name' => 'Transfer limit for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'recharge_amount' => { 'name' => 'Cost of recharge for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*(\.\d{2})?$/ },
- },
- 'recharge_seconds' => { 'name' => 'Recharge time for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- },
- 'recharge_upbytes' => { 'name' => 'Recharge upload for this package',
- 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'recharge_downbytes' => { 'name' => 'Recharge download for this package', 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'recharge_totalbytes' => { 'name' => 'Recharge transfer for this package', 'default' => '',
- 'check' => sub { shift =~ /^\d*$/ },
- 'format' => \&FS::UI::bytecount::display_bytecount,
- 'parse' => \&FS::UI::bytecount::parse_bytecount,
- },
- 'usage_rollover' => { 'name' => 'Allow usage from previous period to roll '.
- 'over into current period',
- 'type' => 'checkbox',
- },
- 'recharge_reset' => { 'name' => 'Reset usage to these values on manual '.
- 'package recharge',
- 'type' => 'checkbox',
- },
+
'add_full_period'=> { 'name' => 'When prorating first month, also bill '.
'for one full period after that',
'type' => 'checkbox',
@@ -88,18 +28,8 @@ use FS::part_pkg::flat;
'the nearest full day',
'type' => 'checkbox',
},
-
- #it would be better if this had to be turned on, its confusing
- 'externalid' => { 'name' => 'Optional External ID',
- 'default' => '',
- },
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'cutoff_day',
- 'seconds', 'upbytes', 'downbytes', 'totalbytes',
- 'recharge_amount', 'recharge_seconds', 'recharge_upbytes',
- 'recharge_downbytes', 'recharge_totalbytes',
- 'usage_rollover', 'recharge_reset', 'add_full_period',
- 'prorate_round_day', 'externalid', ],
+ 'fieldorder' => [ 'cutoff_day', 'add_full_period', 'prorate_round_day' ],
'freq' => 'm',
'weight' => 20,
);
diff --git a/FS/FS/part_pkg/prorate_delayed.pm b/FS/FS/part_pkg/prorate_delayed.pm
index 0073493ed..dd1b81600 100644
--- a/FS/FS/part_pkg/prorate_delayed.pm
+++ b/FS/FS/part_pkg/prorate_delayed.pm
@@ -11,27 +11,18 @@ use FS::part_pkg;
'name' => 'Free (or setup fee) for X days, then prorate, then flat-rate ' .
'(1st of month billing)',
'shortname' => 'Prorate (Nth of month billing), with intro period', #??
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
'free_days' => { 'name' => 'Initial free days',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
+ 'default' => 0,
},
'recur_notify' => { 'name' => 'Number of days before recurring billing'.
' commences to notify customer. (0 means'.
' no warning)',
'default' => 0,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
},
- 'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee', 'unused_credit' ],
+ 'fieldorder' => [ 'free_days', 'recur_notify' ],
#'setup' => '\'my $d = $cust_pkg->bill || $time; $d += 86400 * \' + what.free_days.value + \'; $cust_pkg->bill($d); $cust_pkg_mod_flag=1; \' + what.setup_fee.value',
#'recur' => 'what.recur_fee.value',
'weight' => 22,
@@ -49,18 +40,13 @@ sub calc_setup {
sub calc_remain {
my ($self, $cust_pkg, %options) = @_;
- my $next_bill = $cust_pkg->getfield('bill') || 0;
my $last_bill = $cust_pkg->last_bill || 0;
+ my $next_bill = $cust_pkg->getfield('bill') || 0;
my $free_days = $self->option('free_days');
return 0 if $last_bill + (86400 * $free_days) == $next_bill
&& $last_bill == $cust_pkg->setup;
- return 0 if ! $self->base_recur($cust_pkg)
- || ! $self->option('unused_credit', 1)
- || ! $last_bill
- || ! $next_bill;
-
return $self->SUPER::calc_remain($cust_pkg, %options);
}
diff --git a/FS/FS/part_pkg/rt_time.pm b/FS/FS/part_pkg/rt_time.pm
index 9452d4402..03ed1cde7 100644
--- a/FS/FS/part_pkg/rt_time.pm
+++ b/FS/FS/part_pkg/rt_time.pm
@@ -14,11 +14,14 @@ our %info = (
'name' => 'Bill from Time Worked on tickets in RT',
'shortname' => 'Project Billing (RT)',
'weight' => 55,
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
'base_rate' => { 'name' => 'Rate (per minute)',
'default' => 0,
},
- }
+ 'recur_fee' => {'disabled' => 1},
+ },
+ 'fieldorder' => [ 'base_rate' ],
);
sub calc_setup {
diff --git a/FS/FS/part_pkg/sesmon_hour.pm b/FS/FS/part_pkg/sesmon_hour.pm
index e608d5510..97274d094 100644
--- a/FS/FS/part_pkg/sesmon_hour.pm
+++ b/FS/FS/part_pkg/sesmon_hour.pm
@@ -10,17 +10,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Base charge plus charge per-hour from the session monitor',
'shortname' => 'Session monitor (per-hour)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'recur_included_hours' => { 'name' => 'Hours included',
'default' => 0,
},
@@ -28,7 +19,7 @@ use FS::part_pkg::flat;
'default' => 0,
},
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'recur_included_hours', 'recur_hourly_charge' ],
+ 'fieldorder' => [ 'recur_included_hours', 'recur_hourly_charge' ],
#'setup' => 'what.setup_fee.value',
#'recur' => '\'my $hours = $cust_pkg->seconds_since($cust_pkg->bill || 0) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; \' + what.recur_fee.value + \' + \' + what.recur_hourly_charge.value + \' * $hours;\'',
'weight' => 80,
diff --git a/FS/FS/part_pkg/sesmon_minute.pm b/FS/FS/part_pkg/sesmon_minute.pm
index 654fdf596..9c8dfd1b7 100644
--- a/FS/FS/part_pkg/sesmon_minute.pm
+++ b/FS/FS/part_pkg/sesmon_minute.pm
@@ -10,17 +10,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Base charge plus charge per-minute from the session monitor',
'shortname' => 'Session monitor (per-minute)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'recur_included_min' => { 'name' => 'Minutes included',
'default' => 0,
},
@@ -28,7 +19,7 @@ use FS::part_pkg::flat;
'default' => 0,
},
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'recur_included_min', 'recur_minly_charge' ],
+ 'fieldorder' => [ 'recur_included_min', 'recur_minly_charge' ],
#'setup' => 'what.setup_fee.value',
#'recur' => '\'my $min = $cust_pkg->seconds_since($cust_pkg->bill || 0) / 60 - \' + what.recur_included_min.value + \'; $min = 0 if $min < 0; \' + what.recur_fee.value + \' + \' + what.recur_minly_charge.value + \' * $min;\'',
'weight' => 80,
diff --git a/FS/FS/part_pkg/sql_external.pm b/FS/FS/part_pkg/sql_external.pm
index 8e803f967..8d4308676 100644
--- a/FS/FS/part_pkg/sql_external.pm
+++ b/FS/FS/part_pkg/sql_external.pm
@@ -9,17 +9,8 @@ use DBI;
%info = (
'name' => 'Base charge plus additional fees for external services from a configurable SQL query',
'shortname' => 'External SQL query',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'cutoff_day' => { 'name' => 'Billing Day (1 - 28) for prorating or '.
'subscription',
'default' => '1',
@@ -48,7 +39,7 @@ use DBI;
'default' => '',
},
},
- 'fieldorder' => [qw( setup_fee recur_fee unused_credit recur_method cutoff_day
+ 'fieldorder' => [qw( recur_method cutoff_day
add_full_period datasrc db_username db_password query
)],
'weight' => '58',
diff --git a/FS/FS/part_pkg/sql_generic.pm b/FS/FS/part_pkg/sql_generic.pm
index eb8004476..cf38257fa 100644
--- a/FS/FS/part_pkg/sql_generic.pm
+++ b/FS/FS/part_pkg/sql_generic.pm
@@ -11,17 +11,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Base charge plus a per-domain metered rate from a configurable SQL query',
'shortname' => 'Bulk (per-domain from SQL query)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'recur_included' => { 'name' => 'Units included',
'default' => 0,
},
@@ -41,7 +32,7 @@ use FS::part_pkg::flat;
'default' => '',
},
},
- 'fieldorder' => [qw( setup_fee recur_fee unused_credit recur_included recur_unit_charge datasrc db_username db_password query )],
+ 'fieldorder' => [qw( recur_included recur_unit_charge datasrc db_username db_password query )],
# 'setup' => 'what.setup_fee.value',
# 'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\") or die $DBI::errstr; \'',
#'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\", \"\' + what.db_password.value + \'\" ) or die $DBI::errstr; my $sth = $dbh->prepare(\"\' + what.query.value + \'\") or die $dbh->errstr; my $units = 0; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq \"svc_domain\" } $cust_pkg->cust_svc ) { my $domain = $cust_svc->svc_x->domain; $sth->execute($domain) or die $sth->errstr; $units += $sth->fetchrow_arrayref->[0]; } $units -= \' + what.recur_included.value + \'; $units = 0 if $units < 0; \' + what.recur_fee.value + \' + $units * \' + what.recur_unit_charge.value + \';\'',
diff --git a/FS/FS/part_pkg/sqlradacct_hour.pm b/FS/FS/part_pkg/sqlradacct_hour.pm
index 15f678f0e..3cc46acc4 100644
--- a/FS/FS/part_pkg/sqlradacct_hour.pm
+++ b/FS/FS/part_pkg/sqlradacct_hour.pm
@@ -10,18 +10,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'Base charge plus per-hour (and for data) from an SQL RADIUS radacct table',
'shortname' => 'Usage charges from RADIUS',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
-
'recur_included_hours' => { 'name' => 'Hours included',
'default' => 0,
},
@@ -77,7 +67,7 @@ use FS::part_pkg::flat;
},
},
- 'fieldorder' => [qw( setup_fee recur_fee unused_credit recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )],
+ 'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )],
#'setup' => 'what.setup_fee.value',
#'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_output_charge.value + \' > 0 ) { push @details, \"Last month\\\'s upload \". sprintf(\"%.1f\", $output). \" megs: \\\$$outputcharge\" } if ( \' + what.recur_hourly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_fee.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'',
'weight' => 40,
diff --git a/FS/FS/part_pkg/subscription.pm b/FS/FS/part_pkg/subscription.pm
index 5495e3ad3..3c5f96b89 100644
--- a/FS/FS/part_pkg/subscription.pm
+++ b/FS/FS/part_pkg/subscription.pm
@@ -11,13 +11,8 @@ use FS::part_pkg::flat;
%info = (
'name' => 'First partial month full charge, then flat-rate (selectable billing day)',
'shortname' => 'Subscription (Nth of month, full charge for first)',
+ 'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
'cutoff_day' => { 'name' => 'Billing day',
'default' => 1,
},
@@ -81,7 +76,7 @@ use FS::part_pkg::flat;
'default' => '',
},
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'cutoff_day', 'seconds',
+ 'fieldorder' => [ 'cutoff_day', 'seconds',
'upbytes', 'downbytes', 'totalbytes',
'recharge_amount', 'recharge_seconds', 'recharge_upbytes',
'recharge_downbytes', 'recharge_totalbytes',
diff --git a/FS/FS/part_pkg/usage_Mixin.pm b/FS/FS/part_pkg/usage_Mixin.pm
new file mode 100644
index 000000000..028fce7b9
--- /dev/null
+++ b/FS/FS/part_pkg/usage_Mixin.pm
@@ -0,0 +1,77 @@
+package FS::part_pkg::usage_Mixin;
+
+use strict;
+use vars qw( @ISA %info );
+use FS::part_pkg;
+use FS::UI::bytecount;
+@ISA = qw(FS::part_pkg);
+
+# Field definitions for time and data usage, other than CDRs.
+
+%info = (
+ 'disabled' => 1,
+ 'fields' => {
+ 'seconds' => { 'name' => 'Time limit for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ },
+ 'upbytes' => { 'name' => 'Upload limit for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ 'format' => \&FS::UI::bytecount::display_bytecount,
+ 'parse' => \&FS::UI::bytecount::parse_bytecount,
+ },
+ 'downbytes' => { 'name' => 'Download limit for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ 'format' => \&FS::UI::bytecount::display_bytecount,
+ 'parse' => \&FS::UI::bytecount::parse_bytecount,
+ },
+ 'totalbytes' => { 'name' => 'Transfer limit for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ 'format' => \&FS::UI::bytecount::display_bytecount,
+ 'parse' => \&FS::UI::bytecount::parse_bytecount,
+ },
+ 'recharge_amount' => { 'name' => 'Cost of recharge for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*(\.\d{2})?$/ },
+ },
+ 'recharge_seconds' => { 'name' => 'Recharge time for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ },
+ 'recharge_upbytes' => { 'name' => 'Recharge upload for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ 'format' => \&FS::UI::bytecount::display_bytecount,
+ 'parse' => \&FS::UI::bytecount::parse_bytecount,
+ },
+ 'recharge_downbytes' => { 'name' => 'Recharge download for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ 'format' => \&FS::UI::bytecount::display_bytecount,
+ 'parse' => \&FS::UI::bytecount::parse_bytecount,
+ },
+ 'recharge_totalbytes' => { 'name' => 'Recharge transfer for this package',
+ 'default' => '',
+ 'check' => sub { shift =~ /^\d*$/ },
+ 'format' => \&FS::UI::bytecount::display_bytecount,
+ 'parse' => \&FS::UI::bytecount::parse_bytecount,
+ },
+ 'usage_rollover' => { 'name' => 'Allow usage from previous period to roll '.
+ ' over into current period',
+ 'type' => 'checkbox',
+ },
+ 'recharge_reset' => { 'name' => 'Reset usage to these values on manual '.
+ 'package recharge',
+ 'type' => 'checkbox',
+ },
+ },
+ 'fieldorder' => [ qw( seconds upbytes downbytes totalbytes
+ recharge_amount recharge_seconds recharge_upbytes
+ recharge_downbytes recharge_totalbytes
+ usage_rollover recharge_reset ) ],
+);
+
+1;
diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm
index 768f89487..5dbd115ad 100644
--- a/FS/FS/part_pkg/voip_cdr.pm
+++ b/FS/FS/part_pkg/voip_cdr.pm
@@ -48,25 +48,14 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
%info = (
'name' => 'VoIP rating by plan of CDR records in an internal (or external) SQL table',
'shortname' => 'VoIP/telco CDR rating (standard)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
-
#false laziness w/flat.pm
'recur_temporality' => { 'name' => 'Charge recurring fee for period',
'type' => 'select',
'select_options' => \%temporalities,
},
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
-
'cutoff_day' => { 'name' => 'Billing Day (1 - 28) for prorating or '.
'subscription',
'default' => '1',
@@ -259,7 +248,7 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
},
'fieldorder' => [qw(
- setup_fee recur_fee recur_temporality unused_credit
+ recur_temporality
recur_method cutoff_day
add_full_period
cdr_svc_method
diff --git a/FS/FS/part_pkg/voip_inbound.pm b/FS/FS/part_pkg/voip_inbound.pm
index 8b1844ad9..1b91575d4 100644
--- a/FS/FS/part_pkg/voip_inbound.pm
+++ b/FS/FS/part_pkg/voip_inbound.pm
@@ -24,25 +24,13 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
%info = (
'name' => 'VoIP flat rate pricing of CDRs for inbound calls',
'shortname' => 'VoIP/telco CDR rating (inbound)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
-
#false laziness w/flat.pm
'recur_temporality' => { 'name' => 'Charge recurring fee for period',
'type' => 'select',
'select_options' => \%temporalities,
},
-
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
-
'cutoff_day' => { 'name' => 'Billing Day (1 - 28) for prorating or '.
'subscription',
'default' => '1',
@@ -155,7 +143,7 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
},
'fieldorder' => [qw(
- setup_fee recur_fee recur_temporality unused_credit
+ recur_temporality
recur_method cutoff_day add_full_period
min_charge sec_granularity
default_prefix
diff --git a/FS/FS/part_pkg/voip_sqlradacct.pm b/FS/FS/part_pkg/voip_sqlradacct.pm
index 441df587b..538876712 100644
--- a/FS/FS/part_pkg/voip_sqlradacct.pm
+++ b/FS/FS/part_pkg/voip_sqlradacct.pm
@@ -16,17 +16,8 @@ $DEBUG = 1;
'disabled' => 1, #they're sucked into our CDR table now instead
'name' => 'VoIP rating by plan of CDR records in an SQL RADIUS radacct table',
'shortname' => 'VoIP/telco CDR rating (external RADIUS)',
+ 'inherit_fields' => [ 'global_Mixin' ],
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Base recurring fee for this package',
- 'default' => 0,
- },
- 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
- ' of service at cancellation',
- 'type' => 'checkbox',
- },
'ratenum' => { 'name' => 'Rate plan',
'type' => 'select',
'select_table' => 'rate',
@@ -34,7 +25,7 @@ $DEBUG = 1;
'select_label' => 'ratename',
},
},
- 'fieldorder' => [qw( setup_fee recur_fee unused_credit ratenum ignore_unrateable )],
+ 'fieldorder' => [qw( ratenum ignore_unrateable )],
'weight' => 40,
);