4 use vars qw(@ISA %info);
5 use FS::cdr qw(_cdr_date_parser_maker);
9 # About the ANI/DNIS/*Number columns:
10 # For inbound calls, ANI appears to be the true source number.
11 # Usually ANI = TermNumber in that case. (Case 1a.)
12 # In a few inbound CDRs, ANI = OrigNumber, the BillToNumber is also
13 # the DialedNumber and DNIS (and always an 800 number), and the TermNumber
14 # is a different number. (Case 2; rare.)
16 # For outbound calls, DNIS is always empty. The TermNumber appears to
17 # be the true destination. The DialedNumber may be empty (Case 1b), or
18 # equal the TermNumber (Case 3), or be a different number (Case 4; this
19 # probably shows routing to a different destination).
21 # How we are handling them:
22 # Case 1a (inbound): src = ANI, dst = BillToNumber
23 # Case 1b (outbound): src = BillToNumber, dst = ANI
24 # Case 2: src = ANI, dst = DialedNumber, dst_term = TermNumber
25 # Case 3: src = BillToNumber, dst = DialedNumber
26 # Case 4: src = BillToNumber, dst = DialedNumber, dst_term = TermNumber
31 'type' => 'fixedlength',
32 'fixedlength_format' => [qw(
34 MasterAccountID:12:4:15
38 CallDateStartTime:14:58:71
40 CalculatedSeconds:12:73:84
45 CallDirection:1:178:178
46 CallIndicator:1:179:179
47 ReportIndicator:1:180:180
53 DialedNumber:18:237:254
54 DisplayNumber:18:255:272
55 RecordSource:1:273:273
56 LECInfoDigits:2:274:275
61 OrigCircuit:12:289:300
62 OrigTrunkGroupCLLI:12:301:312
67 TermCircuit:12:326:337
68 TermTrunkGroupCLLI:12:338:349
71 # at least that's how they're defined in the spec we have.
72 # the real CDRs have several differences.
74 '', #CDRType (for now always 'V')
77 'charged_party', #BillToNumber
78 'accountcode', #AccountCode
79 _cdr_date_parser_maker('startdate'),
81 '', #TimeOfDay (always 'S')
82 sub { #CalculatedSeconds
90 'upstream_price', #Charges
93 $cdr->set('direction', $dir);
95 $cdr->set('src', $cdr->charged_party);
96 } elsif ( $dir eq 'I' ) {
97 $cdr->set('dst', $cdr->charged_party);
100 '', #CallIndicator #calltype?
103 # For inbound calls, this is the source.
104 # For outbound calls it's sometimes the destination but TermNumber
106 my ($cdr, $number) = @_;
107 if ( $cdr->direction eq 'I' ) {
108 $cdr->set('src', $number);
115 # For outbound calls, this is the terminal destination (after call
116 # routing). It's sometimes also the dialed destination (Case 1b and 3).
117 my ($cdr, $number) = @_;
118 if ( $cdr->direction eq 'O' ) {
119 $cdr->set('dst_term', $number);
120 $cdr->set('dst', $number); # change this later if Case 4
124 my ($cdr, $number) = @_;
125 # For outbound calls, this is the destination before any call routing,
126 # and should be used for billing. Except when it's null; then use
128 if ( $cdr->direction eq 'O' and $number =~ /\d/ ) {
130 $cdr->set('dst', $number);
141 # Case 1a (inbound): src = ANI, dst = BillToNumber
142 # Case 1b (outbound): src = BillToNumber, dst = TermNumber
143 # Case 2: src = ANI, dst = DialedNumber, dst_term = TermNumber
144 # Case 3: src = BillToNumber, dst = TermNumber
145 # Case 4: src = BillToNumber, dst = DialedNumber, dst_term = TermNumber