shift->num_pkgs("cust_pkg.cancel IS NOT NULL AND cust_pkg.cancel != 0");
}
+=item num_ncancelled_pkgs
+
+Returns the number of packages that have not been cancelled (see L<FS::cust_pkg>) for this
+customer.
+
+=cut
+
sub num_ncancelled_pkgs {
shift->num_pkgs("( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )");
}
+=item num_billing_pkgs
+
+Returns the number of packages that have not been cancelled
+and have a non-zero billing frequency (see L<FS::cust_pkg>)
+for this customer.
+
+=cut
+
+sub num_billing_pkgs {
+ my $self = shift;
+ my $opt = shift || {};
+ $opt->{addl_from} .= ' LEFT JOIN part_pkg USING (pkgpart)';
+ $opt->{extra_sql} .= ' AND ' if $opt->{extra_sql};
+ $opt->{extra_sql} .= "freq IS NOT NULL AND freq != '0'";
+ $self->num_ncancelled_pkgs($opt);
+}
+
sub num_suspended_pkgs {
shift->num_pkgs(" ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
AND cust_pkg.susp IS NOT NULL AND cust_pkg.susp != 0 ");
'subs' => [ 'get_display_recurring'] &>
<SCRIPT>
-<&| /elements/onload.js &>
-get_display_recurring('custnum',<% $cust_main->custnum %>, function (xmlresult) {
+function set_display_recurring (xmlresult) {
var recurring = JSON.parse(xmlresult);
var rlabel = document.getElementById('recurring_label');
var rvalue = document.getElementById('recurring_value');
} else {
rrow.parentNode.removeChild(rrow);
}
-});
-</&>
+}
</SCRIPT>
+% # 10 is an arbitrary number, use ajax for customers with many packages
+% if ( $cust_main->num_billing_pkgs > 10 ) {
+<& '/elements/xmlhttp.html',
+ 'url' => $fsurl.'misc/xmlhttp-cust_main-display_recurring.html',
+ 'subs' => [ 'get_display_recurring'] &>
+<SCRIPT>
+get_display_recurring('custnum',<% $cust_main->custnum %>,set_display_recurring);
+</SCRIPT>
+% } else {
+<SCRIPT>
+set_display_recurring(<% encode_json({'display_recurring' => [ $cust_main->display_recurring ]}) |js_string %>);
+</SCRIPT>
+% }
+
% if ( $conf->exists('cust_main-select-prorate_day') ) {
<TR>
<TD ALIGN="right"><% mt('Prorate day of month') |h %></TD>