[freeside-commits] branch master updated. 9972d7caa7a3e1a29dc4201e0c7256ba093ea705

Jonathan Prykop jonathan at 420.am
Thu Mar 10 22:10:51 PST 2016


The branch, master has been updated
       via  9972d7caa7a3e1a29dc4201e0c7256ba093ea705 (commit)
      from  f5ba2c8127ef9fcbfda8c25e0eeb32d05e47fd30 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9972d7caa7a3e1a29dc4201e0c7256ba093ea705
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Fri Mar 11 00:10:13 2016 -0600

    RT#40806: Enter invoice details from order package page

diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm
index 5a14e2e..1c921d6 100644
--- a/FS/FS/cust_main/Packages.pm
+++ b/FS/FS/cust_main/Packages.pm
@@ -74,6 +74,14 @@ Optional subject for a ticket created and attached to this customer
 
 Optional queue name for ticket additions
 
+=item invoice_details
+
+Optional arrayref of invoice detail strings to add (creates cust_pkg_detail detailtype 'I')
+
+=item package_comments
+
+Optional arrayref of package comment strings to add (creates cust_pkg_detail detailtype 'C')
+
 =back
 
 =cut
@@ -208,6 +216,22 @@ sub order_pkg {
     }
   }
 
+  # add details/comments
+  if ($opt->{'invoice_details'}) {
+    $error = $cust_pkg->set_cust_pkg_detail('I', @{$opt->{'invoice_details'}});
+  }
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return "setting invoice details: $error";
+  }
+  if ($opt->{'package_comments'}) {
+    $error = $cust_pkg->set_cust_pkg_detail('C', @{$opt->{'package_comments'}});
+  }
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return "setting package comments: $error";
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   ''; #no error
 
diff --git a/FS/FS/quotation_pkg.pm b/FS/FS/quotation_pkg.pm
index 1e5a0da..b9b3799 100644
--- a/FS/FS/quotation_pkg.pm
+++ b/FS/FS/quotation_pkg.pm
@@ -106,7 +106,11 @@ sub detail_table          { 'quotation_pkg_detail'; }
 =item insert
 
 Adds this record to the database.  If there is an error, returns the error,
-otherwise returns false.
+otherwise returns false.  Accepts the following options:
+
+quotation_details - optional arrayref of detail strings to add (creates quotation_pkg_detail records)
+
+copy_on_order - value for this field when creating quotation_pkg_detail records (same for all details)
 
 =cut
 
@@ -128,10 +132,22 @@ sub insert {
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
-  } else {
-    $dbh->commit if $oldAutoCommit;
-    return '';
   }
