Invalid License

License is not configured.

User Story

When a batch of CDRs is received as a file from another telco (or legacy switch), administrator wants to import them into PortaBilling so they are charged to customers. If there are any errors (e.g. someone forgot to properly create some customers in billing), he/she wants to review these, alter the configuration and re-process failed CDRs.

Use Cases

Use case #1: Mobile operator CDR batch processing - simple data transformation

Roles: Admin, Daisy mobile operator

Preconditions: Roga&Kopyta is MVNO of Daisy Telecom in UK. Connectivity between Daisy network and Roga&Kopyta's PortaBilling server is established for FTP upload.

Use scenario #1.1: CDR processing definition

Scenario:

  • Admin defines the CDR extractor instance for Daisy.

  • The example CDR file looks like this:
  • The most important part of the definition is the data transformation rules: which column contains "billed ID" (username), which one CLI, CLD and so on.

  • The file format is fairly trivial, so admin decides not to create a custom Perl module for data transformation.

  • The column structure is defined as
CSV fields
CSV_Header          = CallType,CustomerCLI,TelephoneNumber,CallDate,CallTime,Duration,Mb,Description,Time Band,Sales Price,Extension,User,Department,Country Of Origin,Network,Charge Code,Tariff,Mobile Class,Remote Network,Message Count,PN,Translation Number
  • And admin places Perl code snippets directly in the "local" configuration file for extractor, such as:

Config
PortaOne-Service-Type=return 'Voice';
User-Name=return $data{CustomerCLI} =~ m/^\d+$/ ? $data{CustomerCLI} : undef;
Called-Station-Id=my $x = $data{TelephoneNumber}; $x =~ s/^0/44/; return $x;
Acct-Session-Time=<<DURATION
    my ($h, $m, $s) = split(':', $data->{Duration});
    return undef unless defined($s);
    return $h*3600 + $m*60 + $s;
DURATION
h323-connect-time=<<CONNECTTIME
    return undef if (!$data->{CallDate} || $data->{CallDate} eq 'Call Date')
    my ($d, $m, $y) = split(/\//, $data->{CallDate});
    return "$y-$m-$d ".$data->{CallTime};
CONNECTTIME
h323-remote-address=return '3.3.3.3'; # arbitrary value to match Daisy's vendor connection 
  • Admin creates an instance of CDR rating and applies the configuration
  • Admin creates the tariff / product / connection configuration

Use scenario #1.2: CDR file processing in iterations

Scenario:

  • On Nov 16th, Daisy generates a CDR file ALLCDRS20151109-20151116.csv for all calls, made by Roga&Kopyta customers during the week of Nov 9-15. The file contains 100,000 CDR records, it is uploaded to Roga&Kopyta's PortaBilling server.

  • New file is detected and added to the processing queue (administrator can now see ALLCDRS20151109-20151116.csv with status "new" on GUI)
  • Data extraction from the file starts.
  • 1 row (the first one) does not provide valid data (User-Name is evaluated to undef), so it is marked as Skipped. The rest 99,999 rows are inserted as "todo".
  • Administrator can now see a CDR collection ALLCDRS20151109-20151116 with the status "new" and CDR statistics: 99,999 "todo", 0 "error", 1 "skipped"
  • CDR processing starts. It turns out admin did not create the latest 100 customers in PortaBilling, this results in 3000 CDRs to be rejected. The rest of CDRs are charged properly
  • Now CDR collection ALLCDRS20151109-20151116 (status processed) is shown as: 96,999 "imported", 3000 "error", 1 "skipped"
  • Admin creates missing customers and re-runs the import. Onlt the 3000 rejected CDRs are re-processed. Turns out he still missed a few customer's phone numbers, so now 400 CDRs are rejected, 2600 imported ok
  • Now CDR collection ALLCDRS20151109-20151116 is shown as: 99,599 "imported", 400 "error", 1 "skipped"
  • Admin creates missing customers and re-runs the import.
  • All if fine, now CDR collection ALLCDRS20151109-20151116 is shown as: 99,999 "imported", 0 "error", 1 "skipped"