summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorivan <ivan>2005-01-19 21:25:43 +0000
committerivan <ivan>2005-01-19 21:25:43 +0000
commite4ae5122522f2d45c68a38eaef337a82029f2fc1 (patch)
treebe86fc045972868f626731e25f5eb3f66e4cf0c2 /FS
parentfcc0d3d4015c5aae07d853b3b9f928ab9f2b12ef (diff)
credit for unused portion at cancellation, patch from pbowen
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/cust_pkg.pm34
-rw-r--r--FS/FS/part_pkg/flat.pm49
-rw-r--r--FS/FS/part_pkg/flat_comission.pm42
-rw-r--r--FS/FS/part_pkg/flat_comission_cust.pm42
-rw-r--r--FS/FS/part_pkg/flat_comission_pkg.pm58
-rw-r--r--FS/FS/part_pkg/flat_delayed.pm38
-rw-r--r--FS/FS/part_pkg/prorate.pm32
-rw-r--r--FS/FS/part_pkg/sesmon_hour.pm42
-rw-r--r--FS/FS/part_pkg/sesmon_minute.pm40
-rw-r--r--FS/FS/part_pkg/sql_external.pm46
-rw-r--r--FS/FS/part_pkg/sql_generic.pm62
-rw-r--r--FS/FS/part_pkg/sqlradacct_hour.pm74
-rw-r--r--FS/FS/part_pkg/subscription.pm28
-rw-r--r--FS/FS/part_pkg/voip_sqlradacct.pm46
14 files changed, 373 insertions, 260 deletions
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 5705ac2..56da5c7 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -376,6 +376,16 @@ sub cancel {
}
}
+ # Add a credit for remaining service
+ my $remaining_value= $self->calc_remain();
+ if ($remaining_value > 0) {
+ my $error = $self->credit($remaining_value, 'Credit for service remaining');
+ if ($error) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Error crediting customer for service remaining: $error";
+ }
+ }
+
unless ( $self->getfield('cancel') ) {
my %hash = $self->hash;
$hash{'cancel'} = time;
@@ -592,6 +602,30 @@ sub calc_recur {
$self->part_pkg->calc_recur($self, @_);
}
+=item calc_remain
+
+Calls the I<calc_remain> of the FS::part_pkg object associated with this
+billing item.
+
+=cut
+
+sub calc_recur {
+ my $self = shift;
+ $self->part_pkg->calc_remain($self, @_);
+}
+
+=item calc_cancel
+
+Calls the I<calc_cancel> of the FS::part_pkg object associated with this
+billing item.
+
+=cut
+
+sub calc_cancel {
+ my $self = shift;
+ $self->part_pkg->calc_cancel($self, @_);
+}
+
=item cust_svc [ SVCPART ]
Returns the services for this package, as FS::cust_svc objects (see
diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm
index 5721edd..131f850 100644
--- a/FS/FS/part_pkg/flat.pm
+++ b/FS/FS/part_pkg/flat.pm
@@ -10,14 +10,18 @@ use FS::part_pkg;
%info = (
'name' => 'Flat rate (anniversary billing)',
'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
+ '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',
+ },
},
- 'fieldorder' => [ 'setup_fee', 'recur_fee' ],
+ 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit' ],
#'setup' => 'what.setup_fee.value',
#'recur' => 'what.recur_fee.value',
'weight' => 10,
@@ -38,6 +42,37 @@ sub base_recur {
$self->option('recur_fee');
}
+sub calc_remain {
+ my ($self, $cust_pkg) = @_;
+ my $time = time;
+ my $next_bill = $cust_pkg->getfield('bill') || 0;
+ my $last_bill = $cust_pkg->last_bill || 0;
+ return 0 if ! $self->base_recur
+ || ! $self->option('unused_credit')
+ || ! $last_bill
+ || ! $next_bill;
+
+ my $now_date = ParseDate("epoch $time");
+ my $last_date = ParseDate("epoch $last_bill");
+ my $next_date = ParseDate("epoch $next_bill");
+ my $err;
+ my $delta = DateCalc($now_date,$next_date,\$err, 0);
+ my $days_remaining = Delta_Format($delta, 4, "%dh");
+
+ my $frequency = $self->freq;
+
+ # TODO: Remove this after the frequencies are Data::Manip friendly.
+ $frequency .= "m" unless $frequency =~ /[wd]$/;
+
+ my $freq_delta = ParseDateDelta($frequency);
+ my $days = Delta_Format($freq_delta,4,"%dh");
+
+ my $recurring= $self->base_recur;
+ my $daily = $recurring/$days;
+
+ sprintf("%.2f",($daily * $days_remaining));
+}
+
sub is_free_options {
qw( setup_fee recur_fee );
}
diff --git a/FS/FS/part_pkg/flat_comission.pm b/FS/FS/part_pkg/flat_comission.pm
index 9b288c3..21c03c2 100644
--- a/FS/FS/part_pkg/flat_comission.pm
+++ b/FS/FS/part_pkg/flat_comission.pm
@@ -8,25 +8,29 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Flat rate with recurring commission per (any) active package',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- 'comission_amount' => { 'name' => 'Commission amount per month (per active package)',
- 'default' => 0,
- },
- 'comission_depth' => { 'name' => 'Number of layers',
- 'default' => 1,
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'comission_depth', 'comission_amount' ],
- #'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,
+ 'name' => 'Flat rate with recurring commission per (any) active package',
+ '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,
+ },
+ 'comission_depth' => { 'name' => 'Number of layers',
+ 'default' => 1,
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount' ],
+ #'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,
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/flat_comission_cust.pm b/FS/FS/part_pkg/flat_comission_cust.pm
index 8aa993c..27a93ff 100644
--- a/FS/FS/part_pkg/flat_comission_cust.pm
+++ b/FS/FS/part_pkg/flat_comission_cust.pm
@@ -8,25 +8,29 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Flat rate with recurring 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,
- },
- 'comission_amount' => { 'name' => 'Commission amount per month (per active customer)',
- 'default' => 0,
- },
- 'comission_depth' => { 'name' => 'Number of layers',
- 'default' => 1,
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'comission_depth', 'comission_amount' ],
- #'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',
+ 'name' => 'Flat rate with recurring 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,
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount' ],
+ #'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',
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/flat_comission_pkg.pm b/FS/FS/part_pkg/flat_comission_pkg.pm
index befa77e..20d235c 100644
--- a/FS/FS/part_pkg/flat_comission_pkg.pm
+++ b/FS/FS/part_pkg/flat_comission_pkg.pm
@@ -8,33 +8,37 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Flat rate with recurring commission per (selected) active package',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- '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',
- 'select_hash' => { 'disabled' => '' } ,
- 'select_key' => 'pkgpart',
- 'select_label' => 'pkg',
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_fee', 'comission_depth', 'comission_amount', 'comission_pkgpart' ],
- #'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,
- 'weight' => '64',
+ 'name' => 'Flat rate with recurring commission per (selected) active package',
+ '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',
+ 'select_hash' => { 'disabled' => '' } ,
+ 'select_key' => 'pkgpart',
+ 'select_label' => 'pkg',
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'comission_pkgpart' ],
+ #'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,
+ 'weight' => '64',
);
# XXX this needs to be fixed!!!
diff --git a/FS/FS/part_pkg/flat_delayed.pm b/FS/FS/part_pkg/flat_delayed.pm
index f39783f..4a04583 100644
--- a/FS/FS/part_pkg/flat_delayed.pm
+++ b/FS/FS/part_pkg/flat_delayed.pm
@@ -8,23 +8,27 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Free (or setup fee) for X days, then flat rate'.
- ' (anniversary billing)',
- '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,
- },
- },
- 'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee' ],
- #'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' => 50,
+ 'name' => 'Free (or setup fee) for X days, then flat rate'.
+ ' (anniversary billing)',
+ '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,
+ },
+ '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' ],
+ #'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' => 50,
);
sub calc_setup {
diff --git a/FS/FS/part_pkg/prorate.pm b/FS/FS/part_pkg/prorate.pm
index d27adbd..f8a4826 100644
--- a/FS/FS/part_pkg/prorate.pm
+++ b/FS/FS/part_pkg/prorate.pm
@@ -9,20 +9,24 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'First partial month pro-rated, then flat-rate (1st of month billing)',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_fee' ],
- #'setup' => 'what.setup_fee.value',
- #'recur' => '\'my $mnow = $sdate; my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($sdate) )[0,1,2,3,4,5]; my $mstart = timelocal(0,0,0,1,$mon,$year); my $mend = timelocal(0,0,0,1, $mon == 11 ? 0 : $mon+1, $year+($mon==11)); $sdate = $mstart; ( $part_pkg->freq - 1 ) * \' + what.recur_fee.value + \' / $part_pkg->freq + \' + what.recur_fee.value + \' / $part_pkg->freq * ($mend-$mnow) / ($mend-$mstart) ; \'',
- 'freq' => 'm',
- 'weight' => 20,
+ 'name' => 'First partial month pro-rated, then flat-rate (1st of month billing)',
+ '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',
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit' ],
+ #'setup' => 'what.setup_fee.value',
+ #'recur' => '\'my $mnow = $sdate; my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($sdate) )[0,1,2,3,4,5]; my $mstart = timelocal(0,0,0,1,$mon,$year); my $mend = timelocal(0,0,0,1, $mon == 11 ? 0 : $mon+1, $year+($mon==11)); $sdate = $mstart; ( $part_pkg->freq - 1 ) * \' + what.recur_fee.value + \' / $part_pkg->freq + \' + what.recur_fee.value + \' / $part_pkg->freq * ($mend-$mnow) / ($mend-$mstart) ; \'',
+ 'freq' => 'm',
+ 'weight' => 20,
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/sesmon_hour.pm b/FS/FS/part_pkg/sesmon_hour.pm
index 1f62631..41c7f25 100644
--- a/FS/FS/part_pkg/sesmon_hour.pm
+++ b/FS/FS/part_pkg/sesmon_hour.pm
@@ -8,25 +8,29 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Base charge plus charge per-hour from the session monitor',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_flat' => { 'name' => 'Base monthly charge for this package',
- 'default' => 0,
- },
- 'recur_included_hours' => { 'name' => 'Hours included',
- 'default' => 0,
- },
- 'recur_hourly_charge' => { 'name' => 'Additional charge per hour',
- 'default' => 0,
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_flat', '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_flat.value + \' + \' + what.recur_hourly_charge.value + \' * $hours;\'',
- 'weight' => 80,
+ 'name' => 'Base charge plus charge per-hour from the session monitor',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
+ },
+ 'recur_flat' => { 'name' => 'Base monthly charge 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,
+ },
+ 'recur_hourly_charge' => { 'name' => 'Additional charge per hour',
+ 'default' => 0,
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_flat', 'unused_credit', '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_flat.value + \' + \' + what.recur_hourly_charge.value + \' * $hours;\'',
+ 'weight' => 80,
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/sesmon_minute.pm b/FS/FS/part_pkg/sesmon_minute.pm
index 86affa7..fd90235 100644
--- a/FS/FS/part_pkg/sesmon_minute.pm
+++ b/FS/FS/part_pkg/sesmon_minute.pm
@@ -8,25 +8,29 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Base charge plus charge per-minute from the session monitor',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_flat' => { 'name' => 'Base monthly charge for this package',
- 'default' => 0,
- },
- 'recur_included_min' => { 'name' => 'Minutes included',
- 'default' => 0,
- },
- 'recur_minly_charge' => { 'name' => 'Additional charge per minute',
- 'default' => 0,
+ 'name' => 'Base charge plus charge per-minute from the session monitor',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
+ },
+ 'recur_flat' => { 'name' => 'Base monthly charge 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,
},
- },
- 'fieldorder' => [ 'setup_fee', 'recur_flat', '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_flat.value + \' + \' + what.recur_minly_charge.value + \' * $min;\'',
- 'weight' => 80,
+ 'recur_minly_charge' => { 'name' => 'Additional charge per minute',
+ 'default' => 0,
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_flat', 'unused_credit', '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_flat.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 96071fa..28a4897 100644
--- a/FS/FS/part_pkg/sql_external.pm
+++ b/FS/FS/part_pkg/sql_external.pm
@@ -9,31 +9,35 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Base charge plus additional fees for external services from a configurable SQL query',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_flat' => { 'name' => 'Base monthly charge for this package',
- 'default' => 0,
- },
- 'datasrc' => { 'name' => 'DBI data source',
- 'default' => '',
+ 'name' => 'Base charge plus additional fees for external services from a configurable SQL query',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
},
- 'db_username' => { 'name' => 'Database username',
- 'default' => '',
- },
- 'db_password' => { 'name' => 'Database password',
- 'default' => '',
+ 'recur_flat' => { 'name' => 'Base monthly charge for this package',
+ 'default' => 0,
+ },
+ 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
+ ' of service at cancellation',
+ 'type' => 'checkbox',
},
- 'query' => { 'name' => 'SQL query',
+ 'datasrc' => { 'name' => 'DBI data source',
'default' => '',
},
- },
- 'fieldorder' => [qw( setup_fee recur_flat datasrc db_username db_password query )],
- #'setup' => 'what.setup_fee.value',
- #'recur' => q!'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 $price = ' + what.recur_flat.value + '; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq "svc_external" } $cust_pkg->cust_svc ){ my $id = $cust_svc->svc_x->id; $sth->execute($id) or die $sth->errstr; $price += $sth->fetchrow_arrayref->[0]; } $price;'!,
- 'weight' => '72',
+ 'db_username' => { 'name' => 'Database username',
+ 'default' => '',
+ },
+ 'db_password' => { 'name' => 'Database password',
+ 'default' => '',
+ },
+ 'query' => { 'name' => 'SQL query',
+ 'default' => '',
+ },
+ },
+ 'fieldorder' => [qw( setup_fee recur_flat unused_credit datasrc db_username db_password query )],
+ #'setup' => 'what.setup_fee.value',
+ #'recur' => q!'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 $price = ' + what.recur_flat.value + '; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq "svc_external" } $cust_pkg->cust_svc ){ my $id = $cust_svc->svc_x->id; $sth->execute($id) or die $sth->errstr; $price += $sth->fetchrow_arrayref->[0]; } $price;'!,
+ 'weight' => '72',
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/sql_generic.pm b/FS/FS/part_pkg/sql_generic.pm
index d1233e9..646957c 100644
--- a/FS/FS/part_pkg/sql_generic.pm
+++ b/FS/FS/part_pkg/sql_generic.pm
@@ -9,39 +9,43 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Base charge plus a per-domain metered rate from a configurable SQL query',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_flat' => { 'name' => 'Base monthly charge for this package',
- 'default' => 0,
- },
- 'recur_included' => { 'name' => 'Units included',
- 'default' => 0,
- },
- 'recur_unit_charge' => { 'name' => 'Additional charge per unit',
- 'default' => 0,
- },
- 'datasrc' => { 'name' => 'DBI data source',
- 'default' => '',
+ 'name' => 'Base charge plus a per-domain metered rate from a configurable SQL query',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
},
- 'db_username' => { 'name' => 'Database username',
- 'default' => '',
- },
- 'db_password' => { 'name' => 'Database username',
- 'default' => '',
+ 'recur_flat' => { 'name' => 'Base monthly charge for this package',
+ 'default' => 0,
+ },
+ 'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
+ ' of service at cancellation',
+ 'type' => 'checkbox',
},
- 'query' => { 'name' => 'SQL query',
+ 'recur_included' => { 'name' => 'Units included',
+ 'default' => 0,
+ },
+ 'recur_unit_charge' => { 'name' => 'Additional charge per unit',
+ 'default' => 0,
+ },
+ 'datasrc' => { 'name' => 'DBI data source',
'default' => '',
},
- },
- 'fieldorder' => [qw( setup_fee recur_flat 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_flat.value + \' + $units * \' + what.recur_unit_charge.value + \';\'',
- #'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_flat.value + \' + $units * \' + what.recur_unit_charge + \';\'',
- 'weight' => '70',
+ 'db_username' => { 'name' => 'Database username',
+ 'default' => '',
+ },
+ 'db_password' => { 'name' => 'Database username',
+ 'default' => '',
+ },
+ 'query' => { 'name' => 'SQL query',
+ 'default' => '',
+ },
+ },
+ 'fieldorder' => [qw( setup_fee recur_flat unused_credit 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_flat.value + \' + $units * \' + what.recur_unit_charge.value + \';\'',
+ #'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_flat.value + \' + $units * \' + what.recur_unit_charge + \';\'',
+ 'weight' => '70',
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/sqlradacct_hour.pm b/FS/FS/part_pkg/sqlradacct_hour.pm
index 76533d5..7ecb970 100644
--- a/FS/FS/part_pkg/sqlradacct_hour.pm
+++ b/FS/FS/part_pkg/sqlradacct_hour.pm
@@ -8,47 +8,51 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'Base charge plus per-hour (and for data) from an SQL RADIUS radacct table',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_flat' => { 'name' => 'Base monthly charge for this package',
- 'default' => 0,
- },
- 'recur_included_hours' => { 'name' => 'Hours included',
- 'default' => 0,
- },
- 'recur_hourly_charge' => { 'name' => 'Additional charge per hour',
- 'default' => 0,
- },
- 'recur_included_input' => { 'name' => 'Upload megabytes included',
- 'default' => 0,
- },
- 'recur_input_charge' => { 'name' =>
- 'Additional charge per megabyte upload',
+ 'name' => 'Base charge plus per-hour (and for data) from an SQL RADIUS radacct table',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
+ },
+ 'recur_flat' => { 'name' => 'Base monthly charge 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,
},
- 'recur_included_output' => { 'name' => 'Download megabytes included',
- 'default' => 0,
- },
- 'recur_output_charge' => { 'name' =>
- 'Additional charge per megabyte download',
+ 'recur_hourly_charge' => { 'name' => 'Additional charge per hour',
+ 'default' => 0,
+ },
+ 'recur_included_input' => { 'name' => 'Upload megabytes included',
'default' => 0,
},
- 'recur_included_total' => { 'name' =>
- 'Total megabytes included',
- 'default' => 0,
- },
- 'recur_total_charge' => { 'name' =>
- 'Additional charge per megabyte total',
+ 'recur_input_charge' => { 'name' =>
+ 'Additional charge per megabyte upload',
+ 'default' => 0,
+ },
+ 'recur_included_output' => { 'name' => 'Download megabytes included',
+ 'default' => 0,
+ },
+ 'recur_output_charge' => { 'name' =>
+ 'Additional charge per megabyte download',
+ 'default' => 0,
+ },
+ 'recur_included_total' => { 'name' =>
+ 'Total megabytes included',
'default' => 0,
},
- },
- 'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )],
- #'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_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'',
- 'weight' => 40,
+ 'recur_total_charge' => { 'name' =>
+ 'Additional charge per megabyte total',
+ 'default' => 0,
+ },
+ },
+ 'fieldorder' => [qw( setup_fee recur_flat unused_credit recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )],
+ #'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_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'',
+ 'weight' => 40,
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/subscription.pm b/FS/FS/part_pkg/subscription.pm
index d057b6b..e03573b 100644
--- a/FS/FS/part_pkg/subscription.pm
+++ b/FS/FS/part_pkg/subscription.pm
@@ -9,20 +9,20 @@ use FS::part_pkg;
@ISA = qw(FS::part_pkg::flat);
%info = (
- 'name' => 'First partial month full charge, then flat-rate (1st of month billing)',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_fee' => { 'name' => 'Recurring fee for this package',
- 'default' => 0,
- },
- },
- 'fieldorder' => [ 'setup_fee', 'recur_fee' ],
- #'setup' => 'what.setup_fee.value',
- #'recur' => '\'my $mnow = $sdate; my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($sdate) )[0,1,2,3,4,5]; $sdate = timelocal(0,0,0,1,$mon,$year); \' + what.recur_fee.value',
- 'freq' => 'm',
- 'weight' => 30,
+ 'name' => 'First partial month full charge, then flat-rate (1st of month billing)',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
+ },
+ 'recur_fee' => { 'name' => 'Recurring fee for this package',
+ 'default' => 0,
+ },
+ },
+ 'fieldorder' => [ 'setup_fee', 'recur_fee' ],
+ #'setup' => 'what.setup_fee.value',
+ #'recur' => '\'my $mnow = $sdate; my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($sdate) )[0,1,2,3,4,5]; $sdate = timelocal(0,0,0,1,$mon,$year); \' + what.recur_fee.value',
+ 'freq' => 'm',
+ 'weight' => 30,
);
sub calc_recur {
diff --git a/FS/FS/part_pkg/voip_sqlradacct.pm b/FS/FS/part_pkg/voip_sqlradacct.pm
index b9db39f..a6a3a38 100644
--- a/FS/FS/part_pkg/voip_sqlradacct.pm
+++ b/FS/FS/part_pkg/voip_sqlradacct.pm
@@ -7,31 +7,35 @@ use FS::part_pkg;
#use FS::rate;
use FS::rate_prefix;
-@ISA = qw(FS::part_pkg);
+@ISA = qw(FS::part_pkg::flat);
$DEBUG = 1;
%info = (
- 'name' => 'VoIP rating by plan of CDR records in an SQL RADIUS radacct table',
- 'fields' => {
- 'setup_fee' => { 'name' => 'Setup fee for this package',
- 'default' => 0,
- },
- 'recur_flat' => { 'name' => 'Base monthly charge for this package',
- 'default' => 0,
- },
- 'ratenum' => { 'name' => 'Rate plan',
- 'type' => 'select',
- 'select_table' => 'rate',
- 'select_key' => 'ratenum',
- 'select_label' => 'ratename',
- },
- 'ignore_unrateable' => { 'name' => 'Ignore calls for which not rate prefix can be found (otherwise they are fatal)',
- 'type' => 'checkbox',
- },
- },
- 'fieldorder' => [qw( setup_fee recur_flat ratenum ignore_unrateable )],
- 'weight' => 40,
+ 'name' => 'VoIP rating by plan of CDR records in an SQL RADIUS radacct table',
+ 'fields' => {
+ 'setup_fee' => { 'name' => 'Setup fee for this package',
+ 'default' => 0,
+ },
+ 'recur_flat' => { 'name' => 'Base monthly charge 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',
+ 'select_key' => 'ratenum',
+ 'select_label' => 'ratename',
+ },
+ 'ignore_unrateable' => { 'name' => 'Ignore calls for which not rate prefix can be found (otherwise they are fatal)',
+ 'type' => 'checkbox',
+ },
+ },
+ 'fieldorder' => [qw( setup_fee recur_flat unused_credit ratenum ignore_unrateable )],
+ 'weight' => 40,
);
sub calc_setup {