+
+  if ($options{'quotation_details'}) {
+    $error = $self->set_details(
+                details => $options{'quotation_details'},
+                copy_on_order => $options{'copy_on_order'} ? 'Y' : '',
+             );
+    if ( $error ) {
+      $error .= ' (setting details)';
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
+  $dbh->commit if $oldAutoCommit;
+  return '';
 }
 
 =item delete
diff --git a/httemplate/edit/cust_pkg_detail.html b/httemplate/edit/cust_pkg_detail.html
index b1e60da..a1a6db6 100644
--- a/httemplate/edit/cust_pkg_detail.html
+++ b/httemplate/edit/cust_pkg_detail.html
@@ -1,9 +1,4 @@
-<% include("/elements/header-popup.html", $title, '',
-            ( $cgi->param('error') ? '' : 'onload="addRow()"' ),
-          )
-%>
-
-%# <% include('/elements/error.html') %>
+<& /elements/header-popup.html, $title &>
 
 <FORM ACTION="process/cust_pkg_detail.html" NAME="DetailForm" ID="DetailForm" METHOD="POST">
 
@@ -40,17 +35,10 @@
     <TD COLSPAN=2><% ucfirst($name{$detailtype}) %>: </TD>
   </TR>
 
-% my $row = 0;
-% for ( @details ) { 
-
-    <TR>
-      <TD></TD>
-      <TD>
-        <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_->detail |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddRow" >
-      </TD>
-    </TR>
-
-% } 
+<& elements/detail-table.html, 
+     id      => 'DetailTable',
+     details => \@details,
+ &>
 
 </TABLE>
 
@@ -59,48 +47,6 @@
 
 </FORM>
 
-<SCRIPT TYPE="text/javascript">
-
-  var rownum = <% $row %>;
-
-  function possiblyAddRow() {
-    if ( ( rownum - this.getAttribute('rownum') ) == 1 ) {
-      addRow();
-    }
-  }
-
-  function addRow() {
-
-    var table = document.getElementById('DetailTable');
-    var tablebody = table.getElementsByTagName('tbody').item(0);
-
-    var row = document.createElement('TR');
-
-    var empty_cell = document.createElement('TD');
-    row.appendChild(empty_cell);
-
-    var detail_cell = document.createElement('TD');
-
-      var detail_input = document.createElement('INPUT');
-      detail_input.setAttribute('name', 'detail'+rownum);
-      detail_input.setAttribute('id',   'detail'+rownum);
-      detail_input.setAttribute('size', 60);
-      detail_input.setAttribute('maxLength', 65);
-      detail_input.setAttribute('rownum',   rownum);
-      detail_input.onkeyup = possiblyAddRow;
-      detail_input.onchange = possiblyAddRow;
-      detail_cell.appendChild(detail_input);
-
-    row.appendChild(detail_cell);
-
-    tablebody.appendChild(row);
-
-    rownum++;
-
-  }
-
-</SCRIPT>
-
 </BODY>
 </HTML>
 <%init>
@@ -136,7 +82,7 @@ my $cust_pkg = qsearchs({
 
 my $part_pkg = $cust_pkg->part_pkg;
 
-my @details = $cust_pkg->cust_pkg_detail($detailtype);
+my @details = map { $_->detail } $cust_pkg->cust_pkg_detail($detailtype);
 
 my $title = ( scalar(@details) ? 'Edit ' : 'Add ' ). $name{$detailtype};
 
diff --git a/httemplate/edit/elements/detail-table.html b/httemplate/edit/elements/detail-table.html
new file mode 100644
index 0000000..496ba31
--- /dev/null
+++ b/httemplate/edit/elements/detail-table.html
@@ -0,0 +1,85 @@
+<%doc>
+Common code for editing invoice/quotation details/comments.
+
+Expects to be the last element in a two-column table with specified id
+
+  <& /edit/elements/detail-table.html, 
+       id      => 'element_id', # required
+       details => \@details,    # plain text strings, existing details
+       label   => 'Comments',   # optional, shows on first row only
+       field   => 'comment',    # input field name/id, appended with rownum, default 'detail'
+  &>
+
+</%doc>
+
+<SCRIPT>
+% unless ($detail_table_init) {
+%   $detail_table_init = 1;
+
+  var detail_table_info = {};
+  detail_table_info.rownum = {};
+  detail_table_info.label  = {};
+  detail_table_info.field  = {};
+
+  function possiblyAddDetailRow(tableid,rownum) {
+    if (( detail_table_info.rownum[tableid] - rownum == 1 ) || !detail_table_info.rownum[tableid]) {
+      addDetailRow(tableid);
+    }
+  }
+
+  function addDetailRow(tableid,newtext) {
+
+    var table = document.getElementById(tableid);
+    var newrownum = detail_table_info.rownum[tableid];
+    var newfield  = detail_table_info.field[tableid] + newrownum;
+
+    var row = document.createElement('TR');
+
+    var empty_cell = document.createElement('TD');
+    if (!newrownum) {
+      empty_cell.innerHTML = detail_table_info.label[tableid];
+      empty_cell.style.textAlign = 'right';
+    }
+    row.appendChild(empty_cell);
+
+    var detail_cell = document.createElement('TD');
+
+    var detail_input = document.createElement('INPUT');
+    detail_input.setAttribute('name', newfield);
+    detail_input.setAttribute('id',   newfield);
+    detail_input.setAttribute('size', 60);
+    detail_input.setAttribute('maxLength', 65);
+    detail_input.onkeyup = function () { possiblyAddDetailRow(tableid,newrownum) };
+    detail_input.onchange = function () { possiblyAddDetailRow(tableid,newrownum) };
+    detail_input.value = newtext || '';
+    detail_cell.appendChild(detail_input);
+
+    row.appendChild(detail_cell);
+
+    table.appendChild(row);
+
+    detail_table_info.rownum[tableid]++;
+
+  }
+% } # end init
+  detail_table_info.label['<% $id %>'] = '<% emt($label) %>';
+  detail_table_info.field['<% $id %>'] = '<% $field %>';
+  detail_table_info.rownum['<% $id %>'] = 0;
+% foreach my $detail ( @details ) { 
+  addDetailRow('<% $id %>','<% $detail %>');
+% } 
+</SCRIPT>
+
+<%shared>
+my $detail_table_init = 0;
+</%shared>
+<%init>
+my %opt = @_;
+
+my @details = $opt{'details'} ? @{ $opt{'details'} } : ();
+push(@details,'') if $details[$#details] || !@details;
+my $id = $opt{'id'} or die "No id specified";
+my $label = $opt{'label'} || '';
+my $field = $opt{'field'} || 'detail';
+
+</%init>
diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi
index 6035215..5afddde 100644
--- a/httemplate/edit/process/quick-cust_pkg.cgi
+++ b/httemplate/edit/process/quick-cust_pkg.cgi
@@ -159,14 +159,38 @@ foreach my $quantity_param ( grep { $cgi->param($_) && $cgi->param($_) > 0 }
 }
 $hash{cust_pkg_usageprice} = \@cust_pkg_usageprice;
 
+# extract details (false laziness with /misc/order_pkg.html)
+my $details = {
+  'invoice_detail' => [],
+  'package_comment' => [],
+  'quotation_detail' => [],
+};
+foreach my $field ( $cgi->param ) {
+  foreach my $detailtype ( keys %$details ) {
+    if ($field =~ /^$detailtype(\d+)$/) {
+      $details->{$detailtype}->[$1] = $cgi->param($field);
+    }
+  }
+}
+foreach my $detailtype ( keys %$details ) {
+  @{ $details->{$detailtype} } = grep { length($_) } @{ $details->{$detailtype} };
+}
+
 if ( $quotationnum ) {
 
   $quotation_pkg = new FS::quotation_pkg \%hash;
   $quotation_pkg->quotationnum($quotationnum);
   $quotation_pkg->prospectnum($prospect_main->prospectnum) if $prospect_main;
 
+  my %opt = @{ $details->{'quotation_detail'} }
+  ? (
+    quotation_details => $details->{'quotation_detail'},
+    copy_on_order     => scalar($cgi->param('copy_on_order')) ? 'Y' : '',
+  )
+  : ();
+
   #XXX handle new location
-  $error = $quotation_pkg->insert;
+  $error = $quotation_pkg->insert(%opt);
 
 } else {
 
@@ -194,6 +218,9 @@ if ( $quotationnum ) {
     $opt{'locationnum'} = $locationnum;
   }
 
+  $opt{'invoice_details'} = $details->{'invoice_detail'} if @{ $details->{'invoice_detail'} };
+  $opt{'package_comments'} = $details->{'package_comment'} if @{ $details->{'package_comment'} };
+
   $error = $cust_main->order_pkg( \%opt );
 
 }
diff --git a/httemplate/edit/quotation_pkg_detail.html b/httemplate/edit/quotation_pkg_detail.html
index ae09b9c..036bffd 100644
--- a/httemplate/edit/quotation_pkg_detail.html
+++ b/httemplate/edit/quotation_pkg_detail.html
@@ -1,9 +1,4 @@
-<% include("/elements/header-popup.html", $title, '',
-            ( $cgi->param('error') ? '' : 'onload="addRow()"' ),
-          )
-%>
-
-%# <% include('/elements/error.html') %>
+<& /elements/header-popup.html, $title &>
 
 <FORM ACTION="process/quotation_pkg_detail.html" NAME="DetailForm" ID="DetailForm" METHOD="POST">
 
@@ -35,17 +30,11 @@
     </TD>
   </TR>
 
-% my $row = 0;
-% for ( @details ) { 
-
-    <TR>
-      <TD ALIGN="right"><% $row ? '' : 'Detail' %></TD>
-      <TD>
-        <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_ |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddrow">
-      </TD>
-    </TR>
-
-% } 
+<& elements/detail-table.html, 
+     id      => 'DetailTable',
+     details => \@details,
+     label   => 'Details',
+ &>
 
 </TABLE>
 
@@ -54,53 +43,6 @@
 
 </FORM>
 
-<SCRIPT TYPE="text/javascript">
-% # abject false laziness with edit/cust_pkg_detail.html
-
-  var rownum = <% $row %>;
-
-  function possiblyAddRow() {
-    if ( ( rownum - this.getAttribute('rownum') ) == 1 ) {
-      addRow();
-    }
-  }
-
-  function addRow() {
-
-    var table = document.getElementById('DetailTable');
-    var tablebody = table.getElementsByTagName('tbody').item(0);
-
-    var row = document.createElement('TR');
-
-    var empty_cell = document.createElement('TD');
-    if (!rownum) {
-      empty_cell.innerHTML = 'Detail:'
-      empty_cell.style.textAlign = 'right';
-    }
-    row.appendChild(empty_cell);
-
-    var detail_cell = document.createElement('TD');
-
-      var detail_input = document.createElement('INPUT');
-      detail_input.setAttribute('name', 'detail'+rownum);
-      detail_input.setAttribute('id',   'detail'+rownum);
-      detail_input.setAttribute('size', 60);
-      detail_input.setAttribute('maxLength', 65);
-      detail_input.setAttribute('rownum',   rownum);
-      detail_input.onkeyup = possiblyAddRow;
-      detail_input.onchange = possiblyAddRow;
-      detail_cell.appendChild(detail_input);
-
-    row.appendChild(detail_cell);
-
-    tablebody.appendChild(row);
-
-    rownum++;
-
-  }
-
-</SCRIPT>
-
 </BODY>
 </HTML>
 <%init>
diff --git a/httemplate/misc/order_pkg.html b/httemplate/misc/order_pkg.html
index 4e061e2..39cb2f4 100644
--- a/httemplate/misc/order_pkg.html
+++ b/httemplate/misc/order_pkg.html
@@ -196,6 +196,52 @@
 
 % }
 
+% if ($quotationnum) {
+<BR>
+<FONT CLASS="fsinnerbox-title"><% mt('Quotation details') |h %></FONT>
+<TABLE ID="QuotationDetailTable" BORDER="0" BGCOLOR="#cccccc">
+  <TR>
+    <TD></TD>
+    <TD>
+      <SELECT NAME="copy_on_order">
+        <OPTION VALUE=""<% $copy_on_order ? '' : ' SELECTED' %>>
+          <% emt('Details will only appear on quotation') %>
+        </OPTION>
+        <OPTION VALUE="Y"<% $copy_on_order ? ' SELECTED' : '' %>>
+          <% emt('Copy details to invoice when placing order') %>
+        </OPTION>
+      </SELECT>
+    </TD>
+  </TR>
+<& /edit/elements/detail-table.html, 
+     id      => 'QuotationDetailTable',
+     details => $details->{'quotation_detail'},
+     field   => 'quotation_detail',
+ &>
+</TABLE>
+% } else {
+<BR>
+<FONT CLASS="fsinnerbox-title"><% mt('Invoice details') |h %></FONT>
+<TABLE ID="InvoiceDetailTable" BORDER="0" BGCOLOR="#cccccc">
+<& /edit/elements/detail-table.html, 
+     id      => 'InvoiceDetailTable',
+     details => $details->{'invoice_detail'},
+     field   => 'invoice_detail',
+ &>
+</TABLE>
+
+<BR>
+<FONT CLASS="fsinnerbox-title"><% mt('Package comments') |h %></FONT>
+<TABLE ID="PackageCommentTable" BORDER="0" BGCOLOR="#cccccc">
+<& /edit/elements/detail-table.html, 
+     id      => 'PackageCommentTable',
+     details => $details->{'package_comment'},
+     field   => 'package_comment',
+ &>
+</TABLE>
+% }
+
+
 <BR>
 % my $onclick = $cgi->param('lock_locationnum')
 %                 ? 'document.OrderPkgForm.submit()'
@@ -245,6 +291,23 @@ if ( $cgi->param('quotationnum') =~ /^(\d+)$/ ) {
   $quotationnum = $1;
 }
 
+my $details = {
+  'invoice_detail' => [],
+  'package_comment' => [],
+  'quotation_detail' => [],
+};
+foreach my $field ( $cgi->param ) {
+  foreach my $detailtype ( keys %$details ) {
+    if ($field =~ /^$detailtype(\d+)$/) {
+      $details->{$detailtype}->[$1] = $cgi->param($field);
+    }
+  }
+}
+foreach my $detailtype ( keys %$details ) {
+  @{ $details->{$detailtype} } = grep { length($_) } @{ $details->{$detailtype} };
+}
+my $copy_on_order = $cgi->param('copy_on_order');
+
 die 'no custnum or prospectnum' unless $cust_main || $prospect_main;
 
 my $agent =  $cust_main ? $cust_main->agent

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/cust_main/Packages.pm                |   24 ++++++++
 FS/FS/quotation_pkg.pm                     |   24 ++++++--
 httemplate/edit/cust_pkg_detail.html       |   66 ++-------------------
 httemplate/edit/elements/detail-table.html |   85 ++++++++++++++++++++++++++++
 httemplate/edit/process/quick-cust_pkg.cgi |   29 +++++++++-
 httemplate/edit/quotation_pkg_detail.html  |   70 ++---------------------
 httemplate/misc/order_pkg.html             |   63 +++++++++++++++++++++
 7 files changed, 232 insertions(+), 129 deletions(-)
 create mode 100644 httemplate/edit/elements/detail-table.html




More information about the freeside-commits mailing list