diff options
| author | Ivan Kohler <ivan@freeside.biz> | 2013-07-02 21:11:29 -0700 |
|---|---|---|
| committer | Ivan Kohler <ivan@freeside.biz> | 2013-07-02 21:11:29 -0700 |
| commit | 3d0a1bb06b895c5be6e3f0517d355442a6b1e125 (patch) | |
| tree | 84069ebc3254825b952a482e11cdbbbc69f6fe85 /bin | |
| parent | f3b99c11d6eed33f467dda360180a698a85c54e8 (diff) | |
| parent | d62206a94d9d49ef96640e0a8ec492679f8345e9 (diff) | |
Merge branch 'master' of git.freeside.biz:/home/git/freeside
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/23diff | 2 | ||||
| -rwxr-xr-x | bin/32add | 22 | ||||
| -rwxr-xr-x | bin/32commit | 29 | ||||
| -rwxr-xr-x | bin/3add | 19 | ||||
| -rwxr-xr-x | bin/3commit | 26 | ||||
| -rwxr-xr-x | bin/3diff | 13 | ||||
| -rw-r--r-- | bin/cch.finish_failed | 51 | ||||
| -rw-r--r-- | bin/cch.redelete | 52 | ||||
| -rwxr-xr-x | bin/cdr-netsapiens.import | 1 | ||||
| -rwxr-xr-x | bin/cdr_upstream_rate.import | 2 | ||||
| -rwxr-xr-x | bin/cust_main-bulk_change | 54 | ||||
| -rwxr-xr-x | bin/cust_pay_histogram | 2 | ||||
| -rwxr-xr-x | bin/fs-migrate-supplemental | 151 | ||||
| -rwxr-xr-x | bin/fs-migrate-svc_acct_sm | 227 | ||||
| -rwxr-xr-x | bin/fs-radius-add-check | 8 | ||||
| -rwxr-xr-x | bin/fs-radius-add-reply | 8 | ||||
| -rwxr-xr-x | bin/generate-table-module | 2 | ||||
| -rwxr-xr-x | bin/megapop.pl | 114 | ||||
| -rwxr-xr-x | bin/rebill | 2 | ||||
| -rwxr-xr-x | bin/usps-webtools-test-script | 38 |
20 files changed, 570 insertions, 253 deletions
diff --git a/bin/23diff b/bin/23diff index d38c84834..1dc1659d2 100755 --- a/bin/23diff +++ b/bin/23diff @@ -7,7 +7,7 @@ $dir =~ s/freeside(\/?)/freeside2.3$1/; warn $dir; #$cmd = "diff -u $file $dir/$file"; -$cmd = "diff -u $dir/$file $file"; +$cmd = "diff -ubBw $dir/$file $file"; print "$cmd\n"; system($cmd); diff --git a/bin/32add b/bin/32add new file mode 100755 index 000000000..856c2f133 --- /dev/null +++ b/bin/32add @@ -0,0 +1,22 @@ +#!/usr/bin/perl + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +system join('', + "git add @ARGV ; ", + "( for file in @ARGV; do ", + "cp -i \$file /home/$USER/freeside3/$prefix/`dirname \$file`;", + "cp -i \$file /home/$USER/freeside2.3/$prefix/`dirname \$file`;", + "done ) && ", + "cd /home/$USER/freeside3/$prefix/ && ", + "git add @ARGV; ", + "cd /home/$USER/freeside2.3/$prefix/ && ", + "git add @ARGV" +); + diff --git a/bin/32commit b/bin/32commit new file mode 100755 index 000000000..903722e4e --- /dev/null +++ b/bin/32commit @@ -0,0 +1,29 @@ +#!/usr/bin/perl + +# usage: 32commit 'log message' filename filename ... + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +my $desc = shell_quote(shift @ARGV); # -m + +die "no files!" unless @ARGV; + +#warn "$prefix"; + +#print <<END; +system join('', + "( cd /home/$USER/freeside3/$prefix; git pull ) && ", + "( cd /home/$USER/freeside2.3/$prefix; git pull ) && ", + "git diff -u @ARGV | ( cd /home/$USER/freeside3/$prefix; patch -p1 ) ", + " && git diff -u @ARGV | ( cd /home/$USER/freeside2.3/$prefix; patch -p1 ) ", + " && ( ( git pull && git commit -m $desc @ARGV && git push); ", + "( cd /home/$USER/freeside3/$prefix; git commit -m $desc @ARGV && git push); ", + "( cd /home/$USER/freeside2.3/$prefix; git commit -m $desc @ARGV && git push) )" +); + diff --git a/bin/3add b/bin/3add new file mode 100755 index 000000000..8bc034d9c --- /dev/null +++ b/bin/3add @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +system join('', + "git add @ARGV ; ", + "( for file in @ARGV; do ", + "cp -i \$file /home/$USER/freeside3/$prefix/`dirname \$file`;", + "done ) && ", + "cd /home/$USER/freeside3/$prefix/ && ", + "git add @ARGV" +); + diff --git a/bin/3commit b/bin/3commit new file mode 100755 index 000000000..37b500063 --- /dev/null +++ b/bin/3commit @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +# usage: 3commit 'log message' filename filename ... + +use Cwd; +use String::ShellQuote; + +my $USER = $ENV{USER}; + +my $dir = getcwd; +( my $prefix = $dir ) =~ s(^/home/$USER/freeside/?)() or die $dir; #eventually from anywhere + +my $desc = shell_quote(shift @ARGV); # -m + +die "no files!" unless @ARGV; + +#warn "$prefix"; + +#print <<END; +system join('', + "( cd /home/$USER/freeside3/$prefix; git pull ) && ", + "git diff -u @ARGV | ( cd /home/$USER/freeside3/$prefix; patch -p1 ) ", + " && ( ( git pull && git commit -m $desc @ARGV && git push ); ", + "( cd /home/$USER/freeside3/$prefix; git commit -m $desc @ARGV && git push ) )" +); + diff --git a/bin/3diff b/bin/3diff new file mode 100755 index 000000000..badafd579 --- /dev/null +++ b/bin/3diff @@ -0,0 +1,13 @@ +#!/usr/bin/perl + +my $file = shift; + +chomp(my $dir = `pwd`); +$dir =~ s/freeside(\/?)/freeside3$1/; +warn $dir; + +#$cmd = "diff -u $file $dir/$file"; +$cmd = "diff -ubBw $dir/$file $file"; +print "$cmd\n"; +system($cmd); + diff --git a/bin/cch.finish_failed b/bin/cch.finish_failed new file mode 100644 index 000000000..cb2533044 --- /dev/null +++ b/bin/cch.finish_failed @@ -0,0 +1,51 @@ +#!/usr/bin/perl -w + +use strict; +use Storable qw( thaw nfreeze ); +use MIME::Base64; +use FS::UID qw( adminsuidsetup ); +use FS::tax_rate; + +adminsuidsetup(shift); + +#my @namelist = qw( code detail geocode plus4 txmatrix zip ); +my @namelist = qw( code detail plus4 txmatrix zip ); + +my $cache_dir = '/usr/local/etc/freeside/cache.'. $FS::UID::datasrc. '/'; +my $dir = $cache_dir.'taxdata/cch'; + +my @list = (); +foreach my $name ( @namelist ) { + my $difffile = "$dir.new/$name.txt"; + if (1) { # ($update) { + #my $error = $job->update_statustext( "0,Comparing to previous $name" ); + #die $error if $error; + warn "processing $dir.new/$name.txt\n"; # if $DEBUG; + #my $olddir = $update ? "$dir.1" : ""; + my $olddir = "$dir.1"; + $difffile = FS::tax_rate::_perform_cch_diff( $name, "$dir.new", $olddir ); + } + $difffile =~ s/^$cache_dir//; + push @list, "${name}file:$difffile"; +} + +# perform the import +local $FS::tax_rate::keep_cch_files = 1; +my $param = { + 'format' => 'cch-update', + 'uploaded_files' => join( ',', @list ), +}; +my $error = + #_perform_batch_import( $job, encode_base64( nfreeze( $param ) ) ); + FS::tax_rate::_perform_batch_import( '', encode_base64( nfreeze( $param ) ) ); + +if ( $error ) { + warn "ERROR: $error\n"; +} else { + warn "success!\n"; +} + +#XXX do this manually +#rename "$dir.new", "$dir" +# or die "cch tax update processed, but can't rename $dir.new: $!\n"; + diff --git a/bin/cch.redelete b/bin/cch.redelete new file mode 100644 index 000000000..2cff389ad --- /dev/null +++ b/bin/cch.redelete @@ -0,0 +1,52 @@ +#!/usr/bin/perl -w + +use strict; +use Storable qw( thaw nfreeze ); +use MIME::Base64; +use FS::UID qw( adminsuidsetup ); +use FS::tax_rate; + +adminsuidsetup(shift); + +#my @namelist = qw( code detail geocode plus4 txmatrix zip ); +my @namelist = qw( plus4 txmatrix zip ); + +my $cache_dir = '/usr/local/etc/freeside/cache.'. $FS::UID::datasrc. '/'; +my $dir = $cache_dir.'taxdata/cch'; + +my @list = (); +foreach my $name ( @namelist ) { + my $difffile = "$dir.new/$name.txt"; + if (1) { # ($update) { + #my $error = $job->update_statustext( "0,Comparing to previous $name" ); + #die $error if $error; + warn "processing $dir.new/$name.txt\n"; # if $DEBUG; + #my $olddir = $update ? "$dir.1" : ""; + my $olddir = "$dir.1"; + $difffile = FS::tax_rate::_perform_cch_diff( $name, "$dir.new", $olddir ); + } + $difffile =~ s/^$cache_dir//; + push @list, "${name}file:$difffile"; +} + +# perform the import +local $FS::tax_rate::keep_cch_files = 1; +my $param = { + 'format' => 'cch-update', + 'uploaded_files' => join( ',', @list ), + 'delete_only' => 1, +}; +my $error = + #_perform_batch_import( $job, encode_base64( nfreeze( $param ) ) ); + FS::tax_rate::_perform_batch_import( '', encode_base64( nfreeze( $param ) ) ); + +if ( $error ) { + warn "ERROR: $error\n"; +} else { + warn "success!\n"; +} + +#XXX do this manually +#rename "$dir.new", "$dir" +# or die "cch tax update processed, but can't rename $dir.new: $!\n"; + diff --git a/bin/cdr-netsapiens.import b/bin/cdr-netsapiens.import index 8aa4ac0b7..1cce461e2 100755 --- a/bin/cdr-netsapiens.import +++ b/bin/cdr-netsapiens.import @@ -37,6 +37,7 @@ do { my $ns = $part_export->ns_command( 'GET', '/cdr/', 'time_release' => "$time_release,", '_sort' => '+time_release', + '_limit' => '500', ); #loop over them, double check duplicates, insert the rest diff --git a/bin/cdr_upstream_rate.import b/bin/cdr_upstream_rate.import index fda3883b5..ac2856cee 100755 --- a/bin/cdr_upstream_rate.import +++ b/bin/cdr_upstream_rate.import @@ -6,7 +6,7 @@ # # Example: bin/cdr_upstream_rate.import ivan 1 ~ivan/convergent/sample_rate_table.csv # -# username: a freeside login (from /usr/local/etc/freeside/mapsecrets) +# username: a freeside login # ratenum: rate plan (FS::rate) created with the web UI # filename: CSV file # diff --git a/bin/cust_main-bulk_change b/bin/cust_main-bulk_change index fdf53d999..32a6d7bd6 100755 --- a/bin/cust_main-bulk_change +++ b/bin/cust_main-bulk_change @@ -1,13 +1,15 @@ #!/usr/bin/perl use strict; -use vars qw( $opt_p ); +use vars qw( $opt_a $opt_p $opt_t $opt_k ); use Getopt::Std; use FS::UID qw(adminsuidsetup); -use FS::Record qw(qsearchs); +use FS::Record qw(qsearch qsearchs); use FS::cust_main; +use FS::cust_tag; +use FS::cust_pkg; -getopts('p:'); +getopts('a:p:t:k:'); my $user = shift or &usage; adminsuidsetup $user; @@ -31,17 +33,41 @@ while (<STDIN>) { next; } - if ( $opt_p ) { - $cust_main->payby($opt_p); + my %cust_tag = ( custnum=>$custnum, tagnum=>$opt_t ); + if ( $opt_t && ! qsearchs('cust_tag', \%cust_tag) ) { + my $cust_tag = new FS::cust_tag \%cust_tag; + my $error = $cust_tag->insert; + die "$error\n" if $error; } - my $error = $cust_main->replace; - die "$error\n" if $error; + if ( $opt_p || $opt_a ) { + $cust_main->agentnum($opt_a) if $opt_a; + $cust_main->payby($opt_p) if $opt_p; + + my $error = $cust_main->replace; + die "$error\n" if $error; + } + + if ( $opt_k ) { + foreach my $k (split(/\s*,\s*/, $opt_k)) { + my($old, $new) = split(/\s*:\s*/, $k); + foreach my $cust_pkg ( qsearch('cust_pkg', { + 'custnum' => $cust_main->custnum, + 'pkgpart' => $old, + }) + ) + { + $cust_pkg->pkgpart($new); + my $error = $cust_pkg->replace; + die "$error\n" if $error; + } + } + } } sub usage { - die "usage: cust_main-bulk_change -p NEW_PAYBY employee_username <custnums.txt\n"; + die "usage: cust_main-bulk_change [ -a agentnum ] [ -p NEW_PAYBY ] [ -t tagnum ] [ -k old_pkgpart:new_pkgpart,... ] employee_username <custnums.txt\n"; } =head1 NAME @@ -50,13 +76,19 @@ cust_main-bulk_change =head1 SYNOPSIS - cust_main-bulk_change -p NEW_PAYBY username <custnums.txt + cust_main-bulk_change [ -a agentnum ] [ -p NEW_PAYBY ] [ -t tagnum ] [ -k old_pkgpart:new_pkgpart,... ] username <custnums.txt =head1 DESCRIPTION -Command-line tool to change the payby field for a group of customers. +Command-line tool to make bulk changes to a group of customers. + +-a: new agentnum + +-p: new payby, for example, I<CARD> or I<DCRD> + +-t: tagnum to add if not present --p: new payby, for example, I<CARD> or I<DCRD>. +-k: old_pkgpart:new_pkgpart, for example, I<5:4>. Multiple entries can be comma-separated. user: Employee username diff --git a/bin/cust_pay_histogram b/bin/cust_pay_histogram index 714b32140..42bd8844d 100755 --- a/bin/cust_pay_histogram +++ b/bin/cust_pay_histogram @@ -103,7 +103,7 @@ Displays a histogram of cust_pay records in the database. -a: Only process payments of customers with the specified agentnum -user: From the mapsecrets file - see config.html from the base documentation +user: Freeside username =head1 BUGS diff --git a/bin/fs-migrate-supplemental b/bin/fs-migrate-supplemental new file mode 100755 index 000000000..dbef95fc1 --- /dev/null +++ b/bin/fs-migrate-supplemental @@ -0,0 +1,151 @@ +#!/usr/bin/perl + +use strict; +use FS::UID qw(adminsuidsetup); +use FS::Record qw(qsearch qsearchs); +use FS::cust_pkg; +use FS::part_pkg; + +my $user = shift or die &usage; +my @pkgparts = @ARGV or die &usage; +my $dbh = adminsuidsetup $user; + +$FS::UID::AutoCommit = 0; + +my %stats = ( + mainpkgs => 0, + created => 0, + linked => 0, + errors => 0, +); + +my %pkg_freq; # cache +foreach my $pkgpart (@pkgparts) { + my $part_pkg = FS::part_pkg->by_key($pkgpart) + or die "pkgpart $pkgpart not found.\n"; + $pkg_freq{$pkgpart} = $part_pkg->freq; + my @links = $part_pkg->supp_part_pkg_link + or die "pkgpart $pkgpart has no supplemental packages.\n"; + CUST_PKG: foreach my $cust_pkg ( + qsearch('cust_pkg', { + 'pkgpart' => $pkgpart, + 'cancel' => '', + }) + ) { + my $cust_main = $cust_pkg->cust_main; + my @existing = $cust_pkg->supplemental_pkgs; + my @active = grep { !$_->main_pkgnum } $cust_main->ncancelled_pkgs; + LINK: foreach my $link (@links) { + # yeah, it's expensive + # see if there's an existing package with this link identity + foreach (@existing) { + if ($_->pkglinknum == $link->pkglinknum) { + next LINK; + } + } + # no? then is there one with this pkgpart? + my $i = 0; + foreach (@active) { + if ( $_->pkgpart == $link->dst_pkgpart ) { + set_link($cust_pkg, $link, $_); + splice(@active, $i, 1); # delete it so we don't reuse it + next LINK; + } + } + # no? then create one + create_linked($cust_pkg, $link); + } #foreach $link + $stats{mainpkgs}++; + } #foreach $cust_pkg +} #foreach $pkgpart + +print " +Main packages: $stats{mainpkgs} +Supplemental packages linked: $stats{linked} +Supplemental packages ordered: $stats{created} +Errors: $stats{errors} +"; + +$dbh->commit or die $dbh->errstr; + +sub set_link { + my ($main_pkg, $part_pkg_link, $supp_pkg) = @_; + my $task = "linking package ".$supp_pkg->pkgnum. + " to package ".$main_pkg->pkgnum; + $supp_pkg->set('main_pkgnum', $main_pkg->pkgnum); + $supp_pkg->set('pkglinknum', $part_pkg_link->pkglinknum); + # Set the next bill date of the supplemental package to the nearest one in + # the future that lines up with the main package. If the main package + # hasn't started billing yet, use its future start date. + my $new_bill = $main_pkg->get('bill') || $main_pkg->get('start_date'); + if ( $new_bill ) { + my $old_bill = $supp_pkg->get('bill'); + my $diff = $new_bill - $old_bill; + my $main_freq = $pkg_freq{$main_pkg->pkgpart}; + my $prev_bill = 0; + while ($diff < 0) { + # this will exit once $new_bill has overtaken the existing bill date. + # if there is no existing bill date, then this will exit right away + # and set bill to the bill date of the main package, which is correct. + $prev_bill = $new_bill; + $new_bill = FS::part_pkg->add_freq($new_bill, $main_freq); + $diff = $new_bill - $old_bill; + } + # then, of $new_bill and $prev_bill, pick the one that's closer to $old_bill + if ( $prev_bill > 0 and + $new_bill - $old_bill > $old_bill - $prev_bill ) { + $supp_pkg->set('bill', $prev_bill); + } else { + $supp_pkg->set('bill', $new_bill); + } + } else { + # otherwise the main package hasn't been billed yet and has no + # start date, so we can't sync the supplemental to it yet. + # but we can still link them. + warn "$task: main package has no next bill date.\n"; + } + my $error = $supp_pkg->replace; + if ( $error ) { + warn "$task:\n $error\n"; + $stats{errors}++; + } else { + $stats{linked}++; + } + return; +} + +sub create_linked { + my ($main_pkg, $part_pkg_link) = @_; + my $task = "creating pkgpart ".$part_pkg_link->dst_pkgpart. + " supplemental to package ".$main_pkg->pkgnum; + my $supp_pkg = FS::cust_pkg->new({ + 'pkgpart' => $part_pkg_link->dst_pkgpart, + 'pkglinknum' => $part_pkg_link->pkglinknum, + 'custnum' => $main_pkg->custnum, + 'main_pkgnum' => $main_pkg->pkgnum, + 'locationnum' => $main_pkg->locationnum, + 'start_date' => $main_pkg->start_date, + 'order_date' => $main_pkg->order_date, + 'expire' => $main_pkg->expire, + 'adjourn' => $main_pkg->adjourn, + 'contract_end' => $main_pkg->contract_end, + 'susp' => $main_pkg->susp, + 'bill' => $main_pkg->bill, + 'refnum' => $main_pkg->refnum, + 'discountnum' => $main_pkg->discountnum, + 'waive_setup' => $main_pkg->waive_setup, + }); + my $error = $supp_pkg->insert; + if ( $error ) { + warn "$task:\n $error\n"; + $stats{errors}++; + } else { + $stats{created}++; + } + return; +} + +sub usage { + die "Usage:\n fs-migrate-supplemental user main_pkgpart\n"; +} + diff --git a/bin/fs-migrate-svc_acct_sm b/bin/fs-migrate-svc_acct_sm deleted file mode 100755 index 07f7b611c..000000000 --- a/bin/fs-migrate-svc_acct_sm +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/perl -Tw -# -# jeff@cmh.net 01-Jul-20 - -#to delay loading dbdef until we're ready -#BEGIN { $FS::Record::setup_hack = 1; } - -use strict; -use Term::Query qw(query); -#use DBI; -#use DBIx::DBSchema; -#use DBIx::DBSchema::Table; -#use DBIx::DBSchema::Column; -#use DBIx::DBSchema::ColGroup::Unique; -#use DBIx::DBSchema::ColGroup::Index; -use FS::Conf; -use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets); -use FS::Record qw(qsearch qsearchs); -use FS::svc_domain; -use FS::svc_forward; -use vars qw( $conf $old_default_domain %part_domain_svc %part_acct_svc %part_forward_svc $svc_acct $svc_acct_sm $error); - -die "Not running uid freeside!" unless checkeuid(); - -my $user = shift or die &usage; -getsecrets($user); - -$conf = new FS::Conf; -$old_default_domain = $conf->config('domain'); - -#needs to match FS::Record -#my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc; - -### -# This section would be the appropriate place to manipulate -# the schema & tables. -### - -## we need to add the domsvc to svc_acct -## we must add a svc_forward record.... -## I am thinking that the fields svcnum (int), destsvc (int), and -## dest (varchar (80)) are appropriate, with destsvc/dest an either/or -## much in the spirit of cust_main_invoice - -### -# massage the data -### - -my($dbh)=adminsuidsetup $user; - -$|=1; - -$FS::svc_Common::noexport_hack = 1; -$FS::svc_domain::whois_hack = 1; - -%part_domain_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'}); -%part_acct_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); -%part_forward_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_forward'}); - -die "No services with svcdb svc_domain!\n" unless %part_domain_svc; -die "No services with svcdb svc_acct!\n" unless %part_acct_svc; -die "No services with svcdb svc_forward!\n" unless %part_forward_svc; - -my($svc_domain) = qsearchs('svc_domain', { 'domain' => $old_default_domain }); -if (! $svc_domain || $svc_domain->domain != $old_default_domain) { - print <<EOF; - -Your database currently does not contain a svc_domain record for the -domain $old_default_domain. Would you like me to add one for you? -EOF - - my($response)=scalar(<STDIN>); - chop $response; - if ($response =~ /^[yY]/) { - print "\n\n", &menu_domain_svc, "\n", <<END; -I need to create new domain accounts. Which service shall I use for that? -END - my($domain_svcpart)=&getdomainpart; - - $svc_domain = new FS::svc_domain { - 'domain' => $old_default_domain, - 'svcpart' => $domain_svcpart, - 'action' => 'M', - }; -# $error=$svc_domain->insert && die "Error adding domain $old_default_domain: $error"; - $error=$svc_domain->insert; - die "Error adding domain $old_default_domain: $error" if $error; - }else{ - print <<EOF; - - This program cannot function properly until a svc_domain record matching -your conf_dir/domain file exists. -EOF - - exit 1; - } -} - -print "\n\n", &menu_acct_svc, "\n", <<END; -I may need to create some new pop accounts and set up forwarding to them -for some users. Which service shall I use for that? -END -my($pop_svcpart)=&getacctpart; - -print "\n\n", &menu_forward_svc, "\n", <<END; -I may need to create some new forwarding for some users. Which service -shall I use for that? -END -my($forward_svcpart)=&getforwardpart; - -sub menu_domain_svc { - ( join "\n", map "$_: ".$part_domain_svc{$_}->svc, sort keys %part_domain_svc ). "\n"; -} -sub menu_acct_svc { - ( join "\n", map "$_: ".$part_acct_svc{$_}->svc, sort keys %part_acct_svc ). "\n"; -} -sub menu_forward_svc { - ( join "\n", map "$_: ".$part_forward_svc{$_}->svc, sort keys %part_forward_svc ). "\n"; -} -sub getdomainpart { - $^W=0; # Term::Query isn't -w-safe - my $return = query "Enter part number:", 'irk', [ keys %part_domain_svc ]; - $^W=1; - $return; -} -sub getacctpart { - $^W=0; # Term::Query isn't -w-safe - my $return = query "Enter part number:", 'irk', [ keys %part_acct_svc ]; - $^W=1; - $return; -} -sub getforwardpart { - $^W=0; # Term::Query isn't -w-safe - my $return = query "Enter part number:", 'irk', [ keys %part_forward_svc ]; - $^W=1; - $return; -} - - -#migrate data - -my(@svc_accts) = qsearch('svc_acct', {}); -foreach $svc_acct (@svc_accts) { - my(@svc_acct_sms) = qsearch('svc_acct_sm', { - domuid => $svc_acct->getfield('uid'), - } - ); - - # Ok.. we've got the svc_acct record, and an array of svc_acct_sm's - # What do we do from here? - - # The intuitive: - # plop the svc_acct into the 'default domain' - # and then represent the svc_acct_sm's with svc_forwards - # they can be gussied up manually, later - # - # Perhaps better: - # when no svc_acct_sm exists, place svc_acct in 'default domain' - # when one svc_acct_sm exists, place svc_acct in corresponding - # domain & possibly create a svc_forward in 'default domain' - # when multiple svc_acct_sm's exists (in different domains) we'd - # better use the 'intuitive' approach. - # - # Specific way: - # as 'perhaps better,' but we may be able to guess which domain - # is correct by comparing the svcnum of domains to the username - # of the svc_acct - # - - # The intuitive way: - - my $def_acct = new FS::svc_acct ( { $svc_acct->hash } ); - $def_acct->setfield('domsvc' => $svc_domain->getfield('svcnum')); - $error = $def_acct->replace($svc_acct); - die "Error replacing svc_acct for " . $def_acct->username . " : $error" if $error; - - foreach $svc_acct_sm (@svc_acct_sms) { - - my($domrec)=qsearchs('svc_domain', { - svcnum => $svc_acct_sm->getfield('domsvc'), - }) || die "svc_acct_sm references invalid domsvc $svc_acct_sm->getfield('domsvc')\n"; - - if ($svc_acct_sm->getfield('domuser') =~ /^\*$/) { - - my($newdom) = new FS::svc_domain ( { $domrec->hash } ); - $newdom->setfield('catchall', $svc_acct->svcnum); - $newdom->setfield('action', "M"); - $error = $newdom->replace($domrec); - die "Error replacing svc_domain for (anything)@" . $domrec->domain . " : $error" if $error; - - } else { - - my($newacct) = new FS::svc_acct { - 'svcpart' => $pop_svcpart, - 'username' => $svc_acct_sm->getfield('domuser'), - 'domsvc' => $svc_acct_sm->getfield('domsvc'), - 'dir' => '/dev/null', - }; - $error = $newacct->insert; - die "Error adding svc_acct for " . $newacct->username . " : $error" if $error; - - my($newforward) = new FS::svc_forward { - 'svcpart' => $forward_svcpart, - 'srcsvc' => $newacct->getfield('svcnum'), - 'dstsvc' => $def_acct->getfield('svcnum'), - }; - $error = $newforward->insert; - die "Error adding svc_forward for " . $newacct->username ." : $error" if $error; - } - - $error = $svc_acct_sm->delete; - die "Error deleting svc_acct_sm for " . $svc_acct_sm->domuser ." : $error" if $error; - - }; - -}; - - -$dbh->commit or die $dbh->errstr; -$dbh->disconnect or die $dbh->errstr; - -print "svc_acct_sm records sucessfully migrated\n"; - -sub usage { - die "Usage:\n fs-migrate-svc_acct_sm user\n"; -} - diff --git a/bin/fs-radius-add-check b/bin/fs-radius-add-check index 4e4769e58..ee093b375 100755 --- a/bin/fs-radius-add-check +++ b/bin/fs-radius-add-check @@ -1,20 +1,18 @@ #!/usr/bin/perl -Tw # quick'n'dirty hack of fs-setup to add radius attributes +# (i'm not sure this even works in the new world of schema changes - everyone +# uses attributes via groups now) use strict; use DBI; -use FS::UID qw(adminsuidsetup checkeuid getsecrets); +use FS::UID qw(adminsuidsetup); use FS::raddb; -die "Not running uid freeside!" unless checkeuid(); - my %attrib2db = map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib; my $user = shift or die &usage; -getsecrets($user); - my $dbh = adminsuidsetup $user; ### diff --git a/bin/fs-radius-add-reply b/bin/fs-radius-add-reply index 3de01374f..c6c24e039 100755 --- a/bin/fs-radius-add-reply +++ b/bin/fs-radius-add-reply @@ -1,20 +1,18 @@ #!/usr/bin/perl -Tw # quick'n'dirty hack of fs-setup to add radius attributes +# (i'm not sure this even works in the new world of schema changes - everyone +# uses attributes via groups now) use strict; use DBI; -use FS::UID qw(adminsuidsetup checkeuid getsecrets); +use FS::UID qw(adminsuidsetup); use FS::raddb; -die "Not running uid freeside!" unless checkeuid(); - my %attrib2db = map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib; my $user = shift or die &usage; -getsecrets($user); - my $dbh = adminsuidsetup $user; ### diff --git a/bin/generate-table-module b/bin/generate-table-module index e7fc99258..b536360c5 100755 --- a/bin/generate-table-module +++ b/bin/generate-table-module @@ -95,7 +95,7 @@ close TEST; # add them to MANIFEST ### -system('cvs edit FS/MANIFEST'); +#system('cvs edit FS/MANIFEST'); open(MANIFEST,">>FS/MANIFEST") or die $!; print MANIFEST "FS/$table.pm\n", diff --git a/bin/megapop.pl b/bin/megapop.pl new file mode 100755 index 000000000..e2930fb55 --- /dev/null +++ b/bin/megapop.pl @@ -0,0 +1,114 @@ +#!/usr/bin/perl -Tw +# +# this will break when megapop changes the URL or format of their listing page. +# that's stupid. perhaps they can provide a machine-readable listing? + +use strict; +use LWP::UserAgent; +use FS::UID qw(adminsuidsetup); +use FS::svc_acct_pop; + +my $url = "http://www.megapop.com/location.htm"; + +my $user = shift or die &usage; +adminsuidsetup($user); + +my %state2usps = &state2usps; +$state2usps{'WASHINGTON STATE'} = 'WA'; #megapop's on crack +$state2usps{'CANADA'} = 'CANADA'; #freeside's on crack + +my $ua = new LWP::UserAgent; +my $request = new HTTP::Request('GET', $url); +my $response = $ua->request($request); +die $response->error_as_HTML unless $response->is_success; +my $line; +my $usps = ''; +foreach $line ( split("\n", $response->content) ) { + if ( $line =~ /\W(\w[\w\s]*\w)\s+LOCATIONS/i ) { + $usps = $state2usps{uc($1)} + or warn "warning: unknown state $1\n"; + } elsif ( $line =~ /(\d{3})\-(\d{3})\-(\d{4})\s+(\w[\w\s]*\w)/ ) { + print "$1 $2 $3 $4 $usps\n"; + my $svc_acct_pop = new FS::svc_acct_pop ( { + 'city' => $4, + 'state' => $usps, + 'ac' => $1, + 'exch' => $2, + } ); + my $error = $svc_acct_pop->insert; + die $error if $error; + } +} + +sub usage { + die "Usage:\n $0 user\n"; +} + +sub state2usps{ ( + 'ALABAMA' => 'AL', + 'ALASKA' => 'AK', + 'AMERICAN SAMOA' => 'AS', + 'ARIZONA' => 'AZ', + 'ARKANSAS' => 'AR', + 'CALIFORNIA' => 'CA', + 'COLORADO' => 'CO', + 'CONNECTICUT' => 'CT', + 'DELAWARE' => 'DE', + 'DISTRICT OF COLUMBIA' => 'DC', + 'FEDERATED STATES OF MICRONESIA' => 'FM', + 'FLORIDA' => 'FL', + 'GEORGIA' => 'GA', + 'GUAM' => 'GU', + 'HAWAII' => 'HI', + 'IDAHO' => 'ID', + 'ILLINOIS' => 'IL', + 'INDIANA' => 'IN', + 'IOWA' => 'IA', + 'KANSAS' => 'KS', + 'KENTUCKY' => 'KY', + 'LOUISIANA' => 'LA', + 'MAINE' => 'ME', + 'MARSHALL ISLANDS' => 'MH', + 'MARYLAND' => 'MD', + 'MASSACHUSETTS' => 'MA', + 'MICHIGAN' => 'MI', + 'MINNESOTA' => 'MN', + 'MISSISSIPPI' => 'MS', + 'MISSOURI' => 'MO', + 'MONTANA' => 'MT', + 'NEBRASKA' => 'NE', + 'NEVADA' => 'NV', + 'NEW HAMPSHIRE' => 'NH', + 'NEW JERSEY' => 'NJ', + 'NEW MEXICO' => 'NM', + 'NEW YORK' => 'NY', + 'NORTH CAROLINA' => 'NC', + 'NORTH DAKOTA' => 'ND', + 'NORTHERN MARIANA ISLANDS' => 'MP', + 'OHIO' => 'OH', + 'OKLAHOMA' => 'OK', + 'OREGON' => 'OR', + 'PALAU' => 'PW', + 'PENNSYLVANIA' => 'PA', + 'PUERTO RICO' => 'PR', + 'RHODE ISLAND' => 'RI', + 'SOUTH CAROLINA' => 'SC', + 'SOUTH DAKOTA' => 'SD', + 'TENNESSEE' => 'TN', + 'TEXAS' => 'TX', + 'UTAH' => 'UT', + 'VERMONT' => 'VT', + 'VIRGIN ISLANDS' => 'VI', + 'VIRGINIA' => 'VA', + 'WASHINGTON' => 'WA', + 'WEST VIRGINIA' => 'WV', + 'WISCONSIN' => 'WI', + 'WYOMING' => 'WY', + 'ARMED FORCES AFRICA' => 'AE', + 'ARMED FORCES AMERICAS' => 'AA', + 'ARMED FORCES CANADA' => 'AE', + 'ARMED FORCES EUROPE' => 'AE', + 'ARMED FORCES MIDDLE EAST' => 'AE', + 'ARMED FORCES PACIFIC' => 'AP', +) } + diff --git a/bin/rebill b/bin/rebill index 4f052384d..cf473398a 100755 --- a/bin/rebill +++ b/bin/rebill @@ -117,7 +117,7 @@ the bill and collect methods of a cust_main object. See L<FS::cust_main>. -k: skip notify_flat_delay and vacuum -user: From the mapsecrets file - see config.html from the base documentation +user: Freeside user custnum: if one or more customer numbers are specified, only bills those customers. Otherwise, bills all customers. diff --git a/bin/usps-webtools-test-script b/bin/usps-webtools-test-script new file mode 100755 index 000000000..414ae4cad --- /dev/null +++ b/bin/usps-webtools-test-script @@ -0,0 +1,38 @@ +#!/usr/bin/perl + +use FS::Misc::Geo 'standardize'; +use Data::Dumper; $Data::Dumper::Terse = 1; +my @tests = ( + { + address1 => '6406 Ivy Lane', + address2 => '', + city => 'Greenbelt', + state => 'MD', + zip => '', + }, + { + address1 => '8 Wildwood Drive', + address2 => '', + city => 'Old Lyme', + state => 'CT', + zip => '06371', + }, +); + +my ($userid, $password) = @ARGV; + +my %opt = ( + userid => $userid, + password=> $password, + test => 1, +); +my $i = 1; +foreach (@tests) { + print "Test $i\n"; + my $result = eval { standardize($_, %opt) }; + print "ERROR: $@\n\n" if $@; + print Dumper($result); + $i++; +} + +1; |
