summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2013-01-13 19:01:13 -0800
committerIvan Kohler <ivan@freeside.biz>2013-01-13 19:01:13 -0800
commita62346b3ac1f66ffbf12d109c9da186c8d0ca576 (patch)
treebc914cb015aa408d3f9ffb26587e44f785ac82b4
parente722e522c695781f626adfdf36bf0d130698f665 (diff)
GSM TAP3.12 import, RT#20767
-rw-r--r--FS/FS/Record.pm5
-rw-r--r--FS/FS/Schema.pm2
-rw-r--r--FS/FS/cdr/gsm_tap3_12.pm107
3 files changed, 89 insertions, 25 deletions
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index 252b760bf..d24401301 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -1618,6 +1618,7 @@ sub batch_import {
my $count;
my $parser;
my @buffer = ();
+ my $asn_header_buffer;
if ( $type eq 'csv' || $type eq 'fixedlength' ) {
if ( $type eq 'csv' ) {
@@ -1692,6 +1693,8 @@ sub batch_import {
my $asn_output = $parser->decode( $data )
or die "No ". $asn_format->{'macro'}. " found\n";
+ $asn_header_buffer = &{ $asn_format->{'header_buffer'} }( $asn_output );
+
my $rows = &{ $asn_format->{'arrayref'} }( $asn_output );
$count = @buffer = @$rows;
@@ -1786,7 +1789,7 @@ sub batch_import {
last unless scalar(@buffer);
my $row = shift @buffer;
foreach my $key ( keys %{ $asn_format->{map} } ) {
- $hash{$key} = &{ $asn_format->{map}{$key} }( $row );
+ $hash{$key} = &{ $asn_format->{map}{$key} }( $row, $asn_header_buffer );
}
} else {
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 19edc25a9..f6dfe4d7a 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -3364,7 +3364,7 @@ sub tables_hashref {
'rated_classnum', 'int', 'NULL', '', '', '',
'rated_ratename', 'varchar', 'NULL', $char_d, '', '',
- 'carrierid', 'int', 'NULL', '', '', '',
+ 'carrierid', 'bigint', 'NULL', '', '', '',
# service it was matched to
'svcnum', 'int', 'NULL', '', '', '',
diff --git a/FS/FS/cdr/gsm_tap3_12.pm b/FS/FS/cdr/gsm_tap3_12.pm
index 8f50690bd..dbf83d0ed 100644
--- a/FS/FS/cdr/gsm_tap3_12.pm
+++ b/FS/FS/cdr/gsm_tap3_12.pm
@@ -2,10 +2,39 @@ package FS::cdr::gsm_tap3_12;
use base qw( FS::cdr );
use strict;
-use vars qw( %info );
+use vars qw( %info %TZ );
use Time::Local;
use Data::Dumper;
+%TZ = (
+ '+0000' => 'XXX-0',
+ '+0100' => 'XXX-1',
+ '+0200' => 'XXX-2',
+ '+0300' => 'XXX-3',
+ '+0400' => 'XXX-4',
+ '+0500' => 'XXX-5',
+ '+0600' => 'XXX-6',
+ '+0700' => 'XXX-7',
+ '+0800' => 'XXX-8',
+ '+0900' => 'XXX-9',
+ '+1000' => 'XXX-10',
+ '+1100' => 'XXX-11',
+ '+1200' => 'XXX-12',
+ '-0000' => 'XXX+0',
+ '-0100' => 'XXX+1',
+ '-0200' => 'XXX+2',
+ '-0300' => 'XXX+3',
+ '-0400' => 'XXX+4',
+ '-0500' => 'XXX+5',
+ '-0600' => 'XXX+6',
+ '-0700' => 'XXX+7',
+ '-0800' => 'XXX+8',
+ '-0900' => 'XXX+9',
+ '-1000' => 'XXX+10',
+ '-1100' => 'XXX+11',
+ '-1200' => 'XXX+12',
+);
+
%info = (
'name' => 'GSM TAP3 release 12',
'weight' => 50,
@@ -14,29 +43,60 @@ use Data::Dumper;
'asn_format' => {
'spec' => _asn_spec(),
'macro' => 'TransferBatch', #XXX & skip the Notification ones?
+ 'header_buffer' => sub {
+ my $TransferBatch = shift;
+
+ my $networkInfo = $TransferBatch->{networkInfo};
+
+ my $recEntityInfo = $networkInfo->{recEntityInfo};
+ my %recEntity = map { $_->{recEntityCode} => $_->{recEntityId} } @$recEntityInfo;
+
+ my $utcTimeOffsetInfo = $networkInfo->{utcTimeOffsetInfo};
+ my %utcTimeOffset = map { $_->{utcTimeOffsetCode} => $_->{utcTimeOffset} } @$utcTimeOffsetInfo;
+
+ { recEntity => \%recEntity,
+ utcTimeOffset => \%utcTimeOffset,
+ tapDecimalPlaces => $TransferBatch->{accountingInfo}{tapDecimalPlaces},
+ };
+ },
'arrayref' => sub { shift->{'callEventDetails'}; },
'map' => {
- 'startdate' => sub { my $callinfo = shift->{mobileOriginatedCall}{basicCallInformation};
- my $timestamp = $callinfo->{callEventStartTimeStamp};
- my $localTimeStamp = $timestamp->{localTimeStamp};
- my $utcTimeOffsetCode = $timestamp->{utcTimeOffsetCode}; #XXX not handled, utcTimeOffsetInfo in header
- $localTimeStamp =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/ or die "unparsable timestamp: $localTimeStamp\n"; #. Dumper($callinfo);
- my($year, $mon, $day, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6);
- timelocal($sec, $min, $hour, $day, $mon-1, $year);
- },
- 'duration' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{totalCallEventDuration} },
- 'billsec' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{totalCallEventDuration} }, #same..
- 'src' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{chargeableSubscriber}{simChargeableSubscriber}{msisdn} },
- 'charged_party_imsi' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{chargeableSubscriber}{simChargeableSubscriber}{imsi} },
- 'dst' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{destination}{calledNumber} }, #dialledDigits?
- 'carrierid' => sub { shift->{mobileOriginatedCall}{locationInformation}{networkLocation}{recEntityCode} }, #XXX translate to recEntityId via info in header
- 'userfield' => sub { shift->{mobileOriginatedCall}{operatorSpecInformation}[0] },
- 'servicecode' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{basicService}{serviceCode}{teleServiceCode} },
- 'upstream_price' => sub { sprintf('%.5f', shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[0]{charge} / 100000 ) }, #XXX numberOfDecimalPlaces in header
- 'calltypenum' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{callTypeGroup}{callTypelevel1} },
- 'quantity' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{chargedUnits} },
- 'quantity_able' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeableUnits} },
- },
+ 'startdate' => sub { my($row, $buffer) = @_;
+ my $callinfo = $row->{mobileOriginatedCall}{basicCallInformation};
+ my $timestamp = $callinfo->{callEventStartTimeStamp};
+
+ my $localTimeStamp = $timestamp->{localTimeStamp};
+ $localTimeStamp =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/
+ or die "unparsable timestamp: $localTimeStamp\n"; #. Dumper($callinfo);
+ my($year, $mon, $day, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6);
+
+ my $utcTimeOffsetCode = $timestamp->{utcTimeOffsetCode};
+ my $utcTimeOffset = $buffer->{utcTimeOffset}{ $utcTimeOffsetCode };
+ local($ENV{TZ}) = $TZ{ $utcTimeOffset };
+
+ timelocal($sec, $min, $hour, $day, $mon-1, $year);
+ },
+ 'duration' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{totalCallEventDuration} },
+ 'billsec' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{totalCallEventDuration} }, #same..
+ 'src' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{chargeableSubscriber}{simChargeableSubscriber}{msisdn} },
+ 'charged_party_imsi' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{chargeableSubscriber}{simChargeableSubscriber}{imsi} },
+ 'dst' => sub { shift->{mobileOriginatedCall}{basicCallInformation}{destination}{calledNumber} }, #dialledDigits?
+ 'carrierid' => sub { my( $row, $buffer ) = @_;
+ my $recEntityCode = $row->{mobileOriginatedCall}{locationInformation}{networkLocation}{recEntityCode};
+ $buffer->{recEntity}{ $recEntityCode };
+ },
+ 'userfield' => sub { shift->{mobileOriginatedCall}{operatorSpecInformation}[0] },
+ 'servicecode' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{basicService}{serviceCode}{teleServiceCode} },
+ 'upstream_price' => sub { my($row, $buffer) = @_;
+ sprintf('%.'.$buffer->{tapDecimalPlaces}.'f',
+ $row->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[0]{charge}
+ / ( 10 ** $buffer->{tapDecimalPlaces} )
+ )
+ },
+ 'calltypenum' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{callTypeGroup}{callTypelevel1} },
+ 'quantity' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{chargedUnits} },
+ 'quantity_able' => sub { shift->{mobileOriginatedCall}{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeableUnits} },
+ },
},
);
@@ -137,7 +197,8 @@ sub tap3_12_export {
{ #either tele or bearer service usage originated by the mobile subscription (others?)
'mobileOriginatedCall' => {
- #identifies the Network Location, which includes the MSC responsible for handling the call and, where appropriate, the Geographical Location of the mobile
+ #identifies the Network Location, which includes the MSC responsible for handling
+ # the call and, where appropriate, the Geographical Location of the mobile
'locationInformation' => {
'networkLocation' => {
'recEntityCode' => $_->carrierid, #XXX Recording Entity (per 2.5, from "Reference Tables")