diff options
-rw-r--r-- | FS/FS/cust_main/Packages.pm | 24 | ||||
-rw-r--r-- | FS/FS/quotation_pkg.pm | 24 | ||||
-rw-r--r-- | httemplate/edit/cust_pkg_detail.html | 66 | ||||
-rw-r--r-- | httemplate/edit/elements/detail-table.html | 85 | ||||
-rw-r--r-- | httemplate/edit/process/quick-cust_pkg.cgi | 29 | ||||
-rw-r--r-- | httemplate/edit/quotation_pkg_detail.html | 70 | ||||
-rw-r--r-- | httemplate/misc/order_pkg.html | 63 |
7 files changed, 232 insertions, 129 deletions
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 |