push out event triggered suspensions
authorjeff <jeff>
Fri, 26 Sep 2008 03:56:40 +0000 (03:56 +0000)
committerjeff <jeff>
Fri, 26 Sep 2008 03:56:40 +0000 (03:56 +0000)
FS/FS/AccessRight.pm
FS/FS/cust_main.pm
FS/FS/part_bill_event.pm
httemplate/edit/part_bill_event.cgi
httemplate/misc/delay_susp_pkg.html [new file with mode: 0755]
httemplate/misc/process/delay_susp_pkg.html [new file with mode: 0755]
httemplate/view/cust_main/packages.html

index 27486da..856a5f5 100644 (file)
@@ -112,6 +112,7 @@ assigned to users and/or groups.
   'Unsuspend customer package',
   'Cancel customer package immediately',
   'Cancel customer package later',
+  'Delay suspension events',
   'Add on-the-fly cancel reason', #NEW
   'Add on-the-fly suspend reason', #NEW
   'Edit customer package invoice details', #NEW
index 697f478..c0cdfba 100644 (file)
@@ -227,6 +227,8 @@ Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit nu
 
 =item spool_cdr - Enable individual CDR spooling, empty or `Y'
 
+=item dundate - a suggestion to events (see L<FS::part_bill_event">) to delay until this unix timestamp
+
 =back
 
 =head1 METHODS
index 683f484..7d00117 100644 (file)
@@ -4,6 +4,8 @@ use strict;
 use vars qw( @ISA $DEBUG @EXPORT_OK );
 use FS::Record qw( dbh qsearch qsearchs );
 use FS::Conf;
+use FS::cust_main;
+use FS::cust_bill;
 
 @ISA = qw( FS::Record );
 @EXPORT_OK = qw( due_events );
@@ -234,6 +236,9 @@ sub due_events {
   sort {    $a->seconds   <=> $b->seconds
          || $a->weight    <=> $b->weight
         || $a->eventpart <=> $b->eventpart }
+    grep { ref($record) ne 'FS::cust_bill' || $_->eventcode !~ /honor_dundate/
+           || $event_time > $record->cust_main->dundate
+         }
     grep { $_->seconds <= ( $interval )
            && ! qsearch( 'cust_bill_event', {
                           'invnum' => $record->get($record->dbdef_table->primary_key),
index e6639b9..9449213 100755 (executable)
@@ -101,6 +101,18 @@ Invoice Event #<% $hashref->{eventpart} ? $hashref->{eventpart} : "(NEW)" %>
 %  '</SELECT>';
 %}
 %
+%sub honor_dundate {
+%  my $label = shift;
+%  my $plandata = shift;
+%  '<TABLE>'.
+%  '<TR><TD ALIGN="right">Allow delay until dun date? </TD>'.
+%  qq(<TD><INPUT TYPE="checkbox" NAME="$label" VALUE="$label => 1," ).
+%    ( $plandata->{$label} eq "$label => 1," ? 'CHECKED' : '' ).
+%  '>'.
+%  '</TD></TR>'.
+%  '</TABLE>'
+%}
+%
 %my $conf = new FS::Conf;
 %my $money_char = $conf->config('money_char') || '$';
 %
@@ -140,28 +152,29 @@ Invoice Event #<% $hashref->{eventpart} ? $hashref->{eventpart} : "(NEW)" %>
 %  },
 %  'suspend' => {
 %    'name'   => 'Suspend',
-%    'code'   => '$cust_main->suspend(reason => %%%sreason%%%);',
+%    'code'   => '$cust_main->suspend(reason => %%%sreason%%%, %%%honor_dundate%%% );',
+%    'html'   => sub { &honor_dundate('honor_dundate', @_) },
 %    'weight' => 10,
 %    'reason' => 'S',
 %  },
 %  'suspend-if-balance' => {
 %    'name'   => 'Suspend if balance (this invoice and previous) over',
-%    'code'   => '$cust_bill->cust_suspend_if_balance_over( %%%balanceover%%%, reason => %%%sreason%%%, );',
-%    'html'   => " $money_char ". '<INPUT TYPE="text" SIZE="7" NAME="balanceover" VALUE="%%%balanceover%%%">',
+%    'code'   => '$cust_bill->cust_suspend_if_balance_over( %%%balanceover%%%, reason => %%%sreason%%%, %%%balance_honor_dundate%%% );',
+%    'html'   => sub { " $money_char ". '<INPUT TYPE="text" SIZE="7" NAME="balanceover" VALUE="%%%balanceover%%%"> '. &honor_dundate('balance_honor_dundate', @_) },
 %    'weight' => 10,
 %    'reason' => 'S',
 %  },
 %  'suspend-if-pkgpart' => {
 %    'name'   => 'Suspend packages',
-%    'code'   => '$cust_main->suspend_if_pkgpart({pkgparts => [%%%if_pkgpart%%%,], reason => %%%sreason%%%,});',
-%    'html'   => sub { &select_pkgpart('if_pkgpart', @_) },
+%    'code'   => '$cust_main->suspend_if_pkgpart({pkgparts => [%%%if_pkgpart%%%,], reason => %%%sreason%%%, %%%if_pkgpart_honor_dundate%%% });',
+%    'html'   => sub { &select_pkgpart('if_pkgpart', @_). &honor_dundate('if_pkgpart_honor_dundate', @_) },
 %    'weight' => 10,
 %    'reason' => 'S',
 %  },
 %  'suspend-unless-pkgpart' => {
 %    'name'   => 'Suspend packages except',
-%    'code'   => '$cust_main->suspend_unless_pkgpart({unless_pkgpart => [%%%unless_pkgpart%%%], reason => %%%sreason%%%,});',
-%    'html'   => sub { &select_pkgpart('unless_pkgpart', @_) },
+%    'code'   => '$cust_main->suspend_unless_pkgpart({unless_pkgpart => [%%%unless_pkgpart%%%], reason => %%%sreason%%%, %%%unless_pkgpart_honor_dundate%%% });',
+%    'html'   => sub { &select_pkgpart('unless_pkgpart', @_). &honor_dundate('unless_pkgpart_honor_dundate' => @_) },
 %    'weight' => 10,
 %    'reason' => 'S',
 %  },
diff --git a/httemplate/misc/delay_susp_pkg.html b/httemplate/misc/delay_susp_pkg.html
new file mode 100755 (executable)
index 0000000..0755309
--- /dev/null
@@ -0,0 +1,73 @@
+%# if ( $link eq 'popup' ) { 
+  <% include('/elements/header-popup.html', $title ) %>
+%# } else { 
+%#  <%  include("/elements/header.html", $title, '') %>
+%# } 
+
+<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
+<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+
+<% include('/elements/error.html') %>
+
+<FORM NAME="ds_popup" ACTION="<% popurl(1) %>process/delay_susp_pkg.html" METHOD=POST>
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
+
+<BR><BR>
+<% "Delay automatic suspension of $pkgnum: " .$part_pkg->pkg. ' - ' .$part_pkg->comment %>
+<% ntable("#cccccc", 2) %>
+
+<TR>
+  <TD>Delay until</TD>
+    <TD><INPUT TYPE="text" NAME="date" ID="dun_date" VALUE="<% $date |h %>">
+        <IMG SRC="<% $p %>images/calendar.png" ID="dun_button" STYLE="cursor:pointer" TITLE="Select date">
+        <BR><I>m/d/y</I>
+    </TD>
+</TR>
+<SCRIPT TYPE="text/javascript">
+  Calendar.setup({
+    inputField: "dun_date",
+    ifFormat:   "%m/%d/%Y",
+    button:     "dun_button",
+    align:      "BR"
+  });
+</SCRIPT>
+
+</TABLE>
+
+<BR>
+<INPUT TYPE="submit" NAME="submit" VALUE="<% $submit %>">
+
+</FORM>
+</BODY>
+</HTML>
+
+<%init>
+
+my $date = time2str("%m/%d/%Y", time);
+
+my($pkgnum);
+if ( $cgi->param('error') ) {
+  $pkgnum    = $cgi->param('pkgnum');
+  $date      = $cgi->param('date');
+} elsif ( $cgi->param('pkgnum') =~ /^(\d+)$/ ) {
+  $pkgnum    = $1;
+} else {
+  die "illegal query ". $cgi->keywords;
+}
+
+my $submit = 'Delay Suspension';
+my $right  = 'Delay suspension events';
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die "access denied" unless $curuser->access_right($right);
+
+my $title = 'Delay Suspension of Package';
+
+my $cust_pkg = qsearchs('cust_pkg', {'pkgnum' => $pkgnum})
+  or die "Unknown pkgnum: $pkgnum";
+
+my $part_pkg = $cust_pkg->part_pkg;
+
+</%init>
diff --git a/httemplate/misc/process/delay_susp_pkg.html b/httemplate/misc/process/delay_susp_pkg.html
new file mode 100755 (executable)
index 0000000..c7cc7de
--- /dev/null
@@ -0,0 +1,41 @@
+<% header("Package suspension delayed") %>
+  <SCRIPT TYPE="text/javascript">
+    window.top.location.reload();
+  </SCRIPT>
+  </BODY>
+</HTML>
+<%once>
+
+my $right = 'Delay suspension events';
+
+</%once>
+<%init>
+
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right($right);
+
+my ($pkgnum, $date, $cust_pkg, $cust_main, $error);
+
+#untaint pkgnum
+$cgi->param('pkgnum') =~ /^(\d+)$/ or die "Illegal pkgnum";
+$pkgnum = $1;
+
+#untaint date
+str2time($cgi->param('date')) =~ /^(\d+)$/ or die "Illegal date";
+my $date = $1;
+
+$cust_pkg = qsearchs( 'cust_pkg', {'pkgnum'=>$pkgnum} );
+if ($cust_pkg) {
+  $cust_main = $cust_pkg->cust_main;
+  $cust_main->dundate( $date );
+  $error = $cust_main->replace;
+} else {
+  $error = "Invalid pkgnum";
+}
+
+if ($error) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(2). "cancel_pkg.html?". $cgi->query_string );
+}
+
+</%init>
index 5c086f2..63e31dd 100755 (executable)
@@ -392,6 +392,9 @@ Current packages
 %             if ( $curuser->access_right('Suspend customer package later') ) { 
                 (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
 %             } 
+%             if ( $curuser->access_right('Delay suspension events') ) { 
+                (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
+%             } 
 %             if ( $curuser->access_right('Cancel customer package immediately') ) { 
                 (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
 %             } 
@@ -656,6 +659,15 @@ sub pkg_suspend_link { include( '/elements/popup_link-cust_pkg.html',
                               )
                      }
 
+sub pkg_delay_link   { include( '/elements/popup_link-cust_pkg.html',
+                                { 'action'      => $p. 'misc/delay_susp_pkg.html',
+                                  'label'       => 'Delay&nbsp;suspend',
+                                  'actionlabel' => 'Delay suspend for',
+                                  'cust_pkg'    => shift,
+                                }
+                              )
+                     }
+
 sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg',    'Unsuspend',           @_ ); }
 sub pkg_expire_link    { pkg_link('misc/expire_pkg',    'Cancel&nbsp;later',   @_ ); }
 sub pkg_unadjourn_link { pkg_link('misc/unadjourn_pkg', 'Abort',               @_ ); }