communigate (phase 2): rules. RT#7514
authorivan <ivan>
Fri, 23 Apr 2010 06:47:38 +0000 (06:47 +0000)
committerivan <ivan>
Fri, 23 Apr 2010 06:47:38 +0000 (06:47 +0000)
12 files changed:
FS/FS/Mason.pm
FS/FS/Schema.pm
FS/FS/cgp_rule.pm
FS/FS/cgp_rule_action.pm
FS/FS/cgp_rule_condition.pm
httemplate/browse/cgp_rule.html [new file with mode: 0644]
httemplate/edit/cgp_rule.html [new file with mode: 0644]
httemplate/edit/process/cgp_rule.html [new file with mode: 0644]
httemplate/misc/delete-cgp_rule.html [new file with mode: 0644]
httemplate/view/svc_acct/basics.html
httemplate/view/svc_acct/communigate.html [new file with mode: 0644]
httemplate/view/svc_domain/basics.html

index f65d972..41c472d 100644 (file)
@@ -234,6 +234,7 @@ if ( -e $addl_handler_use_file ) {
   use FS::cust_pkg_discount;
   use FS::cust_bill_pkg_discount;
   use FS::svc_mailinglist;
+  use FS::cgp_rule;
   # Sammath Naur
 
   if ( $FS::Mason::addl_handler_use ) {
index ca54d7b..28f8264 100644 (file)
@@ -1788,15 +1788,15 @@ sub tables_hashref {
 
     'cgp_rule' => {
       'columns' => [
-        'rulenum',  'serial', '',      '', '', '',
-        'name',    'varchar', '', $char_d, '', '',
-        'comment', 'varchar', '', $char_d, '', '',
-        'svcnum',      'int', '',      '', '', '',
-        'priority',    'int', '',      '', '', '',
+        'rulenum',  'serial',     '',      '', '', '',
+        'name',    'varchar',     '', $char_d, '', '',
+        'comment', 'varchar', 'NULL', $char_d, '', '',
+        'svcnum',      'int',     '',      '', '', '',
+        'priority',    'int',     '',      '', '', '',
       ],
       'primary_key' => 'rulenum',
       'unique'      => [],
-      'index '      => [ [ 'svcnum' ] ],
+      'index      => [ [ 'svcnum' ] ],
     },
 
     'cgp_rule_condition' => {
@@ -1809,7 +1809,7 @@ sub tables_hashref {
       ],
       'primary_key' => 'ruleconditionnum',
       'unique'      => [],
-      'index '      => [ [ 'rulenum' ] ],
+      'index      => [ [ 'rulenum' ] ],
     },
 
     'cgp_rule_action' => {
@@ -1821,7 +1821,7 @@ sub tables_hashref {
       ],
       'primary_key' => 'ruleactionnum',
       'unique'      => [],
-      'index '      => [ [ 'rulenum' ] ],
+      'index      => [ [ 'rulenum' ] ],
    },
 
     'svc_forward' => {
index 283055f..7e5c9fe 100644 (file)
@@ -2,7 +2,10 @@ package FS::cgp_rule;
 
 use strict;
 use base qw( FS::Record );
-use FS::Record qw( qsearch qsearchs );
+use FS::Record qw( qsearch qsearchs dbh );
+use FS::cust_svc;
+use FS::cgp_rule_condition;
+use FS::cgp_rule_action;
 
 =head1 NAME
 
@@ -25,8 +28,8 @@ FS::cgp_rule - Object methods for cgp_rule records
 
 =head1 DESCRIPTION
 
-An FS::cgp_rule object represents an example.  FS::cgp_rule inherits from
-FS::Record.  The following fields are currently supported:
+An FS::cgp_rule object represents a mail filtering rule.  FS::cgp_rule
+inherits from FS::Record.  The following fields are currently supported:
 
 =over 4
 
@@ -59,7 +62,7 @@ priority
 
 =item new HASHREF
 
-Creates a new example.  To add the example to the database, see L<"insert">.
+Creates a new rule.  To add the rule to the database, see L<"insert">.
 
 Note that this stores the hash reference, not a distinct copy of the hash it
 points to.  You can ask the object for a copy with the I<hash> method.
@@ -85,7 +88,40 @@ Delete this record from the database.
 
 =cut
 
-# the delete method can be inherited from FS::Record
+sub delete {
+  my $self = shift;
+
+  local $SIG{HUP} = 'IGNORE';
+  local $SIG{INT} = 'IGNORE';
+  local $SIG{QUIT} = 'IGNORE';
+  local $SIG{TERM} = 'IGNORE';
+  local $SIG{TSTP} = 'IGNORE';
+  local $SIG{PIPE} = 'IGNORE';
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my @del = $self->cgp_rule_condition;
+  push @del, $self->cgp_rule_action;
+
+  foreach my $del (@del) {
+    my $error = $del->delete;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
+  my $error = $self->SUPER::delete(@_);
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+}
 
 =item replace OLD_RECORD
 
@@ -98,7 +134,7 @@ returns the error, otherwise returns false.
 
 =item check
 
-Checks all fields to make sure this is a valid example.  If there is
+Checks all fields to make sure this is a valid rule.  If there is
 an error, returns the error, otherwise returns false.  Called by the insert
 and replace methods.
 
@@ -113,8 +149,8 @@ sub check {
   my $error = 
     $self->ut_numbern('rulenum')
     || $self->ut_text('name')
-    || $self->ut_text('comment')
-    || $self->ut_number('svcnum')
+    || $self->ut_textn('comment')
+    || $self->ut_foreign_key('svcnum', 'cust_svc', 'svcnum')
     || $self->ut_number('priority')
   ;
   return $error if $error;
@@ -122,12 +158,43 @@ sub check {
   $self->SUPER::check;
 }
 
+=item cust_svc
+
+=cut
+
+sub cust_svc {
+  my $self = shift;
+  qsearchs('cust_svc', { 'svcnum' => $self->svcnum } );
+}
+
+=item cgp_rule_condition
+
+Returns the conditions associated with this rule, as FS::cgp_rule_condition
+objects.
+
+=cut
+
+sub cgp_rule_condition {
+  my $self = shift;
+  qsearch('cgp_rule_condition', { 'rulenum' => $self->rulenum } );
+}
+
+=item cgp_rule_action
+
+Returns the actions associated with this rule, as FS::cgp_rule_action
+objects.
+
+=cut
+
+sub cgp_rule_action {
+  my $self = shift;
+  qsearch('cgp_rule_action', { 'rulenum' => $self->rulenum } );
+}
+
 =back
 
 =head1 BUGS
 
-The author forgot to customize this manpage.
-
 =head1 SEE ALSO
 
 L<FS::Record>, schema.html from the base documentation.
index b5e4970..6dfd424 100644 (file)
@@ -3,6 +3,7 @@ package FS::cgp_rule_action;
 use strict;
 use base qw( FS::Record );
 use FS::Record qw( qsearch qsearchs );
+use FS::cgp_rule;
 
 =head1 NAME
 
@@ -25,8 +26,9 @@ FS::cgp_rule_action - Object methods for cgp_rule_action records
 
 =head1 DESCRIPTION
 
-An FS::cgp_rule_action object represents an example.  FS::cgp_rule_action inherits from
-FS::Record.  The following fields are currently supported:
+An FS::cgp_rule_action object represents a mail filtering action.
+FS::cgp_rule_action inherits from FS::Record.  The following fields are
+currently supported:
 
 =over 4
 
@@ -55,7 +57,7 @@ rulenum
 
 =item new HASHREF
 
-Creates a new example.  To add the example to the database, see L<"insert">.
+Creates a new action.  To add the action to the database, see L<"insert">.
 
 Note that this stores the hash reference, not a distinct copy of the hash it
 points to.  You can ask the object for a copy with the I<hash> method.
@@ -94,7 +96,7 @@ returns the error, otherwise returns false.
 
 =item check
 
-Checks all fields to make sure this is a valid example.  If there is
+Checks all fields to make sure this is a valid action.  If there is
 an error, returns the error, otherwise returns false.  Called by the insert
 and replace methods.
 
@@ -110,7 +112,7 @@ sub check {
     $self->ut_numbern('ruleactionnum')
     || $self->ut_text('action')
     || $self->ut_text('params')
-    || $self->ut_number('rulenum')
+    || $self->ut_foreign_key('rulenum', 'cgp_rule', 'rulenum')
   ;
   return $error if $error;
 
@@ -121,8 +123,6 @@ sub check {
 
 =head1 BUGS
 
-The author forgot to customize this manpage.
-
 =head1 SEE ALSO
 
 L<FS::Record>, schema.html from the base documentation.
index a8b7e56..f91b3e6 100644 (file)
@@ -3,6 +3,7 @@ package FS::cgp_rule_condition;
 use strict;
 use base qw( FS::Record );
 use FS::Record qw( qsearch qsearchs );
+use FS::cgp_rule;
 
 =head1 NAME
 
@@ -25,8 +26,9 @@ FS::cgp_rule_condition - Object methods for cgp_rule_condition records
 
 =head1 DESCRIPTION
 
-An FS::cgp_rule_condition object represents an example.  FS::cgp_rule_condition inherits from
-FS::Record.  The following fields are currently supported:
+An FS::cgp_rule_condition object represents a mail filtering condition.
+FS::cgp_rule_condition inherits from FS::Record.  The following fields are
+currently supported:
 
 =over 4
 
@@ -59,7 +61,7 @@ rulenum
 
 =item new HASHREF
 
-Creates a new example.  To add the example to the database, see L<"insert">.
+Creates a new condition.  To add the condition to the database, see L<"insert">.
 
 Note that this stores the hash reference, not a distinct copy of the hash it
 points to.  You can ask the object for a copy with the I<hash> method.
@@ -98,7 +100,7 @@ returns the error, otherwise returns false.
 
 =item check
 
-Checks all fields to make sure this is a valid example.  If there is
+Checks all fields to make sure this is a valid condition.  If there is
 an error, returns the error, otherwise returns false.  Called by the insert
 and replace methods.
 
@@ -115,7 +117,7 @@ sub check {
     || $self->ut_text('condition')
     || $self->ut_text('op')
     || $self->ut_text('params')
-    || $self->ut_number('rulenum')
+    || $self->ut_foreign_key('rulenum', 'cgp_rule', 'rulenum')
   ;
   return $error if $error;
 
@@ -126,8 +128,6 @@ sub check {
 
 =head1 BUGS
 
-The author forgot to customize this manpage.
-
 =head1 SEE ALSO
 
 L<FS::Record>, schema.html from the base documentation.
diff --git a/httemplate/browse/cgp_rule.html b/httemplate/browse/cgp_rule.html
new file mode 100644 (file)
index 0000000..3bf4d69
--- /dev/null
@@ -0,0 +1,46 @@
+<% include('elements/browse.html',
+             'title'         => "Rules for $svc_label: $svc_value",
+             'name_singular' => 'rule',
+             'html_init'     => $html_init,
+             'query'         => { 'table'   => 'cgp_rule',
+                                  'hashref' => { 'svcnum' => $svcnum },
+                                  'order_by' => 'ORDER BY priority DESC',
+                                },
+             'count_query'   => $count_query,
+             'header'        => [ 'Priority', 'Name', '' ],
+             'fields'        => [ sub { shift->priority || 'Inactive'; },
+                                  'name',
+                                  sub { 'Delete'; },
+                                ],
+             #'align'
+             'links'         => [ $edit_sub, $edit_sub, $del_sub ],
+          )
+%>
+<%init>
+
+$cgi->param('svcnum') =~ /^(\d+)$/ or die 'no svcnum';
+my $svcnum = $1;
+
+#agent virt so you can't do cross-agent communigate rules
+my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $svcnum })
+  or die 'unknown svcnum';
+
+my $count_query = "SELECT COUNT(*) FROM cgp_rule WHERE svcnum = $svcnum";
+
+my($svc_label, $svc_value, $svcdb) = $cust_svc->label;
+
+
+my $view = FS::UI::Web::svc_url( 'm'        => $m,
+                                 'action'   => 'view',
+                                 'part_svc' => $cust_svc->part_svc, 
+                                 'svc'      => $cust_svc,
+                               );
+
+my $html_init =
+  qq(<A HREF="$view">View this $svc_label</A><BR><BR>).
+  qq!<A HREF="${p}edit/cgp_rule.html?svcnum=$svcnum">Add new rule</A><BR><BR>!;
+
+my $edit_sub = [ $p.'edit/cgp_rule.html?', 'rulenum' ];
+my $del_sub = [ $p.'misc/delete-cgp_rule.html?', 'rulenum' ]; #XXX javascript areyousure or something
+
+</%init>
diff --git a/httemplate/edit/cgp_rule.html b/httemplate/edit/cgp_rule.html
new file mode 100644 (file)
index 0000000..9c03a52
--- /dev/null
@@ -0,0 +1,30 @@
+<% include('elements/edit.html',
+             'name_singular' => 'rule',
+             'table'         => 'cgp_rule',
+             'labels' => { 'rulenum'  => 'Rule',
+                           'name'     => 'Name',
+                           'comment'  => 'Comment',
+                           'priority' => 'Priority',
+                         },
+             'fields' => [ 'name',
+                           'comment',
+                           { 'field'   => 'priority',
+                             'type'    => 'select',
+                             'options' => [ 0 .. 10 ],
+                             'labels'  => { 0 => 'Inactive' },
+                           },
+                           { 'field' => 'svcnum', 'type' => 'hidden', },
+                         ],
+             'new_callback' => sub { my( $cgi, $cgp_rule ) = @_;
+                                     $cgp_rule->svcnum( $cgi->param('svcnum') );
+                                   },
+             #'viewall_url' => $viewall_url,
+             'menubar' => [],
+          )
+%>
+<%init>
+
+#my $svcnum #huh
+#my $viewall_url = $p. "browse/$table.html?svcnum=$svcnum";
+
+</%init>
diff --git a/httemplate/edit/process/cgp_rule.html b/httemplate/edit/process/cgp_rule.html
new file mode 100644 (file)
index 0000000..3880b56
--- /dev/null
@@ -0,0 +1,14 @@
+<% include( 'elements/process.html',
+              'table'    => 'cgp_rule',
+              'redirect' => $redirect,
+          )
+%>
+<%init>
+
+my $redirect = sub {
+  my($cgi, $new) = @_;
+  my $svcnum = $new->svcnum;
+  popurl(3)."browse/cgp_rule.html?svcnum=$svcnum;rulenum=";
+};
+
+</%init>
diff --git a/httemplate/misc/delete-cgp_rule.html b/httemplate/misc/delete-cgp_rule.html
new file mode 100644 (file)
index 0000000..a2ba2db
--- /dev/null
@@ -0,0 +1,23 @@
+% if ( $error ) {
+%   errorpage($error);
+% } else {
+<% $cgi->redirect($p. "browse/cgp_rule.html?svcnum=". $svcnum) %>
+% }
+<%init>
+
+# :/  needs agent-virt so you can't futz with arbitrary rules
+
+#die "access denied"
+#  unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service');
+
+#untaint devicenum
+my($query) = $cgi->keywords;
+$query =~ /^(\d+)$/ || die "Illegal rulenum";
+my $rulenum = $1;
+
+my $cgp_rule = qsearchs('cgp_rule', { 'rulenum' => $rulenum } );
+my $svcnum = $cgp_rule->svcnum;
+
+my $error = $cgp_rule->delete;
+
+</%init>
index 7beb88a..f4c8388 100644 (file)
 
 % } elsif ( $opt{'communigate'} ) {
 
-%# settings
-
-  <% include('/view/elements/tr.html', label=>'Mailbox type', value=>$svc_acct->cgp_type) %>
-
-  <% include('/view/elements/tr.html', label=>'Enabled services',
-                        value=>$svc_acct->cgp_accessmodes ) %>
-
-  <% include('/view/elements/tr.html', label=>'Mail storage limit',
-                        value=>$svc_acct->quota ) %>
-
-  <% include('/view/elements/tr.html', label=>'File storage limit',
-                        value=>$svc_acct->file_quota ) %>
-
-  <% include('/view/elements/tr.html', label=>'Number of files limit',
-                        value=>$svc_acct->file_maxnum ) %>
-
-  <% include('/view/elements/tr.html', label=>'File size limit',
-                        value=>$svc_acct->file_maxsize ) %>
-
-  <% include('/view/elements/tr.html', label=>'Password recovery',
-               value=>$svc_acct->password_recover ? 'YES' : 'NO' ) %>
-
-  <% include('/view/elements/tr.html', label=>'Allowed mail rules',
-                        value=>$svc_acct->cgp_rulesallowed || 'default (No)') %>
-
-  <% include('/view/elements/tr.html', label=>'RPOP modifications',
-                        value=>$svc_acct->cgp_rpopallowed ? 'YES' : 'NO' ) %>
-
-  <% include('/view/elements/tr.html', label=>'Accepts mail to "all"',
-                        value=>$svc_acct->cgp_mailtoall ? 'YES' : 'NO' ) %>
-
-  <% include('/view/elements/tr.html', label=>'Add trailer to sent mail',
-                        value=>$svc_acct->cgp_addmailtrailer ? 'YES' : 'NO' ) %>
-
-%# preferences
-
-  <% include('/view/elements/tr.html', label=>'Message delete method',
-                        value=>$svc_acct->cgp_deletemode ) %>
-
-  <% include('/view/elements/tr.html', label=>'On logout remove trash',
-                        value=>$svc_acct->cgp_emptytrash ) %>
-
-  <% include('/view/elements/tr.html', label=>'Language',
-                        value=>$svc_acct->cgp_language || 'default (English)' ) %>
-  <% include('/view/elements/tr.html', label=>'Time zone',
-                        value=>$svc_acct->cgp_timezone || 'default (HostOS)' ) %>
-  <% include('/view/elements/tr.html', label=>'Layout',
-                        value=>$svc_acct->cgp_skinname || 'default (***)' ) %>
-
-  <% include('/view/elements/tr.html', label=>'Pronto style',
-                        value=>$svc_acct->cgp_prontoskinname ) %>
-
-  <% include('/view/elements/tr.html', label=>'Send read receipts',
-                        value=>$svc_acct->cgp_sendmdnmode ) %>
-
-%#XXX vacation message, redirect all mail, mail rules
+  <% include( 'communigate.html', %opt ) %>
 
 % }
 
diff --git a/httemplate/view/svc_acct/communigate.html b/httemplate/view/svc_acct/communigate.html
new file mode 100644 (file)
index 0000000..9d66807
--- /dev/null
@@ -0,0 +1,77 @@
+%# settings
+
+  <% include('/view/elements/tr.html', label=>'Mailbox type', value=>$svc_acct->cgp_type) %>
+
+  <% include('/view/elements/tr.html', label=>'Enabled services',
+                        value=>$svc_acct->cgp_accessmodes ) %>
+
+  <% include('/view/elements/tr.html', label=>'Mail storage limit',
+                        value=>$svc_acct->quota ) %>
+
+  <% include('/view/elements/tr.html', label=>'File storage limit',
+                        value=>$svc_acct->file_quota ) %>
+
+  <% include('/view/elements/tr.html', label=>'Number of files limit',
+                        value=>$svc_acct->file_maxnum ) %>
+
+  <% include('/view/elements/tr.html', label=>'File size limit',
+                        value=>$svc_acct->file_maxsize ) %>
+
+  <% include('/view/elements/tr.html', label=>'Password recovery',
+               value=>$svc_acct->password_recover ? 'YES' : 'NO' ) %>
+
+  <% include('/view/elements/tr.html', label=>'Allowed mail rules',
+                        value=>$svc_acct->cgp_rulesallowed || 'default (No)') %>
+
+  <% include('/view/elements/tr.html', label=>'RPOP modifications',
+                        value=>$svc_acct->cgp_rpopallowed ? 'YES' : 'NO' ) %>
+
+  <% include('/view/elements/tr.html', label=>'Accepts mail to "all"',
+                        value=>$svc_acct->cgp_mailtoall ? 'YES' : 'NO' ) %>
+
+  <% include('/view/elements/tr.html', label=>'Add trailer to sent mail',
+                        value=>$svc_acct->cgp_addmailtrailer ? 'YES' : 'NO' ) %>
+
+%# preferences
+
+  <% include('/view/elements/tr.html', label=>'Message delete method',
+                        value=>$svc_acct->cgp_deletemode ) %>
+
+  <% include('/view/elements/tr.html', label=>'On logout remove trash',
+                        value=>$svc_acct->cgp_emptytrash ) %>
+
+  <% include('/view/elements/tr.html', label=>'Language',
+                        value=>$svc_acct->cgp_language || 'default (English)' ) %>
+  <% include('/view/elements/tr.html', label=>'Time zone',
+                        value=>$svc_acct->cgp_timezone || 'default (HostOS)' ) %>
+  <% include('/view/elements/tr.html', label=>'Layout',
+                        value=>$svc_acct->cgp_skinname || 'default (***)' ) %>
+
+  <% include('/view/elements/tr.html', label=>'Pronto style',
+                        value=>$svc_acct->cgp_prontoskinname ) %>
+
+  <% include('/view/elements/tr.html', label=>'Send read receipts',
+                        value=>$svc_acct->cgp_sendmdnmode ) %>
+
+%#XXX vacation message, redirect all mail
+
+%# mail rules
+
+  <% include('/view/elements/tr.html', label=>'Mail rules',
+               value=>$rule_link,
+            )
+  %>
+
+<%init>
+
+my %opt = @_;
+
+#my $conf = new FS::Conf;
+
+my $svc_acct = $opt{'svc_acct'};
+#my $part_svc = $opt{'part_svc'};
+
+my $rule_link = qq(<A HREF="${p}browse/cgp_rule.html?svcnum=).
+                      $svc_acct->svcnum. '">View/edit mail rules</A>';
+
+</%init>
index c9841f4..1915719 100644 (file)
@@ -79,10 +79,12 @@ Service #<B><% $svcnum %></B>
   </TD>
 </TR>
 
-<TR>
-  <TD ALIGN="right">Enabled services</TD>
-  <TD BGCOLOR="#ffffff"><% $svc_domain->cgp_accessmodes %></TD>
-</TR>
+% if ( $svc_domain->cgp_accessmodes ) {
+  <TR>
+    <TD ALIGN="right">Enabled services</TD>
+    <TD BGCOLOR="#ffffff"><% $svc_domain->cgp_accessmodes %></TD>
+  </TR>
+% }
 
 % if ( $svc_domain->trailer ) {
   <TR>
@@ -91,6 +93,14 @@ Service #<B><% $svcnum %></B>
   </TR>
 % }
 
+% if ( $communigate ) {
+%   my $rule_url = $p. 'browse/cgp_rule.html?svcnum='. $svc_domain->svcnum;
+    <TR>
+      <TD ALIGN="right">Doimain mail rules</TD>
+      <TD BGCOLOR="#ffffff"><A HREF="<% $rule_url %>">View/Edit domain mail rules</A></TD>
+    </TR>
+% }
+
 </TABLE></TD></TR></TABLE>
 
 <%init>