[freeside-commits] branch master updated. a0956b1c4c7dc4193312945353b08098106e5b48

Ivan ivan at 420.am
Mon Jun 9 17:51:27 PDT 2014


The branch, master has been updated
       via  a0956b1c4c7dc4193312945353b08098106e5b48 (commit)
      from  d88573ffdbf81830da692c49461664fc076f855d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a0956b1c4c7dc4193312945353b08098106e5b48
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Mon Jun 9 17:51:26 2014 -0700

    Wholesale CDR cost re-billing, RT#27555

diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm
index 4126d5f..3af776b 100644
--- a/FS/FS/cdr.pm
+++ b/FS/FS/cdr.pm
@@ -1049,6 +1049,31 @@ sub rate_single_price {
 
 }
 
+=item rate_cost
+
+Rates an already-rated CDR according to the cost fields from the rate plan.
+
+Returns the amount.
+
+=cut
+
+sub rate_cost {
+  my $self = shift;
+
+  return 0 unless $self->rated_ratedetailnum;
+
+  my $rate_detail =
+    qsearchs('rate_detail', { 'ratedetailnum' => $self->rated_ratedetailnum } );
+
+  return $rate_detail->min_cost if $self->rated_granularity == 0;
+
+  my $minutes = $self->rated_seconds / 60;
+  my $charge = $rate_detail->conn_cost + $minutes * $rate_detail->min_cost;
+
+  sprintf('%.2f', $charge + .00001 );
+
+}
+
 =item cdr_termination [ TERMPART ]
 
 =cut
