diff options
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/Conf.pm | 7 | ||||
-rw-r--r-- | FS/FS/part_pkg/bulk.pm | 27 | ||||
-rw-r--r-- | FS/FS/part_pkg/voip_cdr.pm | 30 |
3 files changed, 55 insertions, 9 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index b0b44e262..72e38d3d2 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2632,6 +2632,13 @@ and customer address. Include units.', }, { + 'key' => 'cust_pkg-large_pkg_size', + 'section' => 'UI', + 'description' => "In customer view, summarize packages with more than this many services. Set to zero to never summarize packages.", + 'type' => 'text', + }, + + { 'key' => 'svc_acct-edit_uid', 'section' => 'shell', 'description' => 'Allow UID editing.', diff --git a/FS/FS/part_pkg/bulk.pm b/FS/FS/part_pkg/bulk.pm index 69fe98e92..a346b9096 100644 --- a/FS/FS/part_pkg/bulk.pm +++ b/FS/FS/part_pkg/bulk.pm @@ -29,9 +29,13 @@ $me = '[FS::part_pkg::bulk]'; ' of service at cancellation', 'type' => 'checkbox', }, + 'summarize_svcs'=> { 'name' => 'Show a count of services on the invoice, '. + 'instead of a detailed list', + 'type' => 'checkbox', + }, }, 'fieldorder' => [ 'setup_fee', 'recur_fee', 'svc_setup_fee', 'svc_recur_fee', - 'unused_credit', ], + 'unused_credit', 'summarize_svcs' ], 'weight' => 50, ); @@ -50,6 +54,11 @@ sub calc_recur { unless $$sdate > $last_bill; my $total_svc_charge = 0; + my %n_setup = (); + my %n_recur = (); + my %part_svc_label = (); + + my $summarize = $self->option('summarize_svcs',1); warn "$me billing for bulk services from ". time2str('%x', $last_bill). " to ". time2str('%x', $$sdate). "\n" @@ -61,6 +70,7 @@ sub calc_recur { my @label = $h_cust_svc->label_long( $$sdate, $last_bill ); die "fatal: no historical label found, wtf?" unless scalar(@label); #? my $svc_details = $label[0]. ': '. $label[1]. ': '; + $part_svc_label{$h_cust_svc->svcpart} ||= $label[0]; my $svc_charge = 0; @@ -70,6 +80,7 @@ sub calc_recur { } elsif ( $svc_setup_fee ) { $svc_charge += $svc_setup_fee; $svc_details .= $money_char. sprintf('%.2f setup, ', $svc_setup_fee); + $n_setup{$h_cust_svc->svcpart}++; } my $svc_end = $h_cust_svc->date_deleted; @@ -85,11 +96,21 @@ sub calc_recur { if $recur_charge; $svc_charge += $recur_charge; - - push @$details, $svc_details; + $n_recur{$h_cust_svc->svcpart}++; + push @$details, $svc_details if !$summarize; $total_svc_charge += $svc_charge; } + if ( $summarize ) { + foreach my $svcpart (keys %part_svc_label) { + push @$details, sprintf('Setup fee: %d @ '.$money_char.'%.2f', + $n_setup{$svcpart}, $svc_setup_fee ) + if $svc_setup_fee and $n_setup{$svcpart}; + push @$details, sprintf('%d services @ '.$money_char.'%.2f', + $n_recur{$svcpart}, $self->option('svc_recur_fee') ) + if $n_recur{$svcpart}; + } + } sprintf('%.2f', $self->base_recur($cust_pkg) + $total_svc_charge ); } diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 9981da0c9..bcc2c6bc6 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -226,6 +226,10 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); 'type' => 'checkbox', }, + 'bill_inactive_svcs' => { 'name' => 'Bill for all phone numbers that were active during the billing period', + 'type' => 'checkbox', + }, + 'count_available_phones' => { 'name' => 'Consider for tax purposes the number of lines to be svc_phones that may be provisioned rather than those that actually are.', 'type' => 'checkbox', }, @@ -278,7 +282,7 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities(); use_duration 411_rewrite output_format usage_mandate summarize_usage usage_section - bill_every_call + bill_every_call bill_inactive_svcs count_available_phones ) ], @@ -365,11 +369,25 @@ sub calc_usage { my($svc_table, $svc_field) = split('\.', $cdr_svc_method); - foreach my $cust_svc ( - grep { $_->part_svc->svcdb eq $svc_table } $cust_pkg->cust_svc - ) { + my @cust_svc; + if( $self->option('bill_inactive_svcs',1) ) { + #XXX in this mode do we need to restrict the set of CDRs by date also? + @cust_svc = $cust_pkg->h_cust_svc($$sdate, $last_bill); + } + else { + @cust_svc = $cust_pkg->cust_svc; + } + @cust_svc = grep { $_->part_svc->svcdb eq $svc_table } @cust_svc; + + foreach my $cust_svc (@cust_svc) { - my $svc_x = $cust_svc->svc_x; + my $svc_x; + if( $self->option('bill_inactive_svcs',1) ) { + $svc_x = $cust_svc->h_svc_x($$sdate, $last_bill); + } + else { + $svc_x = $cust_svc->svc_x; + } my %options = ( 'disable_src' => $self->option('disable_src'), 'default_prefix' => $self->option('default_prefix'), @@ -709,7 +727,7 @@ sub calc_usage { if ( $charge > 0 ) { #just use FS::cust_bill_pkg_detail objects? my $call_details; - my $phonenum = $cust_svc->svc_x->phonenum; + my $phonenum = $svc_x->phonenum; if ( scalar(@call_details) == 1 ) { $call_details = |