summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/cust_main/Packages.pm24
-rw-r--r--FS/FS/quotation_pkg.pm24
-rw-r--r--httemplate/edit/cust_pkg_detail.html66
-rw-r--r--httemplate/edit/elements/detail-table.html85
-rw-r--r--httemplate/edit/process/quick-cust_pkg.cgi29
-rw-r--r--httemplate/edit/quotation_pkg_detail.html70
-rw-r--r--httemplate/misc/order_pkg.html63
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