diff --git a/FS/FS/part_pkg/agent_cdr.pm b/FS/FS/part_pkg/agent_cdr.pm
new file mode 100644
index 0000000..8c97a01
--- /dev/null
+++ b/FS/FS/part_pkg/agent_cdr.pm
@@ -0,0 +1,198 @@
+package FS::part_pkg::agent_cdr;
+use base qw( FS::part_pkg::recur_Common );
+
+#kind of glommed together from cdr_termination, agent, voip_cdr
+# some false laziness w/ all of them
+
+use strict;
+use vars qw( $DEBUG $me %info );
+use FS::Record qw( qsearch );
+use FS::PagedSearch qw( psearch );
+use FS::agent;
+use FS::cust_main;
+use FS::cdr;
+
+$DEBUG = 0;
+
+$me = '[FS::part_pkg::agent_cdr]';
+
+%info = (
+  'name'      => 'Wholesale CDR cost billing, for master customers of an agent.',
+  'shortname' => 'Whilesale CDR cost billing for agent.',
+  'inherit_fields' => [ 'prorate_Mixin', 'global_Mixin' ],
+  'fields' => { #false laziness w/cdr_termination
+
+    #false laziness w/flat.pm
+    'recur_temporality' => { 'name' => 'Charge recurring fee for period',
+                             'type' => 'select',
+                             'select_options' => \%temporalities,
+                           },
+
+    'cutoff_day'    => { 'name' => 'Billing Day (1 - 28) for prorating or '.
+                                   'subscription',
+                         'default' => '1',
+                       },
+    'recur_method'  => { 'name' => 'Recurring fee method',
+                         #'type' => 'radio',
+                         #'options' => \%recur_method,
+                         'type' => 'select',
+                         'select_options' => \%FS::part_pkg::recur_Common::recur_method,
+                       },
+
+    #false laziness w/voip_cdr.pm
+    'output_format' => { 'name' => 'CDR invoice display format',
+                         'type' => 'select',
+                         'select_options' => { FS::cdr::invoice_formats() },
+                         'default'        => 'simple2', #XXX test
+                       },
+
+    'usage_section' => { 'name' => 'Section in which to place separate usage charges',
+                       },
+
+    'summarize_usage' => { 'name' => 'Include usage summary with recurring charges when usage is in separate section',
+                          'type' => 'checkbox',
+                        },
+
+    'usage_mandate' => { 'name' => 'Always put usage details in separate section',
+                          'type' => 'checkbox',
+                       },
+    #eofalse
+
+  },
+
+  'fieldorder' => [ qw( recur_temporality recur_method cutoff_day ),
+                    FS::part_pkg::prorate_Mixin::fieldorder, 
+                    qw(
+                       output_format usage_section summarize_usage usage_mandate
+                    )
+                  ],
+
+  'weight' => 53,
+
+);
+
+sub calc_recur {
+  my $self, $cust_pkg, $sdate, $details, $param ) = @_;
+
+  #my $last_bill = $cust_pkg->last_bill;
+  my $last_bill = $cust_pkg->get('last_bill'); #->last_bill falls back to setup
+
+  return 0
+    if $self->recur_temporality eq 'preceding'
+    && ( $last_bill eq '' || $last_bill == 0 );
+
+  my $charges = 0;
+
+  #CDR calculations
+
+  #false laziness w/agent.pm
+  #almost always just one,
+  #unless you have multiple agents with same master customer0
+  my @agents = qsearch('agent', { 'agent_custnum' => $cust_pkg->custnum } );
+
+  foreach my $agent (@agents) {
+
+    warn "$me billing wholesale CDRs for agent ". $agent->agent. "\n"
+      if $DEBUG;
+
+    #not the most efficient to load them all into memory,
+    #but good enough for our current needs
+    my @cust_main = qsearch('cust_main', { 'agentnum' => $agent->agentnum } );
+
+    foreach my $cust_main (@cust_main) {
+
+      warn "$me billing agent wholesale CDRs for ". $cust_main->name_short. "\n"
+        if $DEBUG;
+
+      #eofalse laziness w/agent.pm
+
+      my @svcnum = ();
+      foreach my $cust_pkg ( $cust_main->cust_pkg ) {
+        push @svcnum, map $_->svcnum, $cust_pkg->cust_svc( svcdb=>'svc_phone' );
+      }
+
+      next unless @svcnum;
+
+      #false laziness w/cdr_termination
+
+      my $termpart = 1; #or from an option -- we're not termination, we're wholesale?  for now, use one or the other
+
+      #false lazienss w/search/cdr.html (i should be a part_termination method)
+      my $where_term =
+        "( cdr.acctid = cdr_termination.acctid AND termpart = $termpart ) ";
+      #my $join_term = "LEFT JOIN cdr_termination ON ( $where_term )";
+      my $extra_sql =
+        "AND NOT EXISTS ( SELECT 1 FROM cdr_termination WHERE $where_term )";
+
+      #eofalse laziness w/cdr_termination.pm
+
+      #false laziness w/ svc_phone->psearch_cdrs, kinda
+      my $cdr_search = psearch({
+        'table'     => 'cdr',
+        #'addl_from' => $join_term,
+        'hashref'   => {},
+        'extra_sql' => " WHERE freesidestatus IN ( 'rated', 'done' ) ".
+                       "   AND svcnum IN (". join(',', @svcnum). ") ".
+                       $extra_sql,
+        'order_by'  => 'ORDER BY startdate FOR UPDATE ',
+
+      });
+
+      #false laziness w/voip_cdr
+      $cdr_search->limit(1000);
+      $cdr_search->increment(0); #because we're adding cdr_termination as we go?
+      while ( my $cdr = $cdr_search->fetch ) {
+
+        my $cost = $cdr->rate_cost;
+        #XXX exception handling?  return undef? (and err?) ref to a scalar err?
+
+        #false laziness w/cdr_termination
+
+        #add a cdr_termination record and the charges
+
+        my $cdr_termination = new FS::cdr_termination {
+          'acctid'      => $cdr->acctid,
+          'termpart'    => $termpart,
+          'rated_price' => $cost,
+          'status'      => 'done',
+        };
+
+        my $error = $cdr_termination->insert;
+        die $error if $error; #next if $error; #or just skip this one???  why?
+
+        $charges += $cost;
+
+        # and add a line to the invoice
+
+        my $call_details = $cdr->downstream_csv( 'format' => $output_format,
+                                                 'charge' => $cost,
+                                               );
+        my $classnum = ''; #usage class?
+
+       #option to turn off?  or just use squelch_cdr for the customer probably
+        push @$details, [ 'C', $call_details, $cost, $classnum ];
+
+        #eofalse laziness w/cdr_termination
+
+      }
+
+    }
+
+  }
+
+  #eo CDR calculations
+
+  $charges += ($cust_pkg->quantity || 1) * $self->calc_recur_Common(@_);
+
+  $charges;
+}
+
+sub can_discount { 0; }
+
+#?  sub hide_svc_detail { 1; }
+
+sub is_free { 0; }
+
+sub can_usageprice { 0; }
+
+1;

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/cdr.pm                |   25 ++++++
 FS/FS/part_pkg/agent_cdr.pm |  198 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 223 insertions(+)
 create mode 100644 FS/FS/part_pkg/agent_cdr.pm




More information about the freeside-commits mailing list