RT37901: Galactic Telecom CDRs [need to finish field mapping
[freeside.git] / FS / bin / freeside-cdr-portaone-import
1 #!/usr/bin/perl
2
3 use strict;
4
5 use Date::Format 'time2str';
6 use Date::Parse 'str2time';
7 use Getopt::Long;
8 use JSON;
9 use Net::HTTPS::Any qw(https_post);
10
11 use FS::Record qw(qsearchs dbh);
12 use FS::UID qw(adminsuidsetup);
13
14 sub usage {
15   "Usage:
16 freeside-cdr-portaone-import -h 'your.domain.com:443' -u switchusername -p switchpass 
17   [-s startdate] [-e enddate] [-v] freesideuser
18 ";
19 }
20
21 my ($host,$username,$password,$startdate,$enddate,$verbose);
22 GetOptions(
23   "enddate=s"   => \$enddate,
24   "host=s"      => \$host,
25   "password=s"  => \$password,
26   "startdate=s" => \$startdate,
27   "username=s"  => \$username,
28   "verbose"     => \$verbose,
29 );
30
31 my $fsuser = $ARGV[-1];
32
33 die usage() unless $host && $password && $username && $fsuser;
34
35 adminsuidsetup($fsuser);
36
37 my $port = 443;
38 if ($host =~ /^(.*)\:(.*)$/) {
39   $host = $1;
40   $port = $2;
41 }
42
43 if ($startdate) {
44   $startdate = str2time($startdate) or die "Can't parse startdate $startdate";
45   $startdate = time2str("%Y-%m-%d %H:%M:%S",$startdate);
46 }
47 unless ($startdate) {
48   my $lastbatch = qsearchs({
49     'table'     => 'cdr_batch',
50     'hashref'   => { 'cdrbatch' => {op=>'like', value=>'portaone-import%'}},
51     'order_by'  => 'ORDER BY _date DESC LIMIT 1',
52   });
53   $startdate = time2str("%Y-%m-%d %H:%M:%S", $lastbatch->_date + 1) if $lastbatch;
54 }
55 $startdate ||= '2010-01-01 00:00:00'; #seems decently in the past
56
57 my $now = time;
58 if ($enddate) {
59   $enddate = str2time($enddate) or die "Can't parse enddate $enddate";
60   $now = $enddate;
61   $enddate = time2str("%Y-%m-%d %H:%M:%S",$enddate);
62 }
63 $enddate ||= time2str("%Y-%m-%d %H:%M:%S",$now);
64
65 print "Downloading records from $startdate to $enddate\n" if $verbose;
66
67 my $auth_info; # needs to be declared undef for call_api
68 $auth_info = call_api('Session','login',{
69   'login'    => $username,
70   'password' => $password,
71 });
72
73 my $results = {};
74 my $custlist = call_api('Customer','get_customer_list');
75 my @custnum = map { $_->{'i_customer'} } @{$custlist->{'customer_list'}};
76 foreach my $custnum (@custnum) {
77   print "Processing customer $custnum\n" if $verbose;
78   my $xdrs = call_api('Customer','get_customer_xdrs',{
79     'i_customer' => $custnum,
80     'from_date'  => $startdate,
81     'to_date'    => $enddate,
82     'cdr_entity' => 'C', # can also be 'A', or blank for both
83   });
84   my @xdrs = @{$xdrs->{'xdr_list'}};
85   print scalar(@xdrs) . " xdrs retrieved\n" if $verbose;
86   $results->{$custnum} = \@xdrs;
87 }
88
89 call_api('Session','logout',$auth_info);
90
91 $FS::UID::AutoCommit = 0;
92
93 my $cdr_batch = new FS::cdr_batch({ 
94   'cdrbatch' => 'portaone-import-'. time2str('%Y/%m/%d-%T',$now),
95   '_date'    => $now,
96 });
97 my $error = $cdr_batch->insert;
98 if ($error) {
99   dbh->rollback;
100   die "Error inserting batch: $error";
101 }
102
103 foreach my $custnum (keys %$results) {
104   foreach my $xdr (@{$results->{$custnum}}) {
105     my $cdr = FS::cdr->new ({
106       'cdrbatchnum' => $cdr_batch->cdrbatchnum,
107       'acctid'      => $xdr->{'i_xdr'}, #???
108       'accountcode' => $xdr->{'account_id'}, #???
109       'startdate'   => $xdr->{'unix_connect_time'},
110       'enddate'     => $xdr->{'unix_disconnect_time'},
111
112 ### XXX NEED TO MAP FIELDS:
113 #i_xdr                     int      The unique ID of the xdr record
114 #account_id                    int      The unique ID of the account database record
115 #CLI                       string   Calling Line Identification
116 #CLD                       string   Called Line Identification
117 #charged_amount            float    Amount charged
118 #charged_quantity          int      Units charged
119 #country                   string   Country
120 #subdivision               string   Country subdivision
121 #description               string   Destination description
122 #disconnect_cause          string   The code of disconnect cause
123 #bill_status               string   Call bill status
124 #disconnect_reason         string   Call disconnect reason
125 #connect_time              dateTime Call connect time
126 #unix_connect_time         int      Call connect time (expressed in Unix time format - seconds since epoch)
127 #disconnect_time           dateTime Call disconnect time 
128 #unix_disconnect_time      int      Call disconnect time i_xdr                     int      The unique ID of the xdr record
129 #account_id                   int      The unique ID of the account database record
130 #CLI                       string   Calling Line Identification
131 #CLD                       string   Called Line Identification
132 #charged_amount            float    Amount charged
133 #charged_quantity          int      Units charged
134 #country                   string   Country
135 #subdivision               string   Country subdivision
136 #description               string   Destination description
137 #disconnect_cause          string   The code of disconnect cause
138 #bill_status               string   Call bill status
139 #disconnect_reason         string   Call disconnect reason
140 #connect_time              dateTime Call connect time
141 #unix_connect_time         int      Call connect time (expressed in Unix time format - seconds since epoch)
142 #disconnect_time           dateTime Call disconnect time 
143 #unix_disconnect_time      int      Call disconnect time (expressed in Unix time format - seconds since epoch)
144 #bill_time                 dateTime Call bill time 
145 #bit_flags                 int      Extended information how the service was used; the integer field that should be treated as a bit-map. Each currently used bit is listed in the Transaction_Flag_Types table (bit_offset indicates position)
146 #call_recording_url        string   Path to recorded .wav files
147 #call_recording_server_url string   URL to the recording server (expressed in Unix time format - seconds since epoch)
148 #bill_time                 dateTime Call bill time 
149 #bit_flags                 int      Extended information how the service was used; the integer field that should be treated as a bit-map. Each currently used bit is listed in the Transaction_Flag_Types table (bit_offset indicates position)
150 #call_recording_url        string   Path to recorded .wav files
151 #call_recording_server_url string   URL to the recording server 
152
153     });
154     $error = $cdr->insert;
155     if ($error) {
156       dbh->rollback;
157       die "Error inserting cdr: $error";
158     }
159   } #foreach $xdr
160 } #foreach $custnum
161
162 dbh->commit;
163
164 exit;
165
166 sub call_api {
167   my ($service,$method,$params) = @_;
168   my %auth_info = $auth_info ? ('auth_info' => encode_json($auth_info)) : ();
169   $params ||= {};
170   print "Calling $service/$method...\n" if $verbose;
171   my ( $page, $response, %reply_headers ) = https_post(
172     'host'    => $host,
173     'port'    => $port,
174     'path'    => '/rest/'.$service.'/'.$method.'/',
175     'args'    => [ %auth_info, 'params' => encode_json($params) ],
176   );
177   return decode_json($page) if $response eq '200 OK';
178   if ($response =~ /^500/) {
179     my $error = decode_json($page);
180     die "Server returned error during $service/$method: ".$error->{'faultstring'}
181       if $error->{'faultcode'};
182   }
183   die "Bad response from server during $service/$method: $response";
184 }
185
186