2d6297a8aee4632119cc77da537f0f2ea64243a9
[freeside.git] / FS / FS / ClientAPI / PrepaidPhone.pm
1 package FS::ClientAPI::PrepaidPhone;
2
3 use strict;
4 #use vars qw($DEBUG $me);
5 use FS::Record qw(qsearchs);
6 use FS::rate;
7 use FS::svc_phone;
8
9 #$DEBUG = 0;
10 #$me = '[FS::ClientAPI::PrepaidPhone]';
11
12 #TODO:
13 # - shared-secret auth? (set a conf value)
14
15 =item call_time HASHREF
16
17 HASHREF contains the following parameters:
18
19 =over 4
20
21 =item src
22
23 Source number (with countrycode)
24
25 =item dst
26
27 Destination number (with countrycode)
28
29 =back
30
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:
34
35 =over 4
36
37 =item custnum
38
39 Empty if no customer is found associated with the number, customer number
40 otherwise.
41
42 =item seconds
43
44 Number of seconds remaining for a call to destination number
45
46 =back
47
48 =cut
49
50 sub call_time {
51   my $packet = shift;
52
53   my $src = $packet->{'src'};
54   my $dst = $packet->{'dst'};
55
56   my $number;
57   #my $conf = new FS::Conf;
58   #if ( #XXX toll-free?  collect?
59   #  $phonenum = $dst;
60   #} else { #use the src to find the customer
61     $number = $src;
62   #}
63
64   my( $countrycode, $phonenum );
65   if ( $number #this is an interesting regex to parse out 1&2 digit countrycodes
66          =~ /^(2[078]|3[0-469]|4[013-9]|5[1-8]|6[0-6]|7|8[1-469]|9[0-58])(\d*)$/
67        || $number =~ /^(\d{3})(\d*)$/
68      )
69   {
70     $countrycode = $1;
71     $phonenum = $2;
72   } else { 
73     return { 'error' => "unparsable number: $number" };
74   }
75
76   my $svc_phone = qsearchs('svc_phone', { 'countrycode' => $countrycode,
77                                           'phonenum'    => $phonenum,
78                                         }
79                           );
80
81   unless ( $svc_phone ) {
82     return { 'custnum' => '',
83              'seconds' => 0,
84              #'balance' => 0,
85            };
86   };
87
88   my $cust_pkg = $svc_phone->cust_svc->cust_pkg;
89   my $part_pkg = $cust_pkg->part_pkg;
90   my $cust_main = $cust_pkg->cust_main;
91
92   my %return = (
93     'custnum' => $cust_pkg->custnum,
94     #'balance' => $cust_pkg->cust_main->balance,
95   );
96
97   return \%return unless $part_pkg->plan eq 'voip_cdr'
98                       && $part_pkg->option('rating_method') eq 'prefix';
99
100   my $rate = qsearchs('rate', { 'ratenum' => $part_pkg->option('ratenum') } );
101
102   #rate the call and arrive at a max # of seconds for the customer's balance
103   my $rate_detail = $rate->dest_detail({ 'countrycode' => $countrycode,
104                                          'phonenum'    => $phonenum,
105                                        });
106
107   #XXX granularity?  included minutes?  another day...
108
109   $return{'seconds'} = int(60 * $cust_main->balance / $rate_detail->min_charge);
110
111   return \%return;
112  
113 }
114
115 =item call_time_nanpa 
116
117 Like I<call_time>, except countrycode 1 is not required, and all other
118 countrycodes must be prefixed with 011.
119
120 =cut
121
122 # - everything is assumed to be countrycode 1 unless it starts with 011(ccode)
123 sub call_time_nanpa {
124   my $packet = shift;
125
126   foreach (qw( src dst )) {
127     if ( $packet->{$_} =~ /^011(\d+)/ ) {
128       $packet->{$_} = $1;
129     } elsif ( $packet->{$_} !~ /^1/ ) {
130       $packet->{$_} = '1'.$packet->{$_};
131     }
132   }
133
134   call_time($packet);
135
136 }
137
138 =item phonenum_balance HASHREF
139
140 HASHREF contains the following parameters:
141
142 =over 4
143
144 =item countrycode
145
146 Optional countrycode.  Defaults to 1.
147
148 =item phonenum
149
150 Phone number.
151
152 =back
153
154 Always returns a hashref.  If there is an error, the hashref contains a single
155 "error" key with the error message as a value.  Otherwise, returns a hashref
156 with the following keys:
157
158 =over 4
159
160 =item custnum
161
162 Empty if no customer is found associated with the number, customer number
163 otherwise.
164
165 =item balance
166
167 Customer balance.
168
169 =back
170
171 =cut
172
173 sub phonenum_balance {
174   my $packet = shift;
175
176   my $svc_phone = qsearchs('svc_phone', {
177     'countrycode' => ( $packet->{'countrycode'} || 1 ),
178     'phonenum'    => $packet->{'phonenum'},
179   });
180
181   unless ( $svc_phone ) {
182     return { 'custnum' => '',
183              'balance' => 0,
184            };
185   };
186
187   my $cust_pkg = $svc_phone->cust_svc->cust_pkg;
188
189   return {
190     'custnum' => $cust_pkg->custnum,
191     'balance' => $cust_pkg->cust_main->balance,
192   };
193
194 }
195
196 1;