okay group editing UI as well as part_svc group editing UI seem to be working
[freeside.git] / FS / FS / svc_acct.pm
index 2305aeb..a3e97f7 100644 (file)
@@ -27,6 +27,7 @@ use FS::cust_main_invoice;
 use FS::svc_domain;
 use FS::raddb;
 use FS::queue;
+use FS::radius_usergroup;
 
 @ISA = qw( FS::svc_Common );
 
@@ -191,8 +192,6 @@ FS::svc_Common.  The following fields are currently supported:
 
 =item radius_I<Radius_Attribute> - I<Radius-Attribute>
 
-=item domsvc - service number of svc_domain with which to associate
-
 =back
 
 =head1 METHODS
@@ -215,6 +214,10 @@ otherwise returns false.
 The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be 
 defined.  An FS::cust_svc record will be created and inserted.
 
+The additional field I<usergroup> can optionally be defined; if so it should
+contain an arrayref of group names.  See L<FS::radius_usergroup>.  (used in
+sqlradius export only)
+
 If the configuration value (see L<FS::Conf>) shellmachine exists, and the 
 username, uid, and dir fields are defined, the command(s) specified in
 the shellmachine-useradd configuration are added to the job queue (see
@@ -288,6 +291,20 @@ sub insert {
     return $error;
   }
 
+  if ( $self->usergroup ) {
+    foreach my $groupname ( @{$self->usergroup} ) {
+      my $radius_usergroup = new FS::radius_usergroup ( {
+        svcnum    => $self->svcnum,
+        groupname => $groupname,
+      } );
+      my $error = $radius_usergroup->insert;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return $error;
+      }
+    }
+  }
+
   #new-style exports!
   unless ( $noexport_hack ) {
     foreach my $part_export ( $self->cust_svc->part_svc->part_export ) {
@@ -560,6 +577,16 @@ sub delete {
     }
   }
 
+  foreach my $radius_usergroup (
+    qsearch('radius_usergroup', { 'svcnum' => $self->svcnum } )
+  ) {
+    my $error = $radius_usergroup->delete;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
   my $error = $self->SUPER::delete;
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
@@ -699,6 +726,10 @@ sub vpopmail_delete {
 Replaces OLD_RECORD with this one in the database.  If there is an error,
 returns the error, otherwise returns false.
 
+The additional field I<usergroup> can optionally be defined; if so it should
+contain an arrayref of group names.  See L<FS::radius_usergroup>.  (used in
+sqlradius export only)
+
 If the configuration value (see L<FS::Conf>) shellmachine exists, and the 
 dir field has changed, the command(s) specified in the shellmachine-usermod
 configuraiton file are added to the job queue (see L<FS::queue> and
@@ -759,6 +790,40 @@ sub replace {
     return $error if $error;
   }
 
+  $old->usergroup( [ $old->radius_groups ] );
+
+  if ( $new->usergroup ) {
+
+    foreach my $groupname ( @{$old->usergroup} ) {
+      if ( grep { $groupname eq $_ } @{$new->usergroup} ) {
+        $new->usergroup( [ grep { $groupname ne $_ } @{$new->usergroup} ] );
+        next;
+      }
+      my $radius_usergroup = qsearchs('radius_usergroup', {
+        svcnum    => $old->svcnum,
+        groupname => $groupname,
+      } );
+      my $error = $radius_usergroup->delete;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "error deleting radius_usergroup $groupname: $error";
+      }
+    }
+
+    foreach my $groupname ( @{$new->usergroup} ) {
+      my $radius_usergroup = new FS::radius_usergroup ( {
+        svcnum    => $new->svcnum,
+        groupname => $groupname,
+      } );
+      my $error = $radius_usergroup->insert;
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "error adding radius_usergroup $groupname: $error";
+      }
+    }
+
+  }
+
   #new-style exports!
   unless ( $noexport_hack ) {
     foreach my $part_export ( $new->cust_svc->part_svc->part_export ) {
@@ -1282,8 +1347,71 @@ sub seconds_since {
   $self->cust_svc->seconds_since(@_);
 }
 
+=item radius_groups
+
+Returns all RADIUS groups for this account (see L<FS::radius_usergroup>).
+
+=cut
+
+sub radius_groups {
+  my $self = shift;
+  map { $_->groupname }
+    qsearch('radius_usergroup', { 'svcnum' => $self->svcnum } );
+}
+
 =back
 
+=head1 SUBROUTINES
+
+=item radius_usergroup_selector GROUPS_ARRAYREF [ SELECTNAME ]
+
+=cut
+
+sub radius_usergroup_selector {
+  my $sel_groups = shift;
+  my %sel_groups = map { $_=>1 } @$sel_groups;
+
+  my $selectname = shift || 'radius_usergroup';
+
+  my $dbh = dbh;
+  my $sth = $dbh->prepare(
+    'SELECT DISTINCT(groupname) FROM radius_usergroup ORDER BY groupname'
+  ) or die $dbh->errstr;
+  $sth->execute() or die $sth->errstr;
+  my @all_groups = map { $_->[0] } @{$sth->fetchall_arrayref};
+
+  my $html = <<END;
+    <SCRIPT>
+    function ${selectname}_doadd(object) {
+      var myvalue = object.${selectname}_add.value;
+      var optionName = new Option(myvalue,myvalue,false,true);
+      var length = object.$selectname.length;
+      object.$selectname.options[length] = optionName;
+      object.${selectname}_add.value = "";
+    }
+    </SCRIPT>
+    <SELECT MULTIPLE NAME="$selectname">
+END
+
+  foreach my $group ( @all_groups ) {
+    $html .= '<OPTION';
+    if ( $sel_groups{$group} ) {
+      $html .= ' SELECTED';
+      $sel_groups{$group} = 0;
+    }
+    $html .= ">$group</OPTION>\n";
+  }
+  foreach my $group ( grep { $sel_groups{$_} } keys %sel_groups ) {
+    $html .= "<OPTION SELECTED>$group</OPTION>\n";
+  };
+  $html .= '</SELECT>';
+
+  $html .= qq!<BR><INPUT TYPE="text" NAME="${selectname}_add">!.
+           qq!<INPUT TYPE="button" VALUE="Add new group" onClick="${selectname}_doadd(this.form)">!;
+
+  $html;
+}
+
 =head1 BUGS
 
 The $recref stuff in sub check should be cleaned up.
@@ -1292,6 +1420,9 @@ The suspend, unsuspend and cancel methods update the database, but not the
 current object.  This is probably a bug as it's unexpected and
 counterintuitive.
 
+radius_usergroup_selector?  putting web ui components in here?  they should
+probably live somewhere else...
+
 =head1 SEE ALSO
 
 L<FS::svc_Common>, edit/part_svc.cgi from an installed web interface,