update radiator export to deal with prepaid and some other random stuff
[freeside.git] / FS / FS / part_export / radiator.pm
1 package FS::part_export::radiator;
2
3 use vars qw(@ISA %info $radusers);
4 use Tie::IxHash;
5 use FS::part_export::sqlradius;
6
7 tie my %options, 'Tie::IxHash', %FS::part_export::sqlradius::options;
8
9 %info = (
10   'svc'      => 'svc_acct',
11   'desc'     => 'Real-time export to RADIATOR',
12   'options'  => \%options,
13   'nodomain' => '',
14   'notes' => <<'END',
15 Real-time export of the <b>radusers</b> table to any SQL database in
16 <a href="http://www.open.com.au/radiator/">Radiator</a>-native format.
17 To setup accounting, see the RADIATOR documentation for hooks to update
18 a standard <b>radacct</b> table.
19 END
20 );
21
22 @ISA = qw(FS::part_export::sqlradius); #for regular sqlradius accounting
23
24 $radusers = 'RADUSERS'; #MySQL is case sensitive about table names!  huh
25
26 #sub export_username {
27 #  my($self, $svc_acct) = (shift, shift);
28 #  $svc_acct->email;
29 #}
30
31 sub _export_insert {
32   my( $self, $svc_acct ) = (shift, shift);
33
34   $self->radiator_queue(
35     $svc_acct->svcnum,
36     'insert',
37     $self->_radiator_hash($svc_acct),
38   );
39 }
40
41 sub _export_replace {
42   my( $self, $new, $old ) = (shift, shift, shift);
43
44 #  return "can't (yet) change domain with radiator export"
45 #    if $old->domain ne $new->domain;
46 #  return "can't (yet) change username with radiator export"
47 #    if $old->username ne $new->username;
48
49   $self->radiator_queue(
50     $new->svcnum,
51     'replace',
52     $self->export_username($old),
53     $self->_radiator_hash($new),
54   );
55 }
56
57 sub _export_delete {
58   my( $self, $svc_acct ) = (shift, shift);
59
60   $self->radiator_queue(
61     $svc_acct->svcnum,
62     'delete',
63     $self->export_username($svc_acct),
64   );
65 }
66
67 sub _radiator_hash {
68   my( $self, $svc_acct ) = @_;
69   my %hash = (
70     'username'  => $self->export_username($svc_acct),
71     'pass_word' => $svc_acct->_password,
72     'fullname'  => $svc_acct->finger,
73     map { my $method = "radius_$_"; $_ => $svc_acct->$method(); }
74         qw( framed_filter_id framed_mtu framed_netmask framed_protocol
75             framed_routing login_host login_service login_tcp_port )
76   );
77   $hash{'timeleft'} = $svc_acct->seconds
78     if $svc_acct->seconds =~ /^\d+$/;
79   $hash{'staticaddress'} = $svc_acct->slipip
80     if $svc_acct->slipip =~ /^[\d\.]+$/; # and $self->slipip ne '0.0.0.0';
81
82   $hash{'servicename'} = ( $svc_acct->radius_groups )[0];
83
84   my $cust_pkg = $self->cust_svc->cust_pkg;
85   $hash{validto} = $cust_pkg->bill
86     if $cust_pkg && $cust_pkg->part_pkg->is_prepaid && $cust_pkg->bill;
87
88   #some other random stuff, should probably be attributes or virtual fields
89   #$hash{'state'} = 0; #only inserts
90   #$hash{'badlogins'} = 0; #only inserts
91   $hash{'maxlogins'} = 1;
92   $hash{'addeddate'} = $cust_pkg->setup
93     if $cust_pkg && $cust_pkg->setup;
94   $hash{'validfrom'} = $cust_pkg->last_bill || $cust_pkg->setup
95     if $cust_pkg &&  ( $cust_pkg->last_bill || $cust_pkg->setup );
96
97   %hash;
98 }
99
100 sub radiator_queue {
101   my( $self, $svcnum, $method ) = (shift, shift, shift);
102   my $queue = new FS::queue {
103     'svcnum' => $svcnum,
104     'job'    => "FS::part_export::radiator::radiator_$method",
105   };
106   $queue->insert(
107     $self->option('datasrc'),
108     $self->option('username'),
109     $self->option('password'),
110     @_,
111   ); # or $queue;
112 }
113
114 sub radiator_insert { #subroutine, not method
115   my $dbh = radiator_connect(shift, shift, shift);
116   my %hash = @_;
117   $hash{'state'} = 0; #see "random stuff" above
118   $hash{'badlogins'} = 0; #see "random stuff" above
119
120   my $sth = $dbh->prepare(
121     "INSERT INTO $radusers ( ". join(', ', keys %hash ). ' ) '.
122       'VALUES ( '. join(', ', map '?', keys %hash ). ' ) '
123   ) or die $dbh->errstr;
124   $sth->execute( values %hash )
125     or die $sth->errstr;
126
127   $dbh->disconnect;
128
129 }
130
131 sub radiator_replace { #subroutine, not method
132   my $dbh = radiator_connect(shift, shift, shift);
133   my ( $old_username, %hash ) = @_;
134
135   my $sth = $dbh->prepare(
136     "UPDATE $radusers SET ". join(', ', map " $_ = ?", keys %hash ).
137       ' WHERE username = ?'
138   ) or die $dbh->errstr;
139   $sth->execute( values(%hash), $old_username )
140     or die $sth->errstr;
141
142   $dbh->disconnect;
143 }
144
145 sub radiator_delete { #subroutine, not method
146   my $dbh = radiator_connect(shift, shift, shift);
147   my ( $username ) = @_;
148
149   my $sth = $dbh->prepare(
150     "DELETE FROM $radusers WHERE username = ?"
151   ) or die $dbh->errstr;
152   $sth->execute( $username )
153     or die $sth->errstr;
154
155   $dbh->disconnect;
156 }
157
158
159 sub radiator_connect {
160   #my($datasrc, $username, $password) = @_;
161   #DBI->connect($datasrc, $username, $password) or die $DBI::errstr;
162   DBI->connect(@_) or die $DBI::errstr;
163 }
164
165 1;