summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
authorJonathan Prykop <jonathan@freeside.biz>2015-09-10 21:33:37 -0500
committerJonathan Prykop <jonathan@freeside.biz>2015-09-14 23:05:54 -0500
commit205cf3b843285a5858f1d6387386381564a5deca (patch)
tree2bf54867b4a4105c610147d3f28cfab99b0d3a31 /httemplate
parentb78bb7aeaa27daab707106217b33e4096e985262 (diff)
RT#33410: Package GB add-ons
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/edit/process/change-cust_pkg.html39
-rw-r--r--httemplate/elements/cust_pkg_usageprice.html9
-rw-r--r--httemplate/elements/order_pkg.js68
-rwxr-xr-xhttemplate/misc/change_pkg.cgi23
-rw-r--r--httemplate/misc/cust_pkg_usageprice.html121
-rw-r--r--httemplate/misc/order_pkg.html21
-rw-r--r--httemplate/misc/xmlhttp-part_pkg_usageprice.html18
7 files changed, 199 insertions, 100 deletions
diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html
index 046a9795c..308ea8ffd 100644
--- a/httemplate/edit/process/change-cust_pkg.html
+++ b/httemplate/edit/process/change-cust_pkg.html
@@ -59,6 +59,40 @@ unless ($error) {
$error = $cust_pkg->change_later(\%change);
}
} else {
+
+ # for now, can't change usageprice with change_later
+ my @old_cust_pkg_usageprice = $cust_pkg->cust_pkg_usageprice;
+
+ # build new usageprice array
+ # false laziness with /edit/process/quick-cust_pkg.cgi
+ my @cust_pkg_usageprice = ();
+ foreach my $quantity_param ( grep { $cgi->param($_) && $cgi->param($_) > 0 }
+ grep /^usagepricenum(\d+)_quantity$/,
+ $cgi->param
+ )
+ {
+ $quantity_param =~ /^usagepricenum(\d+)_quantity$/ or die 'unpossible';
+ my $num = $1;
+ push @cust_pkg_usageprice, new FS::cust_pkg_usageprice {
+ usagepricepart => scalar($cgi->param("usagepricenum${num}_usagepricepart")),
+ quantity => scalar($cgi->param($quantity_param)),
+ };
+ }
+
+ # Need to figure out if usagepricepart quantities changed
+ my %oldup = map { $_->usagepricepart, $_->quantity } @old_cust_pkg_usageprice;
+ my %newup = map { $_->usagepricepart, $_->quantity } @cust_pkg_usageprice;
+ my $usagechanged = 0;
+ foreach my $up (keys %oldup) {
+ last if $usagechanged;
+ $usagechanged = 1 unless $oldup{$up} == $newup{$up};
+ }
+ foreach my $up (keys %newup) {
+ last if $usagechanged;
+ $usagechanged = 1 unless $oldup{$up} == $newup{$up};
+ }
+ $change{'cust_pkg_usageprice'} = \@cust_pkg_usageprice;
+
# special case: if there's a package change scheduled, and it matches
# the parameters the user requested this time, then change to the existing
# future package.
@@ -68,12 +102,13 @@ unless ($error) {
$change_to->pkgpart == $change{'pkgpart'} and
$change_to->locationnum == $change{'locationnum'} and
$change_to->quantity == $change{'quantity'} and
- $change_to->contract_end == $change{'contract_end'}
+ $change_to->contract_end == $change{'contract_end'} and
+ !$usagechanged
) {
%change = ( 'cust_pkg' => $change_to );
}
}
-
+
# do a package change right now
my $pkg_or_error = $cust_pkg->change( \%change );
$error = ref($pkg_or_error) ? '' : $pkg_or_error;
diff --git a/httemplate/elements/cust_pkg_usageprice.html b/httemplate/elements/cust_pkg_usageprice.html
index 729099320..74b7842be 100644
--- a/httemplate/elements/cust_pkg_usageprice.html
+++ b/httemplate/elements/cust_pkg_usageprice.html
@@ -23,15 +23,16 @@
>
% my $info = $part_pkg_usageprice->target_info;
% my $amount = $part_pkg_usageprice->amount / ($info->{multiplier}||1);
- <OPTION VALUE="">Additional <% $info->{label} %>
+ <OPTION VALUE="">Additional <% $info->{label} %></OPTION>
% for (1..100) { #100? arbitrary.
- <OPTION VALUE="<% $_ %>"><%
+% my $selected = ($opt{'curr_quantity'} == $_) ? ' SELECTED' : '';
+ <OPTION VALUE="<% $_ %>"<% $selected %>><%
$money_char. sprintf('%.2f', $_ * $part_pkg_usageprice->price ).
' '.
'for'. #( $part_pkg_usageprice->action eq 'increment' ? 'per' : 'for' ).
' '.
( $_ * $amount ). ' '. $info->{label}
- %>
+ %></OPTION>
% }
</SELECT>
</TD>
@@ -42,8 +43,6 @@
% }
<%init>
-#my $targets = FS::part_pkg_usageprice->targets;
-
my( %opt ) = @_;
my $conf = new FS::Conf;
diff --git a/httemplate/elements/order_pkg.js b/httemplate/elements/order_pkg.js
index 3586a54cb..a850d2193 100644
--- a/httemplate/elements/order_pkg.js
+++ b/httemplate/elements/order_pkg.js
@@ -1,10 +1,12 @@
function pkg_changed () {
var form = document.OrderPkgForm;
var discountnum = form.discountnum;
+ var opt = form.pkgpart.options[form.pkgpart.selectedIndex];
+
+ usageprice_pkg_changed( opt.value );
if ( form.pkgpart.selectedIndex > 0 ) {
- var opt = form.pkgpart.options[form.pkgpart.selectedIndex];
var date_button = document.getElementById('start_date_button');
var date_button_disabled = document.getElementById('start_date_disabled');
var date_text = document.getElementById('start_date_text');
@@ -68,78 +70,14 @@ function pkg_changed () {
}
}
- get_part_pkg_usageprice( opt.value, update_part_pkg_usageprice );
-
} else {
form.submitButton.disabled = true;
if ( discountnum ) { form.discountnum.disabled = true; }
discountnum_changed(form.discountnum);
}
-}
-
-function update_part_pkg_usageprice(part_pkg_usageprice) {
-
- var table = document.getElementById('cust_pkg_usageprice_table');
-
- // black the current usage price rows
- for ( var r = table.rows.length - 1; r >= 0; r-- ) {
- table.deleteRow(r);
- }
-
- // add the new usage price rows
- var rownum = 0;
- var usagepriceArray = eval('(' + part_pkg_usageprice + ')' );
- for ( var s = 0; s < usagepriceArray.length; s=s+2 ) {
- //surely this should be some kind of JSON structure
- var html = usagepriceArray[s+0];
- var javascript = usagepriceArray[s+1];
-
- // a lot like ("inspiried by") edit/elements/edit.html function spawn_<%$field%>
-
- // XXX evaluate the javascript
- //if (window.ActiveXObject) {
- // window.execScript(newfunc);
- //} else { /* (window.XMLHttpRequest) */
- // //window.eval(newfunc);
- // setTimeout(newfunc, 0);
- //}
-
- var row = table.insertRow(rownum++);
-
- //var label_cell = document.createElement('TD');
-
- //label_cell.id = '<% $field %>_label' + <%$field%>_fieldnum;
-
- //label_cell.style.textAlign = "right";
- //label_cell.style.verticalAlign = "top";
- //label_cell.style.borderTop = "1px solid black";
- //label_cell.style.paddingTop = "5px";
-
- //label_cell.innerHTML = '<% $label %>';
-
- //row.appendChild(label_cell);
-
- var widget_cell = document.createElement('TD');
-
- //widget_cell.style.borderTop = "1px solid black";
- widget_cell.style.paddingTop = "3px";
- widget_cell.colSpan = "2";
-
- widget_cell.innerHTML = html;
-
- row.appendChild(widget_cell);
-
- }
-
- if ( rownum > 0 ) {
- document.getElementById('cust_pkg_usageprice_title').style.display = '';
- } else {
- document.getElementById('cust_pkg_usageprice_title').style.display = 'none';
- }
}
-
function standardize_new_location() {
var form = document.OrderPkgForm;
var loc = form.locationnum;
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
index e74747e82..b562d24cd 100755
--- a/httemplate/misc/change_pkg.cgi
+++ b/httemplate/misc/change_pkg.cgi
@@ -19,13 +19,13 @@
<& /elements/tr-select-cust-part_pkg.html,
'pre_label' => emt('New'),
- 'curr_value' => scalar($cgi->param('pkgpart')),
+ 'curr_value' => scalar($cgi->param('pkgpart')) || $cust_pkg->pkgpart,
'classnum' => $part_pkg->classnum,
'cust_main' => $cust_main,
&>
<& /elements/tr-input-pkg-quantity.html,
- 'curr_value' => $cust_pkg->quantity
+ 'curr_value' => scalar($cgi->param('quantity')) || $cust_pkg->quantity
&>
% if ($use_contract_end) {
@@ -39,6 +39,11 @@
</TABLE>
<BR>
+<% include('/misc/cust_pkg_usageprice.html',
+ 'pkgpart' => (scalar($cgi->param('pkgpart')) || $cust_pkg->pkgpart),
+ 'pkgnum' => ($cust_pkg->change_to_pkgnum || $pkgnum),
+ ) %>
+<BR>
<FONT CLASS="fsinnerbox-title"><% mt('Change') |h %></FONT>
<% ntable('#cccccc') %>
@@ -49,8 +54,16 @@
document.getElementById('start_date_text').disabled = !enable;
document.getElementById('start_date_button').style.display =
(enable ? '' : 'none');
- document.getElementById('start_date_button_disabled').style.display =
- (enable ? 'none' : '');
+ if (document.getElementById('start_date_button_disabled')) { // does this ever exist anymore?
+ document.getElementById('start_date_button_disabled').style.display =
+ (enable ? 'none' : '');
+ }
+ if (enable) {
+ usageprice_disable(1);
+ } else {
+ var form = document.OrderPkgForm;
+ usageprice_disable(0,form.pkgpart.options[form.pkgpart.selectedIndex].value);
+ }
}
<&| /elements/onload.js &>
delay_changed();
@@ -96,7 +109,7 @@
TYPE = "button"
VALUE = "<% mt("Change package") |h %>"
onClick = "this.disabled=true; standardize_new_location();"
- <% scalar($cgi->param('pkgpart')) ? '' : 'DISABLED' %>
+ <% #scalar($cgi->param('pkgpart')) ? '' : 'DISABLED' %>
>
</FORM>
diff --git a/httemplate/misc/cust_pkg_usageprice.html b/httemplate/misc/cust_pkg_usageprice.html
new file mode 100644
index 000000000..f2e0f57e6
--- /dev/null
+++ b/httemplate/misc/cust_pkg_usageprice.html
@@ -0,0 +1,121 @@
+<%doc>
+Sets up the xmlhttp, javascript and initial (empty) table for selecting cust_pkg_usageprice.
+Available values are based on pkgpart, and can be updated when changing pkgpart
+by passing the new pkgpart to the following javascript:
+
+ usageprice_pkg_changed( pkgpart, pkgnum )
+
+The pkgnum input is optional, and will be used to set initial selected values.
+
+If pkgpart is passed as an option to this element, will run usageprice_pkg_changed
+once to initialize table; pkgnum can be passed as an option along with this.
+
+You can disable usageprice selection temporarily (remove the fields from the form)
+with the javascript usageprice_disable(1), and restore it with usageprice_disable(0,pkgnum).
+While disabled, calling usageprice_pkg_changed will have no effect.
+</%doc>
+
+<& /elements/xmlhttp.html,
+ 'url' => $p.'misc/xmlhttp-part_pkg_usageprice.html',
+ 'subs' => [ 'get_part_pkg_usageprice' ],
+&>
+
+<FONT CLASS = "fsinnerbox-title"
+ ID = "cust_pkg_usageprice_title"
+ STYLE = "display:none"
+><% mt('Usage add-ons') |h %></FONT>
+<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 ID="cust_pkg_usageprice_table">
+
+</TABLE>
+
+<SCRIPT>
+
+var usagepriceCache = {};
+var usagepriceDisabled = 0;
+
+function usageprice_disable (disabled, pkgpart) {
+ if (disabled) {
+ usageprice_pkg_changed(0);
+ usagepriceDisabled = 1;
+ } else {
+ usagepriceDisabled = 0;
+ usageprice_pkg_changed(pkgpart);
+ }
+}
+
+// main function to invoke when pkgpart changes
+function usageprice_pkg_changed (pkgpart, pkgnum) {
+ if (usagepriceDisabled) return;
+ clear_part_pkg_usageprice();
+
+ if (pkgpart) {
+ if (usagepriceCache[pkgpart]) {
+ update_part_pkg_usageprice(pkgpart);
+ } else {
+ get_part_pkg_usageprice( pkgpart || 0, pkgnum || 0, download_part_pkg_usageprice );
+ }
+ }
+}
+
+// removes table rows & hides table title
+function clear_part_pkg_usageprice () {
+ var table = document.getElementById('cust_pkg_usageprice_table');
+ for ( var r = table.rows.length - 1; r >= 0; r-- ) {
+ table.deleteRow(r);
+ }
+ document.getElementById('cust_pkg_usageprice_title').style.display = 'none';
+}
+
+// catches response from xmlhttp request, updates cache & calls update function
+function download_part_pkg_usageprice (part_pkg_usageprice) {
+ var usagepriceArray = JSON.parse(part_pkg_usageprice);
+ var pkgpart = usagepriceArray[0];
+ usagepriceCache[pkgpart] = usagepriceArray;
+ update_part_pkg_usageprice(pkgpart);
+}
+
+// updates from cache
+function update_part_pkg_usageprice (pkgpart) {
+ if (usagepriceDisabled) return;
+ clear_part_pkg_usageprice();
+
+ var usagepriceArray = usagepriceCache[pkgpart];
+ var table = document.getElementById('cust_pkg_usageprice_table');
+
+ // add the new usage price rows
+ var rownum = 0;
+ for ( var s = 1; s < usagepriceArray.length; s=s+2 ) {
+ var html = usagepriceArray[s];
+ var javascript = usagepriceArray[s+1];
+
+ var row = table.insertRow(rownum++);
+
+ var widget_cell = document.createElement('TD');
+ widget_cell.style.paddingTop = "3px";
+ widget_cell.colSpan = "2";
+ widget_cell.innerHTML = html;
+ row.appendChild(widget_cell);
+
+ }
+
+ if ( rownum > 0 ) {
+ document.getElementById('cust_pkg_usageprice_title').style.display = '';
+ } else {
+ document.getElementById('cust_pkg_usageprice_title').style.display = 'none';
+ }
+
+}
+
+% if ($opt{'pkgpart'}) {
+<&| /elements/onload.js &>
+usageprice_pkg_changed(<% $opt{'pkgpart'} %>, <% $opt{'pkgnum'} %>);
+</&>
+% }
+
+</SCRIPT>
+
+<%init>
+my %opt = @_;
+</%init>
+
+
diff --git a/httemplate/misc/order_pkg.html b/httemplate/misc/order_pkg.html
index 799165fe0..cb2bd4832 100644
--- a/httemplate/misc/order_pkg.html
+++ b/httemplate/misc/order_pkg.html
@@ -5,11 +5,6 @@
}
&>
-<& /elements/xmlhttp.html,
- 'url' => $p.'misc/xmlhttp-part_pkg_usageprice.html',
- 'subs' => [ 'get_part_pkg_usageprice' ],
-&>
-
<& /elements/init_calendar.html &>
<SCRIPT TYPE="text/javascript" SRC="../elements/order_pkg.js"></SCRIPT>
@@ -121,19 +116,9 @@
</TABLE><BR>
-%#so:
-%# - hide until you selecdt a pacakge with add-ons
-%# -lookup and display the available add-ons when
-%# -add them to the (recur if there is one, otherwise setup) price and display magically like processing fees do on edit/cust_pay.cgi
-
-%# better label?
-<FONT CLASS = "fsinnerbox-title"
- ID = "cust_pkg_usageprice_title"
- STYLE = "display:none"
-><% mt('Usage add-ons') |h %></FONT>
-<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 ID="cust_pkg_usageprice_table">
-
-</TABLE>
+<% include('/misc/cust_pkg_usageprice.html',
+ 'pkgpart' => $pkgpart
+ ) %>
<BR>
% my $discount_cust_pkg = $curuser->access_right('Discount customer package');
diff --git a/httemplate/misc/xmlhttp-part_pkg_usageprice.html b/httemplate/misc/xmlhttp-part_pkg_usageprice.html
index d4e2d8469..9decdeff9 100644
--- a/httemplate/misc/xmlhttp-part_pkg_usageprice.html
+++ b/httemplate/misc/xmlhttp-part_pkg_usageprice.html
@@ -1,24 +1,32 @@
<% encode_json( \@return ) %>\
<%init>
-my( $pkgpart ) = $cgi->param('arg');
+my( $pkgpart, $pkgnum ) = $cgi->param('arg');
#could worry about agent-virting this so you can't see the add-on pricing of
# other agents, but not a real-world big worry
my $part_pkg = qsearchs( 'part_pkg', { pkgpart=>$pkgpart } );
+my %curr_quantity;
+if ($pkgnum) {
+ my $cust_pkg = qsearchs( 'cust_pkg', { pkgnum=>$pkgnum } );
+ %curr_quantity = map { $_->usagepricepart, $_->quantity } $cust_pkg->cust_pkg_usageprice;
+}
+
my $num = 0;
-my @return = map {
+# probably don't need to be returning js_only anymore?
+my @return = ($pkgpart, map {
+ my $usagepricepart = $_->usagepricepart;
my @inc = ('/elements/cust_pkg_usageprice.html',
- 'usagepricepart' => $_->usagepricepart,
+ 'usagepricepart' => $usagepricepart,
);
-
+ push(@inc,'curr_quantity',($curr_quantity{$usagepricepart} || 0));
( include(@inc, field=>'usagepricenum'.$num, html_only=>1 ),
include(@inc, field=>'usagepricenum'.$num++, js_only=>1 ),
);
}
- $part_pkg->part_pkg_usageprice;
+ $part_pkg->part_pkg_usageprice);
</%init>