add skip_dcontext_suffix to skip CDRs with dcontext ending in a definable string...
[freeside.git] / FS / FS / part_pkg / voip_cdr.pm
index 7e21b0f..0ff4e54 100644 (file)
@@ -10,9 +10,6 @@ use FS::Conf;
 use FS::Record qw(qsearchs qsearch);
 use FS::cdr;
 use FS::detail_format;
-#use FS::rate;
-#use FS::rate_prefix;
-#use FS::rate_detail;
 
 $DEBUG = 0;
 
@@ -22,6 +19,7 @@ tie my %cdr_svc_method, 'Tie::IxHash',
   'svc_pbx.svcnum'     => 'Freeside service # (svc_pbx.svcnum)',
   'svc_pbx.ip.src'     => 'PBX name to source IP address',
   'svc_pbx.ip.dst'     => 'PBX name to destination IP address',
+  'svc_acct.username'  => 'Username (svc_acct.username)',
 ;
 
 tie my %rating_method, 'Tie::IxHash',
@@ -108,19 +106,13 @@ tie my %accountcode_tollfree_field, 'Tie::IxHash',
                   },
 
     'ratenum'   => { 'name' => 'Rate plan',
-                     'type' => 'select',
-                     'select_table' => 'rate',
-                     'select_key'   => 'ratenum',
-                     'select_label' => 'ratename',
+                     'type' => 'select-rate',
                    },
                    
     'intrastate_ratenum'   => { 'name' => 'Optional alternate intrastate rate plan',
-                     'type' => 'select',
-                     'select_table' => 'rate',
-                     'select_key'   => 'ratenum',
-                     'select_label' => 'ratename',
+                     'type' => 'select-rate',
                      'disable_empty' => 0,
-                     'empty_label'   => '',
+                     'empty_label'   => ' ',
                    },
 
     'calls_included' => { 'name' => 'Number of calls included at no usage charge', },
@@ -157,7 +149,7 @@ tie my %accountcode_tollfree_field, 'Tie::IxHash',
 #                                    'type' => 'checkbox',
 #                                  },
 
-    'international_prefix' => { 'name'    => 'Destination prefix for international CDR records',
+    'international_prefix' => { 'name'    => 'Destination prefix for international CDR records (or "none" for no prefix)',
                                 'default' => '011',
                               },
 
@@ -193,7 +185,10 @@ tie my %accountcode_tollfree_field, 'Tie::IxHash',
     'skip_dst_prefix' => { 'name' => 'Do not charge for CDRs where the destination number starts with any of these values: ',
     },
 
-    'skip_dcontext' => { 'name' => 'Do not charge for CDRs where the dcontext is set to any of these (comma-separated) values: ',
+    'skip_dcontext' => { 'name' => 'Do not charge for CDRs where dcontext is set to any of these (comma-separated) values: ',
+                       },
+
+    'skip_dcontext_suffix' => { 'name' => 'Do not charge for CDRs where dcontext ends with: ',
                        },
 
     'skip_dstchannel_prefix' => { 'name' => 'Do not charge for CDRs where the dstchannel starts with:',
@@ -290,6 +285,9 @@ tie my %accountcode_tollfree_field, 'Tie::IxHash',
     'bill_inactive_svcs' => { 'name' => 'Bill for all phone numbers that were active during the billing period',
                               'type' => 'checkbox',
                             },
+    'bill_only_pkg_dates' => { 'name' => 'Only bill CDRs with a date during the package 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',
@@ -353,6 +351,7 @@ tie my %accountcode_tollfree_field, 'Tie::IxHash',
                        selfservice_format selfservice_inbound_format
                        usage_mandate usage_section summarize_usage 
                        usage_showzero bill_every_call bill_inactive_svcs
+                       bill_only_pkg_dates
                        count_available_phones suspend_bill 
                      )
                   ],
@@ -405,8 +404,10 @@ sub calc_usage {
   my $included_min = $self->option('min_included', 1) || 0;
     #single price rating
     #or region group
+  $included_min *= ($cust_pkg->quantity || 1);
 
   my $included_calls = $self->option('calls_included', 1) || 0;
+  $included_calls *= ($cust_pkg->quantity || 1);
 
   my $cdr_svc_method    = $self->option('cdr_svc_method',1)||'svc_phone.phonenum';
   my $rating_method     = $self->option('rating_method') || 'prefix';
@@ -461,18 +462,34 @@ sub calc_usage {
         'calltypenum'    => $self->option('use_calltypenum',1),
         'status'         => '',
         'for_update'     => 1,
-      );  # $last_bill, $$sdate )
+    );
+    if ( $self->option('bill_only_pkg_dates') ) {
+      $options{'begin'} = $last_bill;
+      $options{'end'}   = $$sdate;
+    }
     if ( $svc_field eq 'svcnum' ) {
       $options{'by_svcnum'} = 1;
-    }
-    elsif ($svc_table eq 'svc_pbx' and $svc_field eq 'ip') {
+    } elsif ($svc_table eq 'svc_pbx' and $svc_field eq 'ip') {
       $options{'by_ip_addr'} = $by_ip_addr;
     }
 
     #my @invoice_details_sort;
 
+    # for tagging invoice details
+    # (unfortunate; should be a svc_x class method or table_info item or 
+    # something)
+    my $phonenum;
+    if ( $svc_table eq 'svc_phone' ) {
+      $phonenum = $svc_x->phonenum;
+    } elsif ( $svc_table eq 'svc_pbx' ) {
+      $phonenum = $svc_x->title;
+    } elsif ( $svc_table eq 'svc_acct' ) {
+      $phonenum = $svc_x->username;
+    }
+    $formatter->phonenum($phonenum);
+
     #first rate any outstanding CDRs not yet rated
-    # XXX eventually use an FS::Cursor for this
+    # use FS::Cursor for this starting in 4.x
     my $cdr_search = $svc_x->psearch_cdrs(%options);
     $cdr_search->limit(1000);
     $cdr_search->increment(0); # because we're changing their status as we go
@@ -574,6 +591,11 @@ sub check_chargable {
     if $self->option_cacheable('skip_dcontext') =~ /\S/
     && grep { $cdr->dcontext eq $_ } split(/\s*,\s*/, $self->option_cacheable('skip_dcontext'));
 
+  my $len_suffix = length($self->option_cacheable('skip_dcontext_suffix'));
+  return "dcontext ends with ". $self->option_cacheable('skip_dcontext_suffix')
+    if $len_suffix
+    && substr($cdr->dcontext,-$len_suffix,$len_suffix) eq $self->option_cacheable('skip_dcontext_suffix');
+
   my $len_prefix = length($self->option_cacheable('skip_dstchannel_prefix'));
   return "dstchannel starts with ". $self->option_cacheable('skip_dstchannel_prefix')
     if $len_prefix
@@ -652,7 +674,8 @@ sub reset_usage {
                 FS::cust_pkg_usage->new({
                     'pkgnum'        => $cust_pkg->pkgnum,
                     'pkgusagepart'  => $part,
-                    'minutes'       => $part_pkg_usage->minutes,
+                    'minutes'       => $part_pkg_usage->minutes *
+                                        ($cust_pkg->quantity || 1),
                 });
     foreach my $cdr_usage (
       qsearch('cdr_cust_pkg_usage', {'cdrusagenum' => $usage->cdrusagenum})
@@ -678,6 +701,7 @@ sub reset_usage {
 
 # tells whether cust_bill_pkg_detail should return a single line for 
 # each phonenum
+# i think this is currently unused?
 sub sum_usage {
   my $self = shift;
   $self->option('output_format') =~ /^sum_/;