From 90dfd05877a331fb13ba50389e3d8a3105465bc7 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 17 Jun 2011 09:47:04 +0000 Subject: [PATCH] add prorate options to recur_Common packages, #10630 --- FS/FS/part_pkg.pm | 7 ++++++- FS/FS/part_pkg/cdr_termination.pm | 18 ++++-------------- FS/FS/part_pkg/flat.pm | 12 ++++++++++-- FS/FS/part_pkg/prorate.pm | 4 ++-- FS/FS/part_pkg/prorate_Mixin.pm | 30 +++++++++++++++++++++++++++++- FS/FS/part_pkg/recur_Common.pm | 7 +++++++ FS/FS/part_pkg/sql_external.pm | 11 ++++------- FS/FS/part_pkg/voip_cdr.pm | 16 ++++------------ FS/FS/part_pkg/voip_inbound.pm | 16 ++++------------ 9 files changed, 70 insertions(+), 51 deletions(-) diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index f75416712..1981d63df 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -1630,6 +1630,10 @@ foreach my $name (keys(%info)) { my $parents = $info{$name}->{'inherit_fields'} || []; my (%fields, %field_exists, @fieldorder); foreach my $parent ($name, @$parents) { + if ( !exists($info{$parent}) ) { + warn "$name tried to inherit from nonexistent '$parent'\n"; + next; + } %fields = ( # avoid replacing existing fields %{ $info{$parent}->{'fields'} || {} }, %fields @@ -1639,7 +1643,8 @@ foreach my $name (keys(%info)) { next if $field_exists{$_}; $field_exists{$_} = 1; # allow inheritors to remove inherited fields from the fieldorder - push @fieldorder, $_ if !exists($fields{$_}->{'disabled'}); + push @fieldorder, $_ if !exists($fields{$_}) or + !exists($fields{$_}->{'disabled'}); } } $plans{$name}->{'fields'} = \%fields; diff --git a/FS/FS/part_pkg/cdr_termination.pm b/FS/FS/part_pkg/cdr_termination.pm index 3723629aa..37fa47e98 100644 --- a/FS/FS/part_pkg/cdr_termination.pm +++ b/FS/FS/part_pkg/cdr_termination.pm @@ -16,7 +16,7 @@ tie my %temporalities, 'Tie::IxHash', %info = ( 'name' => 'VoIP rating of CDR records for termination partners.', 'shortname' => 'VoIP/telco CDR termination', - 'inherit_fields' => [ 'global_Mixin' ], + 'inherit_fields' => [ 'prorate_Mixin', 'global_Mixin' ], 'fields' => { #'cdr_column' => { 'name' => 'Column from CDR records', # 'type' => 'select', @@ -46,11 +46,6 @@ tie my %temporalities, 'Tie::IxHash', 'subscription', 'default' => '1', }, - 'add_full_period'=> { 'name' => 'When prorating first month, also bill '. - 'for one full period after that', - 'type' => 'checkbox', - }, - 'recur_method' => { 'name' => 'Recurring fee method', #'type' => 'radio', #'options' => \%recur_method, @@ -79,9 +74,9 @@ tie my %temporalities, 'Tie::IxHash', }, #cdr_column - 'fieldorder' => [qw( - recur_temporality recur_method cutoff_day - add_full_period + 'fieldorder' => [qw( recur_temporality recur_method cutoff_day ), + FS::part_pkg::prorate_Mixin::fieldorder, + qw( output_format usage_section summarize_usage usage_mandate ) ], @@ -90,11 +85,6 @@ tie my %temporalities, 'Tie::IxHash', ); -sub calc_setup { - my($self, $cust_pkg ) = @_; - $self->option('setup_fee'); -} - sub calc_recur { my $self = shift; my($cust_pkg, $sdate, $details, $param ) = @_; diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm index e7220f6b3..c1690f87d 100644 --- a/FS/FS/part_pkg/flat.pm +++ b/FS/FS/part_pkg/flat.pm @@ -25,7 +25,7 @@ tie my %contract_years, 'Tie::IxHash', ( %info = ( 'name' => 'Flat rate (anniversary billing)', 'shortname' => 'Anniversary', - 'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ], + 'inherit_fields' => [ 'prorate_Mixin', 'usage_Mixin', 'global_Mixin' ], 'fields' => { #false laziness w/voip_cdr.pm 'recur_temporality' => { 'name' => 'Charge recurring fee for period', @@ -56,6 +56,13 @@ tie my %contract_years, 'Tie::IxHash', ( 'the customer\'s next bill date', 'type' => 'checkbox', }, + 'prorate_round_day' => { + 'name' => 'When synchronizing, round the prorated '. + 'period to the nearest full day', + 'type' => 'checkbox', + }, + 'add_full_period' => { 'disabled' => 1 }, # doesn't make sense with sync? + 'suspend_bill' => { 'name' => 'Continue recurring billing while suspended', 'type' => 'checkbox', }, @@ -72,7 +79,8 @@ tie my %contract_years, 'Tie::IxHash', ( 'fieldorder' => [ qw( recur_temporality expire_months adjourn_months contract_end_months - start_1st sync_bill_date prorate_defer_bill + start_1st + sync_bill_date prorate_defer_bill prorate_round_day suspend_bill unsuspend_adjust_bill externalid ), ], diff --git a/FS/FS/part_pkg/prorate.pm b/FS/FS/part_pkg/prorate.pm index fb76f904a..a0f579f73 100644 --- a/FS/FS/part_pkg/prorate.pm +++ b/FS/FS/part_pkg/prorate.pm @@ -24,8 +24,8 @@ use FS::part_pkg::flat; 'type' => 'checkbox', }, 'prorate_round_day'=> { - 'name' => 'When prorating first month, round to '. - 'the nearest full day', + 'name' => 'Round the prorated period to the nearest '. + 'full day', 'type' => 'checkbox', }, 'prorate_defer_bill'=> { diff --git a/FS/FS/part_pkg/prorate_Mixin.pm b/FS/FS/part_pkg/prorate_Mixin.pm index 6d0c2dad4..75dbe5cf8 100644 --- a/FS/FS/part_pkg/prorate_Mixin.pm +++ b/FS/FS/part_pkg/prorate_Mixin.pm @@ -7,8 +7,30 @@ use Time::Local qw(timelocal); @ISA = qw(FS::part_pkg); %info = ( 'disabled' => 1, + # define all fields that are referenced in this code + 'fields' => { + 'add_full_period' => { + 'name' => 'When prorating first month, also bill for one full '. + 'period after that', + 'type' => 'checkbox', + }, + 'prorate_round_day' => { + 'name' => 'When prorating, round to the nearest full day', + 'type' => 'checkbox', + }, + 'prorate_defer_bill' => { + 'name' => 'When prorating, defer the first bill until the '. + 'billing day', + 'type' => 'checkbox', + }, + }, + 'fieldorder' => [ qw(prorate_defer_bill prorate_round_day add_full_period) ], ); +sub fieldorder { + @{ $info{'fieldorder'} } +} + =head1 NAME FS::part_pkg::prorate_Mixin - Mixin class for part_pkg:: classes that @@ -134,7 +156,13 @@ sub _endpoints { # only works for freq >= 1 month; probably can't be fixed my ($sec, $min, $hour, $mday, $mon, $year) = (localtime($mnow))[0..5]; if( $self->option('prorate_round_day',1) ) { - $mday++ if $hour >= 12; + # If the time is 12:00-23:59, move to the next day by adding 18 + # hours to $mnow. Because of DST this can end up from 05:00 to 18:59 + # but it's always within the next day. + $mnow += 64800 if $hour >= 12; + # Get the new day, month, and year. + ($mday,$mon,$year) = (localtime($mnow))[3..5]; + # Then set $mnow to midnight on that day. $mnow = timelocal(0,0,0,$mday,$mon,$year); } my $mend; diff --git a/FS/FS/part_pkg/recur_Common.pm b/FS/FS/part_pkg/recur_Common.pm index 719fb234e..48e9307c4 100644 --- a/FS/FS/part_pkg/recur_Common.pm +++ b/FS/FS/part_pkg/recur_Common.pm @@ -19,6 +19,13 @@ sub base_recur { $self->option('recur_fee', 1) || 0; } +sub calc_setup { + # moved from all descendant packages which just had $self->option('setup_fee') + my($self, $cust_pkg, $sdate, $details, $param) = @_; + return 0 if $self->prorate_setup($cust_pkg, $sdate); + $self->option('setup_fee'); +} + sub cutoff_day { # prorate/subscription only; we don't support sync_bill_date here my $self = shift; diff --git a/FS/FS/part_pkg/sql_external.pm b/FS/FS/part_pkg/sql_external.pm index c0c57251b..08142b019 100644 --- a/FS/FS/part_pkg/sql_external.pm +++ b/FS/FS/part_pkg/sql_external.pm @@ -9,16 +9,12 @@ 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' ], + 'inherit_fields' => [ 'prorate_Mixin', 'global_Mixin' ], 'fields' => { 'cutoff_day' => { 'name' => 'Billing Day (1 - 28) for prorating or '. 'subscription', 'default' => '1', }, - 'add_full_period'=> { 'name' => 'When prorating first month, also bill '. - 'for one full period after that', - 'type' => 'checkbox', - }, 'recur_method' => { 'name' => 'Recurring fee method', #'type' => 'radio', @@ -39,8 +35,9 @@ use DBI; 'default' => '', }, }, - 'fieldorder' => [qw( recur_method cutoff_day - add_full_period datasrc db_username db_password query + 'fieldorder' => [qw( recur_method cutoff_day ), + FS::part_pkg::prorate_Mixin::fieldorder, + qw( datasrc db_username db_password query )], 'weight' => '58', ); diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 158debdcf..836387325 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -46,7 +46,7 @@ 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' ], + 'inherit_fields' => [ 'prorate_Mixin', 'global_Mixin' ], 'fields' => { 'suspend_bill' => { 'name' => 'Continue recurring billing while suspended', 'type' => 'checkbox', @@ -61,10 +61,6 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); 'subscription', 'default' => '1', }, - 'add_full_period'=> { 'name' => 'When prorating first month, also bill '. - 'for one full period after that', - 'type' => 'checkbox', - }, 'recur_method' => { 'name' => 'Recurring fee method', #'type' => 'radio', #'options' => \%recur_method, @@ -259,8 +255,9 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); }, 'fieldorder' => [qw( recur_temporality - recur_method cutoff_day - add_full_period + recur_method cutoff_day ), + FS::part_pkg::prorate_Mixin::fieldorder, + qw( cdr_svc_method rating_method ratenum intrastate_ratenum min_charge min_included @@ -299,11 +296,6 @@ sub price_info { $str; } -sub calc_setup { - my($self, $cust_pkg ) = @_; - $self->option('setup_fee'); -} - sub calc_recur { my $self = shift; my($cust_pkg, $sdate, $details, $param ) = @_; diff --git a/FS/FS/part_pkg/voip_inbound.pm b/FS/FS/part_pkg/voip_inbound.pm index 7b80e028c..a96e9787c 100644 --- a/FS/FS/part_pkg/voip_inbound.pm +++ b/FS/FS/part_pkg/voip_inbound.pm @@ -24,7 +24,7 @@ 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' ], + 'inherit_fields' => [ 'prorate_Mixin', 'global_Mixin' ], 'fields' => { #false laziness w/flat.pm 'recur_temporality' => { 'name' => 'Charge recurring fee for period', @@ -35,10 +35,6 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); 'subscription', 'default' => '1', }, - 'add_full_period'=> { 'name' => 'When prorating first month, also bill '. - 'for one full period after that', - 'type' => 'checkbox', - }, 'recur_method' => { 'name' => 'Recurring fee method', 'type' => 'select', @@ -148,8 +144,9 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); }, 'fieldorder' => [qw( recur_temporality - recur_method cutoff_day add_full_period - min_charge min_included sec_granularity + recur_method cutoff_day ), + FS::part_pkg::prorate_Mixin::fieldorder, + qw( min_charge min_included sec_granularity default_prefix disable_tollfree use_amaflags @@ -173,11 +170,6 @@ sub price_info { $str; } -sub calc_setup { - my($self, $cust_pkg ) = @_; - $self->option('setup_fee'); -} - sub calc_recur { my $self = shift; my($cust_pkg, $sdate, $details, $param ) = @_; -- 2.11.0