},
{
+ 'key' => 'credit-card-surcharge-text',
+ 'section' => 'credit_cards',
+ 'description' => 'Text for the credit card surcharge invoice line. If not set, it will default to Credit Card Surcharge.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ },
+
+ {
'key' => 'discount-show-always',
'section' => 'invoicing',
'description' => 'Generate a line item on an invoice even when a package is discounted 100%',
package FS::Misc;
use strict;
-use vars qw ( @ISA @EXPORT_OK $DEBUG );
+use vars qw ( @ISA @EXPORT_OK $DEBUG $DISABLE_ALL_NOTICES );
use Exporter;
use Carp;
use Data::Dumper;
called from multiple other modules. These are not OO or necessarily related,
but are collected here to eliminate code duplication.
+=head1 DISABLE ALL NOTICES
+
+Set $FS::Misc::DISABLE_ALL_NOTICES to suppress:
+
+=over 4
+
+=item FS::cust_bill::send_csv
+
+=item FS::cust_bill::spool_csv
+
+=item FS::msg_template::email::send_prepared
+
+=item FS::Misc::send_email
+
+=item FS::Misc::do_print
+
+=item FS::Misc::send_fax
+
+=item FS::Template_Mixin::postal_mail_fsinc
+
+=back
+
+=cut
+
+$DISABLE_ALL_NOTICES = 0;
+
=head1 SUBROUTINES
=over 4
sub send_email {
my(%options) = @_;
+
+ if ( $DISABLE_ALL_NOTICES ) {
+ warn 'send_email() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+ return;
+ }
+
if ( $DEBUG ) {
my %doptions = %options;
$doptions{'body'} = '(full body not shown in debug)';
die 'HylaFAX support has not been configured.'
unless $conf->exists('hylafax');
+ if ( $DISABLE_ALL_NOTICES ) {
+ warn 'send_fax() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+ return;
+ }
+
eval {
require Fax::Hylafax::Client;
};
sub do_print {
my( $data, %opt ) = @_;
+ if ( $DISABLE_ALL_NOTICES ) {
+ warn 'do_print() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+ return;
+ }
+
my $lpr = ( exists($opt{'lpr'}) && $opt{'lpr'} )
? $opt{'lpr'}
: $conf->config('lpr', $opt{'agentnum'} );
'suid', 'int', 'NULL', '', '', '',
'shared_svcnum', 'int', 'NULL', '', '', '',
'serviceid', 'varchar', 'NULL', 64, '', '',#srvexport/reportfields
+ 'speed_test_up', 'int', 'NULL', '', '', '',
+ 'speed_test_down', 'int', 'NULL', '', '', '',
+ 'speed_test_latency', 'int', 'NULL', '', '', '',
],
'primary_key' => 'svcnum',
'unique' => [ [ 'ip_addr' ], [ 'mac_addr' ] ],
sub postal_mail_fsinc {
my ( $self, %opt ) = @_;
+ if ( $FS::Misc::DISABLE_PRINT ) {
+ warn 'postal_mail_fsinc() disabled by $FS::Misc::DISABLE_PRINT' if $DEBUG;
+ return;
+ }
+
my $url = 'https://ws.freeside.biz/print';
my $cust_main = $self->cust_main;
sub send_csv {
my($self, %opt) = @_;
+ if ( $FS::Misc::DISABLE_ALL_NOTICES ) {
+ warn 'send_csv() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+ return;
+ }
+
#create file(s)
my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/cust_bill";
sub spool_csv {
my($self, %opt) = @_;
+ if ( $FS::Misc::DISABLE_ALL_NOTICES ) {
+ warn 'spool_csv() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+ return;
+ }
+
my $time = $opt{'time'} || time;
my $cust_main = $self->cust_main;
}
my $cust_pkg;
+ my $cc_surcharge_text = 'Credit Card Surcharge';
+ $cc_surcharge_text = $conf->config('credit-card-surcharge-text', $self->agentnum) if $conf->exists('credit-card-surcharge-text', $self->agentnum);
my $charge_error = $self->charge({
'amount' => $options{'cc_surcharge'},
- 'pkg' => 'Credit Card Surcharge',
+ 'pkg' => $cc_surcharge_text,
'setuptax' => 'Y',
'cust_pkg_ref' => \$cust_pkg,
});
}
+=item fcc_477_record
+
+Returns a fcc_477 record based on option name.
+
+=cut
+
+sub fcc_477_record {
+ my ($self, $option_name) = @_;
+
+ my $fcc_record = qsearchs({
+ 'table' => 'part_pkg_fcc_option',
+ 'hashref' => { 'pkgpart' => $self->{Hash}->{pkgpart}, 'fccoptionname' => $option_name, },
+ });
+
+ return ( $fcc_record );
+
+}
+
=item tax_locationnum_sql
Returns an SQL expression for the tax location for a package, based
'default' => [],
'all_dates' => [],
'svc_acct' => [qw( username _password domsvc )],
+ 'svc_broadband' => [qw( ip_addr description routernum blocknum sectornum speed_up speed_down )],
'svc_phone' => [qw( countrycode phonenum sip_password pin )],
'svc_external' => [qw( id title )],
'location' => [qw( address1 address2 city state zip country )],
my $self = shift;
my $cust_msg = shift or die "cust_msg required";
+ if ( $FS::Misc::DISABLE_ALL_NOTICES ) {
+ warn 'send_prepared() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+ return;
+ }
+
my $domain = 'example.com';
if ( $cust_msg->env_from =~ /\@([\w\.\-]+)/ ) {
$domain = $1;
sub _export_insert {
my ($self, $svc_broadband) = @_;
- my $service_part = FS::Record::qsearchs( 'part_svc', { 'svcpart' => $svc_broadband->{Hash}->{svcpart} } );
- my $rateplan_name = $service_part->{Hash}->{svc};
- $rateplan_name =~ s/\s/_/g;
+ my $rateplan_name = $self->get_rateplan_name($svc_broadband);
# check for existing rate plan
my $existing_rateplan;
sub _export_replace {
my ($self, $svc_broadband) = @_;
+ $self->_export_insert($svc_broadband);
return '';
}
sub _export_delete {
my ($self, $svc_broadband) = @_;
- my $service_part = FS::Record::qsearchs( 'part_svc', { 'svcpart' => $svc_broadband->{Hash}->{svcpart} } );
- my $rateplan_name = $service_part->{Hash}->{svc};
- $rateplan_name =~ s/\s/_/g;
+ my $rateplan_name = $self->get_rateplan_name($svc_broadband);
+
my $username = $svc_broadband->{Hash}->{svcnum};
## untie host to user
sub export_partsvc {
my ($self, $svc_part) = @_;
- my $rateplan_name = $svc_part->{Hash}->{svc};
- $rateplan_name =~ s/\s/_/g;
- my $speeddown = $svc_part->{Hash}->{svc_broadband__speed_down};
- my $speedup = $svc_part->{Hash}->{svc_broadband__speed_up};
+ my $fcc_477_speeds;
+ if ($svc_part->{Hash}->{svc_broadband__speed_down} eq "down" || $svc_part->{Hash}->{svc_broadband__speed_up} eq "up") {
+ for my $type (qw( down up )) {
+ my $speed_type = "broadband_".$type."stream";
+ foreach my $pkg_svc (FS::Record::qsearch({
+ 'table' => 'pkg_svc',
+ 'select' => 'pkg_svc.*, part_pkg_fcc_option.fccoptionname, part_pkg_fcc_option.optionvalue',
+ 'addl_from' => ' LEFT JOIN part_pkg_fcc_option USING (pkgpart) ',
+ 'extra_sql' => " WHERE pkg_svc.svcpart = ".$svc_part->{Hash}->{svcpart}." AND pkg_svc.quantity > 0 AND part_pkg_fcc_option.fccoptionname = '".$speed_type."'",
+ })) { $fcc_477_speeds->{
+ $pkg_svc->{Hash}->{pkgpart}}->{$speed_type} = $pkg_svc->{Hash}->{optionvalue} * 1000 unless !$pkg_svc->{Hash}->{optionvalue}; }
+ }
+ }
+ else {
+ $fcc_477_speeds->{1}->{broadband_downstream} = $svc_part->{Hash}->{"svc_broadband__speed_down"};
+ $fcc_477_speeds->{1}->{broadband_upstream} = $svc_part->{Hash}->{"svc_broadband__speed_up"};
+ }
- my $temp_svc = $svc_part->{Hash};
- my $svc_broadband = {};
- map { if ($_ =~ /^svc_broadband__(.*)$/) { $svc_broadband->{Hash}->{$1} = $temp_svc->{$_}; } } keys %$temp_svc;
+ foreach my $key (keys %$fcc_477_speeds) {
- # check for existing rate plan
- my $existing_rateplan;
- $existing_rateplan = $self->api_get_rateplan($rateplan_name) unless $self->{'__saisei_error'};
+ $svc_part->{Hash}->{speed_down} = $fcc_477_speeds->{$key}->{broadband_downstream};
+ $svc_part->{Hash}->{speed_up} = $fcc_477_speeds->{$key}->{broadband_upstream};
+ $svc_part->{Hash}->{svc_broadband__speed_down} = $fcc_477_speeds->{$key}->{broadband_downstream};
+ $svc_part->{Hash}->{svc_broadband__speed_up} = $fcc_477_speeds->{$key}->{broadband_upstream};
- # Modify the existing rate plan with new service data.
- $self->api_modify_existing_rateplan($svc_broadband, $rateplan_name) unless ($self->{'__saisei_error'} || !$existing_rateplan);
+ my $temp_svc = $svc_part->{Hash};
+ my $svc_broadband = {};
+ map { if ($_ =~ /^svc_broadband__(.*)$/) { $svc_broadband->{Hash}->{$1} = $temp_svc->{$_}; } } keys %$temp_svc;
- # if no existing rate plan create one and modify it.
- $self->api_create_rateplan($svc_broadband, $rateplan_name) unless $existing_rateplan;
- $self->api_modify_rateplan($svc_part, $rateplan_name) unless ($self->{'__saisei_error'} || $existing_rateplan);
+ my $rateplan_name = $self->get_rateplan_name($svc_broadband, $svc_part->{Hash}->{svc});
+
+ # check for existing rate plan
+ my $existing_rateplan;
+ $existing_rateplan = $self->api_get_rateplan($rateplan_name) unless $self->{'__saisei_error'};
+
+ # Modify the existing rate plan with new service data.
+ $self->api_modify_existing_rateplan($svc_broadband, $rateplan_name) unless ($self->{'__saisei_error'} || !$existing_rateplan);
+
+ # if no existing rate plan create one and modify it.
+ $self->api_create_rateplan($svc_broadband, $rateplan_name) unless $existing_rateplan;
+ $self->api_modify_rateplan($svc_part, $rateplan_name) unless ($self->{'__saisei_error'} || $existing_rateplan);
+
+ }
return $self->api_error;
return $self->api_error;
}
+## creates the rateplan name
+sub get_rateplan_name {
+ my ($self, $svc_broadband, $svc_name) = @_;
+
+ my $service_part = FS::Record::qsearchs( 'part_svc', { 'svcpart' => $svc_broadband->{Hash}->{svcpart} } ) unless $svc_name;
+ my $service_name = $svc_name ? $svc_name : $service_part->{Hash}->{svc};
+
+ my $rateplan_name = $service_name . " " . $svc_broadband->{Hash}->{speed_down} . "-" . $svc_broadband->{Hash}->{speed_up};
+ $rateplan_name =~ s/\s/_/g;
+
+ return $rateplan_name;
+}
+
=head1 Saisei API
These methods allow access to the Saisei API using the credentials
my $svc_count = scalar @svcs;
my %status = {};
- for (my $c=10; $c <=100; $c=$c+10) { $status{int($svc_count * ($c/100))} = $c; }
+ for (my $c=1; $c <=100; $c=$c+1) { $status{int($svc_count * ($c/100))} = $c; }
my $process_count=0;
foreach my $svc (@svcs) {
map {
my $f = $svcdb.'__'.$_;
my $flag = $param->{ $f.'_flag' } || ''; #silence warnings
- if ( $flag =~ /^[MAH]$/ ) {
+ if ( $flag =~ /^[MAHP]$/ ) {
$param->{ $f } = delete( $param->{ $f.'_classnum' } );
}
- if ( ( $flag =~ /^[MAHS]$/ or $_ eq 'usergroup' )
+ if ( ( $flag =~ /^[MAHSP]$/ or $_ eq 'usergroup' )
and ref($param->{ $f }) ) {
$param->{ $f } = join(',', @{ $param->{ $f } });
}
;
return $error if $error;
- $self->columnflag =~ /^([DFSMAHX]?)$/
+ $self->columnflag =~ /^([DFSMAHXP]?)$/
or return "illegal columnflag ". $self->columnflag;
$self->columnflag(uc($1));
'fields' => {
'svcnum' => 'Service',
'description' => 'Descriptive label',
- 'speed_down' => 'Download speed (Kbps)',
- 'speed_up' => 'Upload speed (Kbps)',
+ 'speed_up' => {
+ 'label' => 'Upload speed (Kbps)',
+ 'type' => 'fcc_477_speed',
+ 'def_info' => 'both upload and download speed must be set to FCC 477 information if using that modifier',
+ },
+ 'speed_down' => {
+ 'label' => 'Download speed (Kbps)',
+ 'type' => 'fcc_477_speed',
+ 'def_info' => 'both upload and download speed must be set to FCC 477 information if using that modifier',
+ },
'ip_addr' => 'IP address',
'blocknum' => {
'label' => 'Address block',
disable_inventory => 1,
},
'serviceid' => 'Torrus serviceid', #but is should be hidden
+ 'speed_test_up' => { 'label' => 'Speed test upload (Kbps)' },
+ 'speed_test_down' => { 'label' => 'Speed test download (Kbps)' },
+ 'speed_test_latency' => 'Speed test latency (ms)',
},
};
}
|| $self->ut_textn('description')
|| $self->ut_numbern('speed_up')
|| $self->ut_numbern('speed_down')
+ || $self->ut_numbern('speed_test_up')
+ || $self->ut_numbern('speed_test_down')
|| $self->ut_ipn('ip_addr')
|| $self->ut_hexn('mac_addr')
|| $self->ut_hexn('auth_key')
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearchs qsearch);
+use FS::svc_broadband;
+
+my $user = shift or die &usage;
+my $dbh = adminsuidsetup($user);
+
+my $fcc_up_speed = "(select part_pkg_fcc_option.optionvalue from part_pkg_fcc_option where fccoptionname = 'broadband_upstream' and pkgpart = cust_pkg.pkgpart) AS fcc477_upstream";
+my $fcc_down_speed = "(select part_pkg_fcc_option.optionvalue from part_pkg_fcc_option where fccoptionname = 'broadband_downstream' and pkgpart = cust_pkg.pkgpart) AS fcc477_downstream";
+foreach my $rec (qsearch({
+ 'select' => 'svc_broadband.*, cust_svc.svcpart, cust_pkg.pkgpart, '.$fcc_up_speed.', '.$fcc_down_speed,
+ 'table' => 'svc_broadband',
+ 'addl_from' => 'LEFT JOIN cust_svc USING ( svcnum ) LEFT JOIN cust_pkg USING ( pkgnum )',
+})) {
+ $rec->{Hash}->{speed_test_up} = $rec->{Hash}->{speed_up};
+ $rec->{Hash}->{speed_test_down} = $rec->{Hash}->{speed_down};
+ $rec->{Hash}->{speed_up} = $rec->{Hash}->{fcc477_upstream} * 1000;
+ $rec->{Hash}->{speed_down} = $rec->{Hash}->{fcc477_downstream} * 1000;
+ $rec->replace();
+ warn "Fixing broadband service speeds for service ".$rec->{Hash}->{svcnum}."-".$rec->{Hash}->{description}."\n";
+}
+
+warn "Completed fixing broadband service speeds!\n";
+
+exit;
+
+=head1 NAME
+
+move_svc_broadband_speeds
+
+=head1 SYNOPSIS
+
+ move_svc_broadband_speeds.pl [ user ]
+
+=head1 DESCRIPTION
+
+Moves value for speed_down to speed_test_down, speed_up to speed_test_up,
+and sets speed_down, speed_up to matching fcc_477 speeds from package for
+all svc_broadband services.
+
+user: freeside username
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::svc_broadband>
+
+=cut
\ No newline at end of file
<TD>
<SELECT NAME="month">
<%= for ( ( map "0$_", 1 .. 9 ), 10 .. 12 ) {
- $OUT .= '<OPTION'. ($_ == $month ? ' SELECTED' : ''). ">$_\n";
+ $OUT .= '<OPTION'. ($_ == $month ? ' SELECTED' : ''). " VALUE='$_'>$_\n";
} %>
</SELECT>
</TD>
<TD>
<SELECT NAME="year">
<%= my @a = localtime; for ( $a[5]+1900 .. $a[5]+1915 ) {
- $OUT .= '<OPTION'. ($_ == $year ? ' SELECTED' : ''). ">$_\n";
+ $OUT .= '<OPTION'. ($_ == $year ? ' SELECTED' : ''). " VALUE='$_'>$_\n";
} %>
</SELECT>
</TD>
$cgi->param('paycvv') =~ /^\s*(.{0,4})\s*$/ or die "illegal CVV2";
my $paycvv = $1;
- $cgi->param('month') =~ /^(\d{2})$/ or die "illegal month";
+ $cgi->param('month') =~ /^(\d{2})/ or die "illegal month";
my $month = $1;
- $cgi->param('year') =~ /^(\d{4})$/ or die "illegal year";
+ $cgi->param('year') =~ /^(\d{4})/ or die "illegal year";
my $year = $1;
$cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
);
}
-
-
'A' => 'Automatically filled in from inventory',
'H' => 'Selected from hardware class',
'X' => 'Excluded',
+ 'P' => 'From package 477 information',
);
my %search;
# don't allow the 'inventory' flags (M, A) to be chosen for
# fields that aren't free-text
my $inv_sub = sub { $_[0]->{disable_inventory} || $_[0]->{type} ne 'text' };
+
tie my %flag, 'Tie::IxHash',
'' => { 'desc' => 'No default', 'condition' => sub { 0 } },
'D' => { 'desc' => 'Default',
'H' => { 'desc' => 'Select from hardware class',
'condition' => sub { $_[0]->{type} ne 'select-hardware' },
},
+ 'P' => { 'desc' => 'From package FCC 477 information',
+ 'condition' => sub { $_[0]->{type} ne 'fcc_477_speed' }, # get values from package fcc 477 information
+ },
'X' => { 'desc' => 'Excluded',
'condition' => sub { 1 }, # obsolete
},
% $mode = 'hardware';
% $multiple = 0;
% }
+%
+% if ( $def->{'type'} eq 'fcc_477_speed' ) {
+% if ($field eq 'speed_up') {
+ <SPAN ID="<% $name %>_select">
+ upstream speed
+ <INPUT TYPE="hidden" ID="<% $name %>_select" NAME="<% $name %>_classnum" VALUE="up">
+ </SPAN>
+% } elsif ($field eq 'speed_down') {
+ <SPAN ID="<% $name %>_select">
+ downstream speed
+ <INPUT TYPE="hidden" ID="<% $name %>_select" NAME="<% $name %>_classnum" VALUE="down">
+ </SPAN>
+% }
+% } else {
<& /elements/select-table.html,
'field' => $name.'_classnum',
'id' => $name.'_select',
'empty_label' => "Select $mode class",
'multiple' => $multiple,
&>
+% }
% }
</TD>
<TD>
];
} # shouldn't this be enforced for all 'S' fields?
+ elsif ( $flag eq 'P' ) { #form fcc_477 values
+ $f->{type} = 'fixed';
+ my $cust_pkg = FS::Record::qsearchs({
+ 'table' => 'cust_pkg',
+ 'hashref' => { 'pkgnum' => $object->{Hash}->{pkgnum} }
+ });
+ my $fcc_record = $cust_pkg->fcc_477_record('broadband_'.$columndef->columnvalue.'stream') if $cust_pkg;
+ $f->{'value'} = $fcc_record->{Hash}->{optionvalue} ? $fcc_record->{Hash}->{optionvalue} * 1000 : '';
+ } # end 477 values
+
if ( $f->{'type'} =~ /^select-svc/ )
{
$f->{'include_opt_callback'} =
select.multiple = false;
}
}
- } else if ( newflag == 'M' || newflag == 'A' || newflag == 'H' ) {
+ } else if ( newflag == 'M' || newflag == 'A' || newflag == 'H' || newflag == 'P' ) {
// these all require a class selection
if ( select ) {
select.disabled = false;
}
var required = document.getElementById(layer + '__' + field + '_required');
if (required && !required.disabledinit) {
- if (newflag == "F") {
+ if (newflag == "F" || newflag =="P") {
required.checked = false;
required.disabled = true;
} else {
# for use with tables that are FS::option_Common (among other things)
'args_callback' => sub { my( $cgi, $object ) = @_; },
+ # if no errors after package insert or replace will update services attached to package.
+ 'update_svc' => sub { my( $cgi, $object ) = @_; },
+
'debug' => 1, #turns on debugging output
#agent virtualization
}
}
+ if ( !$error and $opt{'update_svc'} ) {
+ my @args = ();
+ @args = &{ $opt{'args_callback'} }( $cgi, $new ) if $opt{'args_callback'};
+ $error = &{ $opt{'update_svc'} }( $cgi, $new, @args );
+ }
+
if ( $error ) {
$cgi->param('error', $error);
'edit_ext' => 'cgi',
'precheck_callback' => $precheck_callback,
'args_callback' => $args_callback,
+ 'update_svc' => $update_svc,
'process_locale' => 'pkg',
'process_m2m' => \@process_m2m,
'process_o2m' => \@process_o2m,
};
+## update services upon package change.
+my $update_svc = sub {
+ my $cgi = shift @_;
+ my $new = shift @_;
+ my %args = @_;
+ my $error;
+
+ my @svcs = $new->pkg_svc();
+
+## update broadband services getting their up and down speeds from package fcc_477 options
+ foreach my $svc_part(@svcs) {
+ my @part_svc_column = qsearch('part_svc_column',{ 'svcpart' => $svc_part->{Hash}->{svcpart}, 'columnflag' => 'P' });
+
+ if ($svc_part->{Hash}->{svcdb} eq "svc_broadband" && (keys $args{fcc_options}) && @part_svc_column ) {
+ ## find provisioned services to update
+ my @svc_svcdb = qsearch({
+ 'table' => 'svc_broadband',
+ 'select' => 'svc_broadband.*, cust_svc.svcpart',
+ 'addl_from' => 'LEFT JOIN cust_svc USING (svcnum) LEFT JOIN cust_pkg USING (pkgnum)',
+ 'extra_sql' => " WHERE cust_svc.svcpart = '".$svc_part->{Hash}->{svcpart}."' AND cust_pkg.pkgpart = '".$svc_part->{Hash}->{pkgpart}."'",
+ });
+ foreach my $svc (@svc_svcdb) {
+ next if ($svc->{Hash}->{speed_down} == $args{fcc_options}->{broadband_downstream} * 1000 && $svc->{Hash}->{speed_up} == $args{fcc_options}->{broadband_upstream} * 1000);
+ $svc->{Hash}->{speed_down} = $args{fcc_options}->{broadband_downstream} * 1000;
+ $svc->{Hash}->{speed_up} = $args{fcc_options}->{broadband_upstream} * 1000;
+ $error = $svc->replace();
+ }
+ }
+ }
+ return $error;
+};
+
my $redirect_callback = sub {
#my( $cgi, $new ) = @_;
return '' unless $custnum;
;
my @fields = (
- qw( description speed_down speed_up ),
+ qw( description speed_down speed_up speed_test_down speed_test_up speed_test_latency),
{ field=>'sectornum', type=>'select-tower_sector', },
{ field=>'routernum', type=>'select-router_block_ip',
include_opt_callback => sub {
my $columndef = $part_svc->part_svc_column($fieldref->{'field'});
if ($fieldref->{field} eq 'usergroup' && $columndef->columnflag eq 'F') {
-
$fieldref->{'formatted_value'} =
[ $object->radius_groups('long_description') ];
}
<OPTION VALUE="svc_acct">Account service
<OPTION VALUE="svc_acct-agent_custid">Account service with agent_custid
<OPTION VALUE="svc_acct-locationnum">Account service with existing location
+ <OPTION VALUE="svc_broadband">Broadband service
<OPTION VALUE="svc_phone">Phone service
<OPTION VALUE="svc_phone-agent_custid">Phone service with agent_custid
<OPTION VALUE="svc_phone-locationnum">Phone service with existing location
<b>Account service with existing location</b> format has the following field order: <i>custnum<%$req%>, locationnum, pkgpart<%$req%>, discountnum, start_date, setup, bill, last_bill, susp, adjourn, cancel, expire, username, _password, domsvc</i>
<BR><BR>
+<b>Broadband service</b> format has the following field order: <i>custnum<%$req%>, pkgpart<%$req%>, discountnum, start_date, setup, bill, last_bill, susp, adjourn, cancel, expire, ip_addr<%$req%>, description, routernum, blocknum, sectornum, speed_up, speed_down</i>
+<BR><BR>
+
<b>Phone service</b> format has the following field order: <i>custnum<%$req%>, pkgpart<%$req%>, discountnum, start_date, setup, bill, last_bill, susp, adjourn, cancel, expire, countrycode, phonenum, sip_password, pin</i>
<BR><BR>
'header' => \@header,
'fields' => \@fields,
'links' => \@links,
+ 'disable_maxselect' => '1',
&>
<%init>
## sql to get the first active date, last cancel date, and last reason.
my $active_date = 'select min(setup) from cust_pkg left join part_pkg using (pkgpart) where cust_pkg.custnum = cust_main.custnum and part_pkg.freq > \'0\'';
-my $cancel_date = 'select max(cancel) from cust_pkg where cust_pkg.custnum = cust_main.custnum';
+
+## set cancel date range here
+my($beginning_date, $ending_date) = FS::UI::Web::parse_beginning_ending($cgi, '');
+my $cancel_date = 'select max(cancel) from cust_pkg left join part_pkg using (pkgpart) where cust_pkg.custnum = cust_main.custnum and part_pkg.freq > \'0\' and (cancel >= '.$beginning_date.' and cancel <= '.$ending_date.')';
+
my $cancel_reason = 'select reason.reason from cust_pkg
left join cust_pkg_reason on (cust_pkg.pkgnum = cust_pkg_reason.pkgnum)
left join reason on (cust_pkg_reason.reasonnum = reason.reasonnum)
#setup some pagination things if we're in html mode
my $conf = new FS::Conf;
- $confmax = $conf->config('maxsearchrecordsperpage') || 100;
- if ( $cgi->param('maxrecords') =~ /^(\d+)$/ ) {
- $maxrecords = $1;
- } else {
- $maxrecords ||= $confmax;
- }
-
$opt{'disable_maxselect'} ||= $conf->exists('disable_maxselect');
+ unless ($opt{'disable_maxselect'}) {
+ $confmax = $conf->config('maxsearchrecordsperpage') || 100;
+ if ( $cgi->param('maxrecords') =~ /^(\d+)$/ ) {
+ $maxrecords = $1;
+ } else {
+ $maxrecords ||= $confmax;
+ }
+ }
$limit = $maxrecords ? "LIMIT $maxrecords" : '';
'curr_value' => scalar( $cgi->param('cust_status') ),
&>
+ <& /elements/tr-input-beginning_ending.html &>
+
</FORM>
</TABLE>
{ field => 'routernum', value_callback => \&router },
'speed_down',
'speed_up',
+ 'speed_test_down',
+ 'speed_test_up',
+ 'speed_test_latency',
{ field => 'ip_addr', value_callback => \&ip_addr },
{ field => 'sectornum', value_callback => \§ornum },
{ field => 'mac_addr', type=>'mac_addr', value_callback => \&mac_addr },