Overview

The Unbound Billing process has a number of components that we’d like to test. Some of them are:

  • CDR - get them
  • Emails - send them
  • Taxes - compute them
  • Charges - compute them

CDR Tests - fetch_inphonex_cdr.pl

The call data records (CDR) are obtained from Inphonex1. This is done via the script fetch_inphonex_cdr.pl

Key Modules Used

This script uses the following F modules.

Inphonex

This module in employed to get the call detail records. In particular the list_plan_calls() method

list_plan_calls()

This method in turn uses the service method of F::Inphonex that in turn uses the service, uri and proxy methods of F:SOAP::Lite to return a service for us to query. They key feature for Iphonex service method is defined as such:

sub service {
    my ( $self$type ) = @_;
# ...
    my %services = (
# ... 
        call => { area => 'Calls', name => 'Call', short => 1 },

    );
    my ($area$svc$short) = @{$services{lc $type}}{qw( area name short )};
    my $service_str = $short ? "/$area/$svc.php?wsdl" : "/$area/$svc/$svc.php?wsdl" ;
    my $service = 
          F::SOAP::Lite->service(BASE . $service_str)
                       ->uri("http://$svc")
                       ->proxy(BASE . $service_str, timeout => 300);

    return $self->{_last_service} = $service;
}

We then use the call method of the SOAP $service object with list_plan_calls to make the query which look like:

sub list_plan_calls {
    my ($self%p) = @_;

    my $service = $self->service('call');
    my ($start_row$limit@calls) = (0, 100);

    $result = $service->call(
        'ListCalls' => F::SOAP::Data->value(
            F::SOAP::Data->name('StateId'   => $$self{StateId}),
            F::SOAP::Data->name('StartDate' => $p{StartDate}),
            F::SOAP::Data->name('EndDate'   => $p{EndDate}),
            F::SOAP::Data->name(
                'CallSearch' => {
                    'start_row'   => $start_row,
                    'limit'       => $limit,
                    'customer_id' => $p{InphonexCid},
                }
            )
        )
    );
# ...
    my $total_rows = $result->result->{'total_rows'};
    my $calls      = $result->result->{'calls'};
    push(@calls$calls);

    # if we got all the calls in one simple request
    if ($total_rows && ($limit > $total_rows)) {
        @calls = &flatten(\@calls);
         $$self{ListPlanCalls} = \@calls;
    }
# handle mutliple requests ...
}

Call Detail Example

Here we have the details for two calls. Note that one is under the FONALITY NOMLIMITED plan while the other has a plan_name that’s empty.

[
    {
        disposition             => 'ANSWERED',
        did                     => '2062747054',
        country_code            => 'US',
        billable_duration       => '3',
        call_duration           => '3',
        customer_id             => '1048163',
        ani                     => '8003702139',
        destination_description => '',
        plan_name               => '',
        called_number           => '4460600',
        call_date               => '2010-03-09 12:22:30',
        virtual_number          => '4460600',
        unique_id               => '3dc6c54d60404c04ba4cae7dd1cd5afe',
        call_cost               => '0'
    },
    {
        disposition  => 'ANSWERED',
        did          => '',
        country_code => 'US',
        prepays      => [
            {
                amount => '0.0254',
                id     => '388889'
            },
            {
                amount => '0.0254',
                id     => '413787'
            }
        ],
        billable_duration       => '19',
        call_duration           => '25',
        customer_id             => '1045767',
        ani                     => '4247318400',
        destination_description => '',
        plan_name               => 'FONALITY NOMLIMITED',
        called_number           => '14243547833',
        call_date               => '2010-03-08 21:28:03',
        virtual_number          => '8727702',
        unique_id               => '93dde550f5b04ec093d4ecdd7559717c',
        call_cost               => '0.0254'
    }
];

Modules Continued..

  • Unbound
  • Util
  • Mail
  • Customer
  • Contact

along with the Perl modules:

  • Data::Dumper
  • Getopt::Std

Subroutines

The following subroutines are defined in fetch_inphonex_cdr.pl:

  • check_threshold
  • is_mobile
  • make_mobile_hash
  • send_error

check_threshold

Arguments

my ($sid,$reg_mins,$tollfree_mins,$start,$end) = @_;

Queries

There are a few queries that perform the following functions

get the number of seats - $get_seat_no

select sum(quantity) 
  from live_invoice_items 
 where item_id in ($seat_ids) 
   and server_id = ?

where:

$seat_ids = '1080,1082,1084,1279';

get the number of tollfree seats - $get_tollfree_seat

select count(*) 
  from devices 
 where name like 'SIP/%'
   and server_id = ?;

insert the threshold

insert into unbound_cdr_thresholds 
(server_id, threshold_mins, tollfree_mins, updated) 
values(?,?,?,now())

get server, customer, and inphonex ids of Unbound customers

my $sql =<<'END_SQL';
select distinct(s.server_id), c.inphonex_id, 
       c.inphonex_reseller_id, co.first_name, co.last_name 
  from server s join customer c 
    on (s.customer_id = c.customer_id)
  join contact co 
    on (c.customer_id = co.customer_id)
 where (inphonex_id > 0 or inphonex_id IS NOT NULL)
   and c.customer_id not in ($test_customer_ids)
END_SQL

if($server_id)
  {
    $sql .= "and s.server_id = $server_id ";
  }

$sql .= 'order by s.server_id';
my $get_ids = $dbh->prepare($sql);
$get_ids->execute();

Footnotes

1 This will change when we offer service to Australia. Fonality proxy servers will store the CDRs.

My tags:
 
Popular tags:
 
Powered by MojoMojo