one-time charge enhancements
authorjeff <jeff>
Fri, 12 Jan 2007 02:04:50 +0000 (02:04 +0000)
committerjeff <jeff>
Fri, 12 Jan 2007 02:04:50 +0000 (02:04 +0000)
FS/FS/cust_main.pm
FS/FS/part_pkg/flat.pm
httemplate/edit/process/quick-charge.cgi
httemplate/edit/quick-charge.html [new file with mode: 0644]
httemplate/view/cust_main/packages.html

index 8603bde..0534686 100644 (file)
@@ -1904,7 +1904,7 @@ sub bill {
     
       warn "    bill setup\n" if $DEBUG > 1;
 
     
       warn "    bill setup\n" if $DEBUG > 1;
 
-      $setup = eval { $cust_pkg->calc_setup( $time ) };
+      $setup = eval { $cust_pkg->calc_setup( $time, \@details ) };
       if ( $@ ) {
         $dbh->rollback if $oldAutoCommit;
         return "$@ running calc_setup for $cust_pkg\n";
       if ( $@ ) {
         $dbh->rollback if $oldAutoCommit;
         return "$@ running calc_setup for $cust_pkg\n";
@@ -3615,10 +3615,22 @@ the error, otherwise returns false.
 =cut
 
 sub charge {
 =cut
 
 sub charge {
-  my ( $self, $amount ) = ( shift, shift );
-  my $pkg      = @_ ? shift : 'One-time charge';
-  my $comment  = @_ ? shift : '$'. sprintf("%.2f",$amount);
-  my $taxclass = @_ ? shift : '';
+  my $self = shift;
+  my ( $amount, $pkg, $comment, $taxclass, $additional );
+  if ( ref( $_[0] ) ) {
+    $amount     = $_[0]->{amount};
+    $pkg        = exists($_[0]->{pkg}) ? $_[0]->{pkg} : 'One-time charge';
+    $comment    = exists($_[0]->{comment}) ? $_[0]->{comment}
+                                           : '$'. sprintf("%.2f",$amount);
+    $taxclass   = exists($_[0]->{taxclass}) ? $_[0]->{taxclass} : '';
+    $additional = $_[0]->{additional};
+  }else{
+    $amount     = shift;
+    $pkg        = @_ ? shift : 'One-time charge';
+    $comment    = @_ ? shift : '$'. sprintf("%.2f",$amount);
+    $taxclass   = @_ ? shift : '';
+    $additional = [];
+  }
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -3634,16 +3646,20 @@ sub charge {
   my $part_pkg = new FS::part_pkg ( {
     'pkg'      => $pkg,
     'comment'  => $comment,
   my $part_pkg = new FS::part_pkg ( {
     'pkg'      => $pkg,
     'comment'  => $comment,
-    #'setup'    => $amount,
-    #'recur'    => '0',
     'plan'     => 'flat',
     'plan'     => 'flat',
-    'plandata' => "setup_fee=$amount",
     'freq'     => 0,
     'disabled' => 'Y',
     'taxclass' => $taxclass,
   } );
 
     'freq'     => 0,
     'disabled' => 'Y',
     'taxclass' => $taxclass,
   } );
 
-  my $error = $part_pkg->insert;
+  my %options = ( ( map { ("additional_info$_" => $additional->[$_] ) }
+                        ( 0 .. @$additional - 1 )
+                  ),
+                  'additional_count' => scalar(@$additional),
+                  'setup_fee' => $amount,
+                );
+
+  my $error = $part_pkg->insert( options => \%options );
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
index 39be379..f4031ec 100644 (file)
@@ -60,7 +60,13 @@ use FS::part_pkg;
 );
 
 sub calc_setup {
 );
 
 sub calc_setup {
-  my($self, $cust_pkg ) = @_;
+  my($self, $cust_pkg, $sdate, $details ) = @_;
+
+  my ( $i, $count ) = ( 0, $self->option( 'additional_count' ) );
+  while ($i < $count) {
+    push @$details, $self->option( 'additional_info' . $i++ );
+  }
+
   $self->option('setup_fee');
 }
 
   $self->option('setup_fee');
 }
 
index 2c5ac81..f614dd5 100644 (file)
@@ -1,41 +1,47 @@
-%#untaint custnum
-%$cgi->param('custnum') =~ /^(\d+)$/
-%  or die 'illegal custnum '. $cgi->param('custnum');
-%my $custnum = $1;
 %
 %
-%$cgi->param('amount') =~ /^\s*\$?\s*(\d+(\.\d{1,2})?)\s*$/
-%  or die 'illegal amount '. $cgi->param('amount');
-%my $amount = $1;
-%
-%my( $error, $cust_main);
-%if ( $cgi->param('taxclass') eq '(select)' ) {
-%
-%
-% $error = 'Must select a tax class';
-%} else {
-%
-%  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
-%    or die "unknown custnum $custnum";
-%
-%  $error = $cust_main->charge(
-%    $amount,
-%    $cgi->param('pkg'),
-%    '$'. sprintf("%.2f",$amount),
-%    $cgi->param('taxclass')
-%  );
-%
-%}
-%
-%if ($error) {
-%
-
-<!-- mason kludge -->
-%
-%  eidiot($error);
-%} else {
-%  print $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum" );
-%}
-%
-%
-
+%  my $error = '';
+%  my $param = $cgi->Vars;
+%
+%  my @description = ();
+%  for ( my $row = 0; exists($param->{"description$row"}); $row++ ) {
+%    push @description, $param->{"description$row"};
+%  }
+%  pop @description until ($description[$#description]);
+%
+%  $param->{"custnum"} =~ /^(\d+)$/
+%    or $error .= "Illegal customer number " . $param->{"custnum"} . "  ";
+%  my $custnum = $1;
+%
+%  $param->{"amount"} =~ /^\s*(\d+(\.\d{1,2})?)\s*$/
+%    or $error .= "Illegal amount " . $param->{"amount"} . "  ";
+%  my $amount = $1;
+%
+%  if ( $param->{'taxclass'} eq '(select)' ) {
+%    $error .= "Must select a tax class.  ";
+%  }
+%
+%  unless ( $error ) {
+%    my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+%      or $error .= "Unknown customer number $custnum.  ";
+%
+%    $error ||= $cust_main->charge({ 'amount'   => $amount,
+%                                   'pkg'      => $cgi->param('pkg'),
+%                                   'taxclass' => $cgi->param('taxclass'),
+%                                   'additional' => \@description,
+%                                 }
+%                               );
+%  }
+%
+%  if ( $error ) {
+%
+%    $cgi->param('error', "$error" );
+%    
+<% $cgi->redirect($p.'quick-charge.html?'. $cgi->query_string) %>
+%
+% }
+<% header("One-time charge added") %>
+  <SCRIPT TYPE="text/javascript">
+    window.top.location.reload();
+  </SCRIPT>
+  </BODY></HTML>
 
 
diff --git a/httemplate/edit/quick-charge.html b/httemplate/edit/quick-charge.html
new file mode 100644 (file)
index 0000000..b30285c
--- /dev/null
@@ -0,0 +1,163 @@
+<% include("/elements/header-popup.html", 'One-time charge entry', '',
+            ( $cgi->param('error') ? '' : 'onload="addRow()"' ),
+          )
+%>
+% if ( $cgi->param('error') ) { 
+
+  <FONT SIZE="+1" COLOR="#ff0000"><% $cgi->param('error') %></FONT><BR><BR>
+% } 
+
+<SCRIPT TYPE="text/javascript">
+
+function enable_quick_charge () {
+  if (    document.QuickChargeForm.amount.value
+       && document.QuickChargeForm.pkg.value    ) {
+    document.QuickChargeForm.submit.disabled = false;
+  } else {
+    document.QuickChargeForm.submit.disabled = true;
+  }
+}
+
+function enable_quick_charge_desc () {
+  if (  document.QuickChargeForm.amount.value ) {
+    document.QuickChargeForm.submit.disabled = false;
+  } else {
+    document.QuickChargeForm.submit.disabled = true;
+  }
+}
+
+function enable_quick_charge_amount () {
+  if ( document.QuickChargeForm.pkg.value ) {
+    document.QuickChargeForm.submit.disabled = false;
+  } else {
+    document.QuickChargeForm.submit.disabled = true;
+  }
+}
+
+function validate_quick_charge () {
+  var pkg = document.QuickChargeForm.pkg.value;
+  var pkg_regex = /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]]*)$/ ;
+  var amount = document.QuickChargeForm.amount.value;
+  var amount_regex = /^\s*\$?\s*(\d+(\.\d{1,2})?)\s*$/ ;
+  var rval = true;
+
+  if ( ! amount_regex.test(amount) ) {
+    alert('Illegal amount - enter an amount to charge, for example, "5" or "43" or "21.46".');
+    return false;
+  }
+  if ( String(pkg).length < 1 ) {
+    rval = false;
+  }
+  if ( ! pkg_regex.test(pkg) ) {
+    rval = false;
+  }
+  var i=0;
+  for (i=0; i < rownum; i++) {
+    if (! eval('pkg_regex.test(document.QuickChargeForm.description' + i + '.value)')){
+      rval = false;
+      break;
+    }
+  }
+  if (rval == true) {
+    return true;
+  }
+
+  if ( ! pkg ) {
+    alert('Enter a description for the one-time charge');
+    return false;
+  }
+
+  alert('Illegal description - spaces, letters, numbers, and the following punctuation characters are allowed: . , ! ? @ # $ % & ( ) - + ; : ' + "'" + ' " = [ ]' );
+  return false;
+}
+
+</SCRIPT>
+
+
+
+<FORM ACTION="process/quick-charge.cgi" NAME="QuickChargeForm" METHOD="POST" onsubmit="document.QuickChargeForm.submit.disabled=true;return validate_quick_charge();">
+
+<INPUT TYPE="hidden" NAME="custnum" VALUE="<% $cgi->param('custnum') %>">
+<TABLE ID="QuickChargeTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0>
+
+<TR>
+  <TD>Amount:</TD>
+  <TD>
+    $<INPUT TYPE="text" NAME="amount" SIZE=6 VALUE="<% $cgi->param('amount') %>" onChange="enable_quick_charge()" on KeyPress="enable_quick_charge_amount()">
+  </TD>
+  <TD>
+    <% include('/elements/select-taxclass.html') %>
+  </TD>
+</TR>
+  <TD>Description:</TD>
+  <TD>
+    <INPUT TYPE="text" NAME="pkg" SIZE="60" MAXLENGTH="65" VALUE="<% $cgi->param('pkg') %>" onChange="enable_quick_charge()" onKeyPress="enable_quick_charge_desc()">
+  </TD>
+</TR>
+% my $row = 0;
+%   if ( $cgi->param('error') ) {
+%     my $param = $cgi->Vars;
+%
+% for ( $row = 0; exists($param->{"description$row"}); $row++ ) { 
+
+    <TR>
+      <TD></TD>
+      <TD>
+        <INPUT TYPE="text" NAME="description<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $param->{"description$row"} %>" rownum="<% $row %>" onkeyup = "possiblyAddRow;" >
+      </TD>
+    </TR>
+% } 
+% } 
+
+
+</TABLE>
+
+<BR>
+<INPUT TYPE="submit" NAME="submit" VALUE="Add one-time charge" DISABLED>
+
+</FORM>
+
+
+<SCRIPT TYPE="text/javascript">
+
+  var rownum = <% $row %>;
+
+  function possiblyAddRow() {
+    if ( ( rownum - this.getAttribute('rownum') ) == 1 ) {
+      addRow();
+    }
+  }
+
+  function addRow() {
+
+    var table = document.getElementById('QuickChargeTable');
+    var tablebody = table.getElementsByTagName('tbody').item(0);
+
+    var row = document.createElement('TR');
+
+    var empty_cell = document.createElement('TD');
+    row.appendChild(empty_cell);
+
+    var description_cell = document.createElement('TD');
+
+      var description_input = document.createElement('INPUT');
+      description_input.setAttribute('name', 'description'+rownum);
+      description_input.setAttribute('id',   'description'+rownum);
+      description_input.setAttribute('size', 60);
+      description_input.setAttribute('maxlength', 65);
+      description_input.setAttribute('rownum',   rownum);
+      description_input.onkeyup = possiblyAddRow;
+      description_cell.appendChild(description_input);
+
+    row.appendChild(description_cell);
+
+    tablebody.appendChild(row);
+
+    rownum++;
+
+  }
+
+</SCRIPT>
+
+</BODY>
+</HTML>
index 37f3ec4..6ec92ef 100755 (executable)
@@ -16,7 +16,8 @@
 %      ) {
 %
 
 %      ) {
 %
 
-  <% include('quick-charge.html', $cust_main ) %>
+  <% popup_link('edit/quick-charge.html?custnum='. $cust_main->custnum, 'One-time charge', 'One-time charge', 684) %>
+  <BR>
 % } 
 % if ( $curuser->access_right('Bulk change customer packages') ) { 
 
 % } 
 % if ( $curuser->access_right('Bulk change customer packages') ) { 
 
@@ -518,19 +519,19 @@ Current packages
 %  my($action, $label, $actionlabel, $cust_pkg) = @_;
 %  $action .= '&pkgnum='. $cust_pkg->pkgnum;
 %  $actionlabel .= ' package '. $cust_pkg->pkgnum;
 %  my($action, $label, $actionlabel, $cust_pkg) = @_;
 %  $action .= '&pkgnum='. $cust_pkg->pkgnum;
 %  $actionlabel .= ' package '. $cust_pkg->pkgnum;
-%  popup_link($action, $label, $actionlabel);
+%  popup_link($action, $label, $actionlabel, 392);
 %}
 %
 %sub svc_popup_link {
 %  my($action, $label, $actionlabel, $cust_svc) = @_;
 %  $action .= '?svcnum='. $cust_svc->svcnum;
 %  $actionlabel .= ' service '. $cust_svc->svcnum;
 %}
 %
 %sub svc_popup_link {
 %  my($action, $label, $actionlabel, $cust_svc) = @_;
 %  $action .= '?svcnum='. $cust_svc->svcnum;
 %  $actionlabel .= ' service '. $cust_svc->svcnum;
-%  popup_link($action, $label, $actionlabel);
+%  popup_link($action, $label, $actionlabel, 392);
 %}
 %
 %sub popup_link {
 %}
 %
 %sub popup_link {
-%  my($action, $label, $actionlabel) = @_;
-%  qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('$p$action', 392, 336, 'pkg_or_svc_action_popup' ), CAPTION, '$actionlabel', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">$label</A>!;
+%  my($action, $label, $actionlabel, $width) = @_;
+%  qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('$p$action', $width, 336, 'pkg_or_svc_action_popup' ), CAPTION, '$actionlabel', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">$label</A>!;
 %}
 %
 %sub pkg_customize_link {
 %}
 %
 %sub pkg_customize_link {