summaryrefslogtreecommitdiff
path: root/httemplate/edit
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2015-10-23 16:17:51 -0700
committerIvan Kohler <ivan@freeside.biz>2015-10-23 16:17:51 -0700
commit80c2d997c5c983344c530ecbb46f94f1c299b35f (patch)
tree28bafc1d55836acb5455e6554941c06f0912ef98 /httemplate/edit
parent3b1a5e8789d76f0581079d07190664f57bd773a3 (diff)
parent0806f9fdbf2086671c151b3bcb078dc008e96f6c (diff)
Merge branch 'master' of git.freeside.biz:/home/git/freeside
Diffstat (limited to 'httemplate/edit')
-rw-r--r--httemplate/edit/cust_pkg_detail.html3
-rwxr-xr-xhttemplate/edit/cust_pkg_discount.html66
-rw-r--r--httemplate/edit/elements/rate_detail.html8
-rw-r--r--httemplate/edit/log_email.html45
-rw-r--r--httemplate/edit/msg_template/email.html6
-rw-r--r--httemplate/edit/process/cust_pkg_discount.html96
-rw-r--r--httemplate/edit/process/elements/process.html2
-rw-r--r--httemplate/edit/process/log_email.html18
-rw-r--r--httemplate/edit/process/quick-cust_pkg.cgi29
-rw-r--r--httemplate/edit/process/quotation_pkg_detail.html45
-rw-r--r--httemplate/edit/process/rate_detail.html16
-rw-r--r--httemplate/edit/quotation_pkg_detail.html116
-rw-r--r--httemplate/edit/rate.cgi10
13 files changed, 381 insertions, 79 deletions
diff --git a/httemplate/edit/cust_pkg_detail.html b/httemplate/edit/cust_pkg_detail.html
index 5e107066d..b1e60dad5 100644
--- a/httemplate/edit/cust_pkg_detail.html
+++ b/httemplate/edit/cust_pkg_detail.html
@@ -46,7 +46,7 @@
<TR>
<TD></TD>
<TD>
- <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_->detail |h %>" rownum="<% $row++ %>" onkeyup = "possiblyAddRow;" >
+ <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_->detail |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddRow" >
</TD>
</TR>
@@ -88,6 +88,7 @@
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);
diff --git a/httemplate/edit/cust_pkg_discount.html b/httemplate/edit/cust_pkg_discount.html
index 0bb84b8f2..e1e3daede 100755
--- a/httemplate/edit/cust_pkg_discount.html
+++ b/httemplate/edit/cust_pkg_discount.html
@@ -1,18 +1,5 @@
-<% include('/elements/header-popup.html', "Discount Package") %>
-
-<SCRIPT TYPE="text/javascript">
-
- function enable_discount_pkg () {
- if ( document.DiscountPkgForm.discountnum.selectedIndex > 0 ) {
- document.DiscountPkgForm.submit.disabled = false;
- } else {
- document.DiscountPkgForm.submit.disabled = true;
- }
- }
-
-</SCRIPT>
-
-<% include('/elements/error.html') %>
+<& /elements/header-popup.html, "Discount Package" &>
+<& /elements/error.html &>
<FORM NAME="DiscountPkgForm" ACTION="<% $p %>edit/process/cust_pkg_discount.html" METHOD=POST>
<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
@@ -26,17 +13,17 @@
</TD>
</TR>
-<% include('/elements/tr-select-discount.html',
- 'empty_label' => ( $pkgdiscountnum ? '' : 'Select discount' ),
- 'onchange' => 'enable_discount_pkg()',
- 'cgi' => $cgi,
- )
-%>
-
+<& /elements/tr-select-pkg-discount.html,
+ curr_value_setup => $setup_discountnum,
+ curr_value_recur => $recur_discountnum,
+ disable_setup => $disable_setup,
+ disable_recur => $disable_recur,
+&>
+
</TABLE>
<BR>
-<INPUT NAME="submit" TYPE="submit" VALUE="Discount package" <% $pkgdiscountnum ? '' : 'DISABLED' %>>
+<INPUT NAME="submit" TYPE="submit" VALUE="Discount package">
</FORM>
</BODY>
@@ -44,14 +31,13 @@
<%init>
-#some false laziness w/misc/change_pkg.cgi
-
my $conf = new FS::Conf;
my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $curuser->access_right('Discount customer package');
+ unless $curuser->access_right([ 'Discount customer package',
+ 'Waive setup fee']);
my $pkgnum = scalar($cgi->param('pkgnum'));
$pkgnum =~ /^(\d+)$/ or die "illegal pkgnum $pkgnum";
@@ -67,10 +53,30 @@ my $cust_pkg =
'extra_sql' => ' AND '. $curuser->agentnums_sql,
}) or die "unknown pkgnum $pkgnum";
-#my $cust_main = $cust_pkg->cust_main
-# or die "can't get cust_main record for custnum ". $cust_pkg->custnum.
-# " ( pkgnum ". cust_pkg->pkgnum. ")";
-
my $part_pkg = $cust_pkg->part_pkg;
+my @discounts = $cust_pkg->cust_pkg_discount_active;
+my ($setup_discountnum, $recur_discountnum);
+foreach (@discounts) {
+ if ( $_->setuprecur eq 'setup') {
+ die "multiple setup discounts on pkg#$pkgnum" if $setup_discountnum;
+ $setup_discountnum = $_->discountnum;
+ } elsif ( $_->setuprecur eq 'recur' ) {
+ die "multiple setup discounts on pkg#$pkgnum" if $recur_discountnum;
+ $recur_discountnum = $_->discountnum;
+ }
+}
+if ( $cust_pkg->waive_setup ) {
+ $setup_discountnum = -2;
+}
+
+my $disable_setup = 1;
+if ( !$cust_pkg->get('setup') and $cust_pkg->base_setup > 0 ) {
+ $disable_setup = 0;
+}
+my $disable_recur = 1;
+if ( $cust_pkg->base_recur > 0 ) {
+ $disable_recur = 0;
+}
+
</%init>
diff --git a/httemplate/edit/elements/rate_detail.html b/httemplate/edit/elements/rate_detail.html
index 7b5ec314a..32dd502ce 100644
--- a/httemplate/edit/elements/rate_detail.html
+++ b/httemplate/edit/elements/rate_detail.html
@@ -61,18 +61,18 @@ with row headers showing the region name and prefixes.
% $row++;
% }# foreach @rate_region
% if ( !$opt{regionnum} ) {
-%# global default
+% # global default for this cdrtypenum
<TR>
<TD COLSPAN=2 STYLE="padding-top: 10px">
<B>Global default</B> (for calls not matching any prefix)
</TD>
<TD STYLE="padding-top: 10px">
-% # default rate: set a null region
+% # default rate: set a null region for this cdr type
<B>
<& .detail_box,
- detail => $rate->default_detail,
+ detail => $rate->default_detail($cdrtypenum),
ratetimenum => '',
- cdrtypenum => '',
+ cdrtypenum => $cdrtypenum,
regionnum => '',
ratenum => $rate->ratenum
&>
diff --git a/httemplate/edit/log_email.html b/httemplate/edit/log_email.html
new file mode 100644
index 000000000..bbce7c708
--- /dev/null
+++ b/httemplate/edit/log_email.html
@@ -0,0 +1,45 @@
+<% include( 'elements/edit.html',
+ 'name_singular' => 'log email condition',
+ 'table' => 'log_email',
+ 'fields' => [
+ { 'field' => 'context',
+ 'type' => 'select',
+ 'options' => [ '', @contexts ],
+ 'labels' => { '' => '(all)', map { $_ => $_ } @contexts },
+ 'curr_value' => scalar($cgi->param('context')),
+ },
+ { 'field' => 'min_level',
+ 'type' => 'select',
+ 'options' => [ 0..7 ],
+ 'labels' => { map {$_ => $FS::Log::LEVELS[$_]} 0..7 },
+ 'curr_value' => scalar($cgi->param('min_level')),
+ },
+ 'to_addr',
+ { 'field' => 'msgnum',
+ 'type' => 'select-msg_template',
+ 'empty_label' => 'Select template',
+ 'required' => 1,
+ },
+ ],
+ 'labels' => {
+ 'context' => 'Context',
+ 'min_level' => 'Min. Level',
+ 'to_addr' => 'To',
+ 'msgnum' => 'Message',
+ },
+ 'viewall_dir' => 'browse',
+ 'popup' => $opts{'popup'},
+ 'form_init' => $opts{'popup'} ? q(<INPUT TYPE="hidden" NAME="popup" VALUE="1">) : '',
+ )
+%>
+<%once>
+my @contexts = sort FS::log_context->contexts;
+</%once>
+<%init>
+
+my %opts = @_;
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right([ 'View system logs', 'Configuration' ]);
+
+</%init>
diff --git a/httemplate/edit/msg_template/email.html b/httemplate/edit/msg_template/email.html
index dc70ef6ec..b0c1aa31a 100644
--- a/httemplate/edit/msg_template/email.html
+++ b/httemplate/edit/msg_template/email.html
@@ -302,6 +302,11 @@ my %substitutions = (
'$payinfo' => 'Card/account# (masked)',
'$error' => 'Decline reason',
],
+ 'system_log' => [
+ '$logmessage' => 'Log entry message',
+ '$loglevel' => 'Log entry level',
+ '$logcontext' => 'Log entry context',
+ ],
);
tie my %sections, 'Tie::IxHash', (
@@ -315,6 +320,7 @@ tie my %sections, 'Tie::IxHash', (
'svc_domain'=> 'Domain service fields',
'svc_phone' => 'Phone service fields',
'svc_broadband' => 'Broadband service fields',
+'system_log' => 'System log fields',
);
my $widget = new HTML::Widgets::SelectLayers(
diff --git a/httemplate/edit/process/cust_pkg_discount.html b/httemplate/edit/process/cust_pkg_discount.html
index 4a71f6975..143611ef9 100644
--- a/httemplate/edit/process/cust_pkg_discount.html
+++ b/httemplate/edit/process/cust_pkg_discount.html
@@ -14,9 +14,8 @@
<%init>
my $curuser = $FS::CurrentUser::CurrentUser;
-
-die "access denied"
- unless $curuser->access_right('Discount customer package');
+my $can_discount = $curuser->access_right('Discount customer package');
+my $can_waive_setup = $curuser->access_right('Waive setup fee');
#this search is really for security wrt agent virt...
#maybe move it to the cust_pkg_discount->insert call?
@@ -29,20 +28,81 @@ my $cust_pkg = qsearchs({
});
die 'unknown pkgnum' unless $cust_pkg;
-my $cust_pkg_discount = new FS::cust_pkg_discount {
- 'pkgnum' => $cust_pkg->pkgnum,
- 'discountnum' => scalar($cgi->param('discountnum')),
- 'months_used' => 0,
- 'end_date' => '', #XXX
- #for the create a new discount case
- '_type' => scalar($cgi->param('discountnum__type')),
- 'amount' => scalar($cgi->param('discountnum_amount')),
- 'percent' => scalar($cgi->param('discountnum_percent')),
- 'months' => scalar($cgi->param('discountnum_months')),
- 'setup' => scalar($cgi->param('discountnum_setup')),
- #'linked' => scalar($cgi->param('discountnum_linked')),
- #'disabled' => $self->discountnum_disabled,
-};
-my $error = $cust_pkg_discount->insert;
+my $error;
+my %discountnum = (setup => '', recur => '');
+if ( $cgi->param('setup_discountnum') == -2 ) {
+
+ die "access denied" unless $can_waive_setup; # UI protects against this
+ # waive setup fee (not really a discount but treated as one in the UI)
+ if ( !$cust_pkg->get('setup') and !$cust_pkg->waive_setup ) {
+ $cust_pkg->set('waive_setup' => 'Y');
+ $error = $cust_pkg->replace;
+ }
+
+} else {
+ if ( $cgi->param('setup_discountnum') =~ /^(-?\d+)$/ ) {
+ $discountnum{setup} = $1;
+ }
+ if ( $cust_pkg->waive_setup ) {
+ $cust_pkg->set('waive_setup', '');
+ $error = $cust_pkg->replace;
+ }
+}
+
+if ( $cgi->param('recur_discountnum') =~ /^(-?\d+)$/ ) {
+
+ $discountnum{recur} = $1;
+
+}
+
+my @active_discounts = $cust_pkg->cust_pkg_discount_active;
+
+foreach my $setuprecur (qw(setup recur)) {
+
+ if ( $cust_pkg->get('setup') and $setuprecur eq 'setup' ) {
+ # no point allowing setup discounts to be edited for a previously setup
+ # package
+ next;
+ }
+
+ my ($active) = grep { $_->setuprecur eq $setuprecur } @active_discounts;
+
+ if ( $active ) {
+ if ( $active->discount ne $discountnum{$setuprecur} ) {
+ $active->set('disabled' => 'Y');
+ $error ||= $active->replace;
+ undef $active;
+ } else {
+ # it's the same discountnum; don't touch it
+ next;
+ }
+ }
+
+ if ( $discountnum{$setuprecur} ) {
+ die "access_denied" unless $can_discount;
+ my $cust_pkg_discount = FS::cust_pkg_discount->new({
+ 'pkgnum' => $cust_pkg->pkgnum,
+ 'discountnum' => $discountnum{$setuprecur},
+ 'setuprecur' => $setuprecur,
+ 'months_used' => 0,
+ 'end_date' => '', #XXX
+ #for the create a new discount case
+ '_type' => scalar($cgi->param($setuprecur.'_discountnum__type')),
+ 'amount' => scalar($cgi->param($setuprecur.'_discountnum_amount')),
+ 'percent' => scalar($cgi->param($setuprecur.'_discountnum_percent')),
+ });
+ if ( $setuprecur eq 'setup' ) {
+ $cust_pkg_discount->set('setup' => 'Y');
+ $cust_pkg_discount->set('months' => 1);
+ } else {
+ if ( $cgi->param($setuprecur.'_discountnum_months') =~ /^(\w+)$/ ) {
+ $cust_pkg_discount->set('months' => $1);
+ }
+ }
+
+ $error ||= $cust_pkg_discount->insert;
+
+ }
+} # foreach $setuprecur
</%init>
diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html
index a76f4befb..fd12c61d9 100644
--- a/httemplate/edit/process/elements/process.html
+++ b/httemplate/edit/process/elements/process.html
@@ -164,7 +164,9 @@ process();
% # some false laziness with the above
% my ($form_name, $job_fields) = @{ $opt{'progress_init'} };
<form name="<% $form_name %>">
+ <input type="hidden" name="<% $pkey %>" value="<% $new->get($pkey) %>">
% foreach my $field (@$job_fields) {
+% next if $field eq $pkey;
<input type="hidden" name="<% $field %>" value="<% $cgi->param($field) |h %>">
% }
<& /elements/progress-init.html,
diff --git a/httemplate/edit/process/log_email.html b/httemplate/edit/process/log_email.html
new file mode 100644
index 000000000..769e180a8
--- /dev/null
+++ b/httemplate/edit/process/log_email.html
@@ -0,0 +1,18 @@
+<% include('elements/process.html',
+ 'table' => 'log_email',
+ %processopts
+ ) %>
+<%init>
+
+my %opts = @_;
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+ unless $curuser->access_right([ 'View system logs', 'Configuration' ]);
+
+my %processopts = $opts{'popup'}
+ ? ( 'popup_reload' => 'Logging email added' )
+ : ( 'redirect' => $fsurl.'browse/log_email.html?' ); # id will be needlessly appended, should be harmless
+
+</%init>
diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi
index f1d8c2696..60352154a 100644
--- a/httemplate/edit/process/quick-cust_pkg.cgi
+++ b/httemplate/edit/process/quick-cust_pkg.cgi
@@ -79,9 +79,6 @@ my $contactnum = $1;
$cgi->param('locationnum') =~ /^(\-?\d*)$/
or die 'illegal locationnum '. $cgi->param('locationnum');
my $locationnum = $1;
-$cgi->param('discountnum') =~ /^(\-?\d*)$/
- or die 'illegal discountnum '. $cgi->param('discountnum');
-my $discountnum = $1;
# for going right to a provision service after ordering a package
my( $svcpart, $part_svc ) = ( '', '' );
@@ -114,19 +111,29 @@ my %hash = (
'refnum' => $refnum,
'contactnum' => $contactnum,
'locationnum' => $locationnum,
- 'discountnum' => $discountnum,
- #for the create a new discount case
- 'discountnum__type' => scalar($cgi->param('discountnum__type')),
- 'discountnum_amount' => scalar($cgi->param('discountnum_amount')),
- 'discountnum_percent' => scalar($cgi->param('discountnum_percent')),
- 'discountnum_months' => scalar($cgi->param('discountnum_months')),
- 'discountnum_setup' => scalar($cgi->param('discountnum_setup')),
'contract_end' => ( scalar($cgi->param('contract_end'))
? parse_datetime($cgi->param('contract_end'))
: ''
),
- 'waive_setup' => ( $cgi->param('waive_setup') eq 'Y' ? 'Y' : '' ),
);
+
+if ( $cgi->param('setup_discountnum') =~ /^(-?\d+)$/ ) {
+ if ( $1 == -2 ) {
+ $hash{waive_setup} = 'Y';
+ } else {
+ $hash{setup_discountnum} = $1;
+ $hash{setup_discountnum_amount} = $cgi->param('setup_discountnum_amount');
+ $hash{setup_discountnum_percent} = $cgi->param('setup_discountnum_percent');
+ }
+}
+
+if ( $cgi->param('recur_discountnum') =~ /^(-?\d+)$/ ) {
+ $hash{recur_discountnum} = $1;
+ $hash{recur_discountnum_amount} = $cgi->param('recur_discountnum_amount');
+ $hash{recur_discountnum_percent} = $cgi->param('recur_discountnum_percent');
+ $hash{recur_discountnum_months} = $cgi->param('recur_discountnum_months');
+}
+
$hash{'custnum'} = $cust_main->custnum if $cust_main;
if ( $cgi->param('start') eq 'on_hold' ) {
diff --git a/httemplate/edit/process/quotation_pkg_detail.html b/httemplate/edit/process/quotation_pkg_detail.html
new file mode 100644
index 000000000..2fc420280
--- /dev/null
+++ b/httemplate/edit/process/quotation_pkg_detail.html
@@ -0,0 +1,45 @@
+% if ( $error ) {
+<% header('Error') %>
+<FONT COLOR="#ff0000"><B><% $error |h %></B></FONT><BR><BR>
+<CENTER><INPUT TYPE="BUTTON" VALUE="OK" onClick="parent.cClick()"></CENTER>
+</BODY></HTML>
+% } else {
+<% header($action) %>
+ <SCRIPT TYPE="text/javascript">
+ window.top.location.reload();
+ </SCRIPT>
+ </BODY></HTML>
+% }
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+ unless $curuser->access_right('Generate quotation');
+
+$cgi->param('pkgnum') =~ /^(\d+)$/ or die 'illegal pkgnum';
+my $pkgnum = $1;
+
+my $quotation_pkg = qsearchs({
+ 'table' => 'quotation_pkg',
+ 'addl_from' => 'LEFT JOIN quotation USING ( quotationnum )'.
+ 'LEFT JOIN cust_main USING ( custnum )',
+ 'hashref' => { 'quotationpkgnum' => $pkgnum },
+ 'extra_sql' => ' AND '. $curuser->agentnums_sql,
+});
+
+my @orig_details = $quotation_pkg->details();
+
+my $action = 'Quotation details'.
+ ( scalar(@orig_details) ? ' changed ' : ' added ' );
+
+my $param = $cgi->Vars;
+my @details = ();
+for ( my $row = 0; exists($param->{"detail$row"}); $row++ ) {
+ push @details, $param->{"detail$row"}
+ if $param->{"detail$row"} =~ /\S/;
+}
+
+my $error = $quotation_pkg->set_details(@details);
+
+</%init>
diff --git a/httemplate/edit/process/rate_detail.html b/httemplate/edit/process/rate_detail.html
index f8a744418..4020ce9e2 100644
--- a/httemplate/edit/process/rate_detail.html
+++ b/httemplate/edit/process/rate_detail.html
@@ -2,7 +2,7 @@
'table' => 'rate_detail',
'popup_reload' => 'Rate changed', #a popup "parent reload" for now
#someday change the individual element and go away instead
- 'noerror_callback' => $set_default_detail
+ #'noerror_callback' => $set_default_detail
&>
<%init>
@@ -12,19 +12,11 @@ die "access denied"
my $set_default_detail = sub {
my ($cgi, $rate_detail) = @_;
- if (!$rate_detail->dest_regionnum) {
+ if (!$rate_detail->dest_regionnum and !$rate_detail->cdrtypenum) {
# then this is a global default rate
+ # default_detailnum is no longer used, but maintain it anyway (and point
+ # it at the one with null cdrtypenum)
my $rate = $rate_detail->rate;
- if ($rate->default_detailnum) {
- if ($rate->default_detailnum == $rate_detail->ratedetailnum) {
- return;
- } else {
- # there's somehow an existing default rate. remove it.
- my $old_default = $rate->default_detail;
- my $error = $old_default->delete;
- die "$error (removing old default rate)\n" if $error;
- }
- }
$rate->set('default_detailnum' => $rate_detail->ratedetailnum);
my $error = $rate->replace;
die "$error (setting default rate)\n" if $error;
diff --git a/httemplate/edit/quotation_pkg_detail.html b/httemplate/edit/quotation_pkg_detail.html
new file mode 100644
index 000000000..b8f589a9a
--- /dev/null
+++ b/httemplate/edit/quotation_pkg_detail.html
@@ -0,0 +1,116 @@
+<% include("/elements/header-popup.html", $title, '',
+ ( $cgi->param('error') ? '' : 'onload="addRow()"' ),
+ )
+%>
+
+%# <% include('/elements/error.html') %>
+
+<FORM ACTION="process/quotation_pkg_detail.html" NAME="DetailForm" ID="DetailForm" METHOD="POST">
+
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
+
+<TABLE ID="DetailTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=1 STYLE="background-color: #cccccc">
+
+ <TR>
+ <TD ALIGN="right">Package</TD>
+ <TD BGCOLOR="#ffffff"><% $part_pkg->pkg %></TD>
+ </TR>
+
+ <TR>
+ <TD ALIGN="right">Comment</TD>
+ <TD BGCOLOR="#ffffff"><% $part_pkg->comment |h %></TD>
+ </TR>
+
+ <TR>
+ <TD COLSPAN=2>Detail: </TD>
+ </TR>
+
+% my $row = 0;
+% for ( @details ) {
+
+ <TR>
+ <TD></TD>
+ <TD>
+ <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_ |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddrow">
+ </TD>
+ </TR>
+
+% }
+
+</TABLE>
+
+<BR>
+<INPUT TYPE="submit" ID="submit" NAME="submit" VALUE="<% $title %>">
+
+</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');
+ 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>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+ unless $curuser->access_right('Generate quotation');
+
+$cgi->param('pkgnum') =~ /^(\d+)$/ or die 'illegal pkgnum';
+my $pkgnum = $1;
+
+my $quotation_pkg = qsearchs({
+ 'table' => 'quotation_pkg',
+ 'addl_from' => 'LEFT JOIN quotation USING ( quotationnum )'.
+ 'LEFT JOIN cust_main USING ( custnum )',
+ 'hashref' => { 'quotationpkgnum' => $pkgnum },
+ 'extra_sql' => ' AND '. $curuser->agentnums_sql,
+});
+
+my $part_pkg = $quotation_pkg->part_pkg;
+
+my @details = $quotation_pkg->details;
+
+my $title = ( scalar(@details) ? 'Edit ' : 'Add ' ). 'Quotation Details';
+
+</%init>
diff --git a/httemplate/edit/rate.cgi b/httemplate/edit/rate.cgi
index 1b052d62d..5bfc108c1 100644
--- a/httemplate/edit/rate.cgi
+++ b/httemplate/edit/rate.cgi
@@ -1,7 +1,11 @@
-<% include("/elements/header.html","$action Rate plan", menubar(
+<& /elements/header.html,
+ "$action Rate plan",
+ menubar(
'View all rate plans' => "${p}browse/rate.cgi",
- ))
-%>
+ 'View packages that use this plan' => "${p}browse/part_pkg.cgi?ratenum="
+ . $rate->ratenum,
+ )
+&>
<% include('/elements/progress-init.html',
'OneTrueForm',