1 package FS::ClientAPI::PrepaidPhone;
4 use vars qw($DEBUG $me);
5 use FS::Record qw(qsearchs);
10 $me = '[FS::ClientAPI::PrepaidPhone]';
13 # - shared-secret auth? (set a conf value)
15 =item call_time HASHREF
17 HASHREF contains the following parameters:
23 Source number (with countrycode)
27 Destination number (with countrycode)
31 Always returns a hashref. If there is an error, the hashref contains a single
32 "error" key with the error message as a value. Otherwise, returns a hashref
33 with the following keys:
39 Empty if no customer is found associated with the number, customer number
44 Number of seconds remaining for a call to destination number
53 my $src = $packet->{'src'};
54 my $dst = $packet->{'dst'};
58 #my $conf = new FS::Conf;
59 #if ( #XXX toll-free? collect?
61 #} else { #use the src to find the customer
66 my( $countrycode, $phonenum );
67 if ( $chargeto #an interesting regex to parse out 1&2 digit countrycodes
68 =~ /^(2[078]|3[0-469]|4[013-9]|5[1-8]|6[0-6]|7|8[1-469]|9[0-58])(\d*)$/
69 || $chargeto =~ /^(\d{3})(\d*)$/
75 return { 'error' => "unparsable billing number: $chargeto" };
79 my $svc_phone = qsearchs('svc_phone', { 'countrycode' => $countrycode,
80 'phonenum' => $phonenum,
84 unless ( $svc_phone ) {
85 return { 'error' => "can't find customer for +$countrycode $phonenum" };
86 # return { 'custnum' => '',
92 my $cust_pkg = $svc_phone->cust_svc->cust_pkg;
93 my $cust_main = $cust_pkg->cust_main;
95 my $part_pkg = $cust_pkg->part_pkg;
96 my @part_pkg = ( $part_pkg, map $_->dst_pkg, $part_pkg->bill_part_pkg_link );
97 #XXX uuh, behavior indeterminate if you have more than one voip_cdr+prefix
99 warn "$me ". scalar(@part_pkg). ': '.
100 join('/', map { $_->plan. $_->option('rating_method') } @part_pkg )
103 grep { $_->plan eq 'voip_cdr' && $_->option('rating_method') eq 'prefix' }
107 'custnum' => $cust_pkg->custnum,
108 #'balance' => $cust_pkg->cust_main->balance,
111 warn "$me: ". scalar(@part_pkg). ': '.
112 join('/', map { $_->plan. $_->option('rating_method') } @part_pkg )
114 return \%return unless @part_pkg;
116 warn "$me searching for rate ". $part_pkg[0]->option('ratenum')
119 my $rate = qsearchs('rate', { 'ratenum'=>$part_pkg[0]->option('ratenum') } );
122 my $error = 'ratenum '. $part_pkg[0]->option('ratenum'). ' not found';
125 return { 'error'=>$error };
128 warn "$me found rate ". $rate->ratenum
131 #rate the call and arrive at a max # of seconds for the customer's balance
133 my( $rate_countrycode, $rate_phonenum );
134 if ( $rateby #this is an interesting regex to parse out 1&2 digit countrycodes
135 =~ /^(2[078]|3[0-469]|4[013-9]|5[1-8]|6[0-6]|7|8[1-469]|9[0-58])(\d*)$/
136 || $rateby =~ /^(\d{3})(\d*)$/
139 $rate_countrycode = $1;
142 return { 'error' => "unparsable rating number: $rateby" };
145 my $rate_detail = $rate->dest_detail({ 'countrycode' => $rate_countrycode,
146 'phonenum' => $rate_phonenum,
148 unless ( $rate_detail ) {
149 return { 'error'=>"can't find rate for +$rate_countrycode $rate_phonenum"};
152 unless ( $rate_detail->min_charge > 0 ) {
153 #XXX no charge?? return lots of seconds, a default, 0 or what?
154 #return { 'error' => '0 rate for +$rate_countrycode $rate_phonenum; prepaid service not available" };
155 #customer wants no default for now# $return{'seconds'} = 1800; #half hour?!
159 #XXX granularity? included minutes? another day...
160 if ( $cust_main->balance >= 0 ) {
161 return { 'error'=>'No balance' };
163 $return{'seconds'} = int(60 * abs($cust_main->balance) / $rate_detail->min_charge);
166 warn "$me returning seconds: ". $return{'seconds'};
172 =item call_time_nanpa
174 Like I<call_time>, except countrycode 1 is not required, and all other
175 countrycodes must be prefixed with 011.
179 # - everything is assumed to be countrycode 1 unless it starts with 011(ccode)
180 sub call_time_nanpa {
183 foreach (qw( src dst )) {
184 if ( $packet->{$_} =~ /^011(\d+)/ ) {
186 } elsif ( $packet->{$_} !~ /^1/ ) {
187 $packet->{$_} = '1'.$packet->{$_};
195 =item phonenum_balance HASHREF
197 HASHREF contains the following parameters:
203 Optional countrycode. Defaults to 1.
211 Always returns a hashref. If there is an error, the hashref contains a single
212 "error" key with the error message as a value. Otherwise, returns a hashref
213 with the following keys:
219 Empty if no customer is found associated with the number, customer number
230 sub phonenum_balance {
233 my $svc_phone = qsearchs('svc_phone', {
234 'countrycode' => ( $packet->{'countrycode'} || 1 ),
235 'phonenum' => $packet->{'phonenum'},
238 unless ( $svc_phone ) {
239 return { 'custnum' => '',
244 my $cust_pkg = $svc_phone->cust_svc->cust_pkg;
247 'custnum' => $cust_pkg->custnum,
248 'balance' => $cust_pkg->cust_main->balance,