summaryrefslogtreecommitdiff
path: root/FS/bin
diff options
context:
space:
mode:
Diffstat (limited to 'FS/bin')
-rwxr-xr-xFS/bin/freeside-addgroup50
-rw-r--r--FS/bin/freeside-addoutsource28
-rw-r--r--FS/bin/freeside-addoutsourceuser17
-rw-r--r--FS/bin/freeside-adduser108
-rwxr-xr-xFS/bin/freeside-bill128
-rwxr-xr-xFS/bin/freeside-daily161
-rw-r--r--FS/bin/freeside-deloutsource13
-rw-r--r--FS/bin/freeside-deloutsourceuser2
-rw-r--r--FS/bin/freeside-deluser2
-rwxr-xr-xFS/bin/freeside-email4
-rwxr-xr-xFS/bin/freeside-expiration-alerter4
-rwxr-xr-xFS/bin/freeside-monthly91
-rw-r--r--FS/bin/freeside-prepaidd41
-rw-r--r--FS/bin/freeside-queued7
-rwxr-xr-xFS/bin/freeside-reset-fixed69
-rw-r--r--FS/bin/freeside-selfservice-server23
-rwxr-xr-xFS/bin/freeside-setup86
-rw-r--r--FS/bin/freeside-sqlradius-radacctd2
-rwxr-xr-xFS/bin/freeside-upgrade132
19 files changed, 462 insertions, 506 deletions
diff --git a/FS/bin/freeside-addgroup b/FS/bin/freeside-addgroup
new file mode 100755
index 000000000..7b30f7d95
--- /dev/null
+++ b/FS/bin/freeside-addgroup
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+
+use strict;
+use vars qw($opt_s);
+use Getopt::Std;
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearch);
+use FS::CurrentUser;
+use FS::AccessRight;
+use FS::access_group;
+use FS::access_right;
+use FS::access_groupagent;
+
+getopts("s");
+my $user = shift or die &usage; #just for adminsuidsetup
+my $group = shift or die &usage;
+
+$FS::CurrentUser::upgrade_hack = 1;
+#adminsuidsetup $rootuser;
+adminsuidsetup $user;
+
+my $access_group = new FS::access_group { 'groupname' => $group };
+my $error = $access_group->insert;
+die $error if $error;
+
+if ( $opt_s ) {
+ foreach my $rightname ( FS::AccessRight->rights ) {
+ my $access_right = new FS::access_right {
+ 'righttype' => 'FS::access_group',
+ 'rightobjnum' => $access_group->groupnum,
+ 'rightname' => $rightname,
+ };
+ my $ar_error = $access_right->insert;
+ die $ar_error if $ar_error;
+ }
+
+ foreach my $agent ( qsearch('agent', {} ) ) {
+ my $access_groupagent = new FS::access_groupagent {
+ 'groupnum' => $access_group->groupnum,
+ 'agentnum' => $agent->agentnum,
+ };
+ my $aga_error = $access_groupagent->insert;
+ die $aga_error if $aga_error;
+ }
+}
+
+sub usage {
+ die "Usage:\n\n freeside-addgroup [ -s ] username groupname"
+}
+
diff --git a/FS/bin/freeside-addoutsource b/FS/bin/freeside-addoutsource
index db4e7a307..9cb12195a 100644
--- a/FS/bin/freeside-addoutsource
+++ b/FS/bin/freeside-addoutsource
@@ -2,23 +2,31 @@
domain=$1
+FREESIDE_CONF=%%%FREESIDE_CONF%%%
+FREESIDE_CACHE=%%%FREESIDE_CACHE%%%
+FREESIDE_EXPORT=%%%FREESIDE_EXPORT%%%
+
+#without this, [a-z]* matches CVS/, the copy doesn't return a sucessful error
+# status, and the rest of the commands aren't run
+export LANG=C
+
createdb $domain && \
\
-mkdir /usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain && \
+mkdir $FREESIDE_CONF/conf.DBI:Pg:dbname=$domain && \
\
-chown freeside /usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain && \
+chown freeside $FREESIDE_CONF/conf.DBI:Pg:dbname=$domain && \
\
-cp /home/ivan/freeside/conf/[a-z]* /usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain && \
+cp /home/ivan/freeside/conf/[a-z]* $FREESIDE_CONF/conf.DBI:Pg:dbname=$domain && \
\
-touch /usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain/secrets && \
+touch $FREESIDE_CONF/conf.DBI:Pg:dbname=$domain/secrets && \
\
-chown freeside /usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain/secrets && \
+chown freeside $FREESIDE_CONF/conf.DBI:Pg:dbname=$domain/secrets && \
\
-chmod 600 /usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain/secrets && \
+chmod 600 $FREESIDE_CONF/conf.DBI:Pg:dbname=$domain/secrets && \
\
-echo -e "DBI:Pg:dbname=$domain\nfreeside\n" >/usr/local/etc/freeside/conf.DBI:Pg:dbname=$domain/secrets && \
+echo -e "DBI:Pg:dbname=$domain\nfreeside\n" >$FREESIDE_CONF/conf.DBI:Pg:dbname=$domain/secrets && \
\
-mkdir /usr/local/etc/freeside/counters.DBI:Pg:dbname=$domain && \
-mkdir /usr/local/etc/freeside/cache.DBI:Pg:dbname=$domain && \
-mkdir /usr/local/etc/freeside/export.DBI:Pg:dbname=$domain
+mkdir $FREESIDE_CACHE/counters.DBI:Pg:dbname=$domain && \
+mkdir $FREESIDE_CACHE/cache.DBI:Pg:dbname=$domain && \
+mkdir $FREESIDE_EXPORT/export.DBI:Pg:dbname=$domain
diff --git a/FS/bin/freeside-addoutsourceuser b/FS/bin/freeside-addoutsourceuser
index cad07f1fd..cbe792acc 100644
--- a/FS/bin/freeside-addoutsourceuser
+++ b/FS/bin/freeside-addoutsourceuser
@@ -3,13 +3,16 @@
username=$1
domain=$2
password=$3
+realdomain=$4
+FREESIDE_CONF=%%%FREESIDE_CONF%%%
-freeside-adduser -h /usr/local/etc/freeside/htpasswd \
- -s conf.DBI:Pg:dbname=$domain/secrets \
- -b \
- $username $password 2>/dev/null
+freeside-adduser -s conf.DBI:Pg:dbname=$domain/secrets \
+ -n \
+ $username #2>/dev/null
-[ -e /usr/local/etc/freeside/dbdef.DBI:Pg:dbname=$domain ] \
- || ( freeside-setup -s $username 2>/dev/null; \
- /home/ivan/freeside/bin/populate-msgcat $username 2>/dev/null )
+[ -e $FREESIDE_CONF/dbdef.DBI:Pg:dbname=$domain ] \
+ || ( freeside-setup -d $realdomain -u $username )
+freeside-adduser -g 1 $username
+
+htpasswd -b $FREESIDE_CONF/htpasswd $username $password
diff --git a/FS/bin/freeside-adduser b/FS/bin/freeside-adduser
index c3ee05b9b..237e29ef8 100644
--- a/FS/bin/freeside-adduser
+++ b/FS/bin/freeside-adduser
@@ -1,37 +1,85 @@
#!/usr/bin/perl -w
-#
-# $Id: freeside-adduser,v 1.8 2002-09-27 05:36:29 ivan Exp $
use strict;
-use vars qw($opt_h $opt_b $opt_c $opt_s);
+use vars qw($opt_s $opt_g $opt_n);
use Fcntl qw(:flock);
use Getopt::Std;
-my $FREESIDE_CONF = "/usr/local/etc/freeside";
+my $FREESIDE_CONF = "%%%FREESIDE_CONF%%%";
-getopts("bch:s:");
-die &usage if $opt_c && ! $opt_h;
+getopts("s:g:n");
my $user = shift or die &usage;
-if ( $opt_h ) {
- my @args = ( 'htpasswd' );
- push @args, '-b' if $opt_b;
- push @args, '-c' if $opt_c;
- push @args, $opt_h, $user;
- push @args, shift if $opt_b;
- system(@args) == 0 or die "htpasswd failed: $?";
+if ( $opt_s ) {
+
+ #if ( -e "$FREESIDE_CONF/mapsecrets" ) {
+ # open(MAPSECRETS,"<$FREESIDE_CONF/mapsecrets")
+ # or die "can't open $FREESIDE_CONF/mapsecrets: $!";
+ # while (<MAPSECRETS>) {
+ # /^(\S+) / or die "unparsable line in mapsecrets: $_";
+ # die "user $user already exists\n" if $user eq $1;
+ # }
+ # close MAPSECRETS;
+ #}
+
+ #insert new entry before a wildcard...
+ open(MAPSECRETS,"<$FREESIDE_CONF/mapsecrets")
+ and flock(MAPSECRETS,LOCK_EX)
+ or die "can't open $FREESIDE_CONF/mapsecrets: $!";
+ open(NEW,">$FREESIDE_CONF/mapsecrets.new")
+ or die "can't open $FREESIDE_CONF/mapsecrets.new: $!";
+ while(<MAPSECRETS>) {
+ if ( /^\*\s/ ) {
+ print NEW "$user $opt_s\n";
+ }
+ print NEW $_;
+ }
+ close MAPSECRETS or die "can't close $FREESIDE_CONF/mapsecrets: $!";
+ close NEW or die "can't close $FREESIDE_CONF/mapsecrets.new: $!";
+ rename("$FREESIDE_CONF/mapsecrets.new", "$FREESIDE_CONF/mapsecrets")
+ or die "can't move mapsecrets.new into place: $!";
+
}
-my $secretfile = $opt_s || 'secrets';
+###
+
+exit if $opt_n;
+
+###
+
+use FS::UID qw(adminsuidsetup);
+use FS::CurrentUser;
+use FS::access_user;
+use FS::access_usergroup;
+
+$FS::CurrentUser::upgrade_hack = 1;
+#adminsuidsetup $rootuser;
+adminsuidsetup $user;
+
+my $access_user = new FS::access_user {
+ 'username' => $user,
+ '_password' => 'notyet',
+ 'first' => 'Firstname', # $opt_f ||
+ 'last' => 'Lastname', # $opt_l ||
+};
+my $au_error = $access_user->insert;
+die $au_error if $au_error;
+
+if ( $opt_g ) {
-open(MAPSECRETS,">>$FREESIDE_CONF/mapsecrets")
- and flock(MAPSECRETS,LOCK_EX)
- or die "can't open $FREESIDE_CONF/mapsecrets: $!";
-print MAPSECRETS "$user $secretfile\n";
-close MAPSECRETS or die "can't close $FREESIDE_CONF/mapsecrets: $!";
+ my $access_usergroup = new FS::access_usergroup {
+ 'usernum' => $access_user->usernum,
+ 'groupnum' => $opt_g,
+ };
+ my $aug_error = $access_usergroup->insert;
+ die $aug_error if $aug_error;
+
+}
+
+###
sub usage {
- die "Usage:\n\n freeside-adduser [ -h htpasswd_file [ -c ] [ -b ] ] [ -s secretfile ] username"
+ die "Usage:\n\n freeside-adduser [ -n ] [ -s ] [ -g groupnum ] username [ password ]"
}
=head1 NAME
@@ -40,24 +88,32 @@ freeside-adduser - Command line interface to add (freeside) users.
=head1 SYNOPSIS
- freeside-adduser [ -h htpasswd_file [ -c ] ] [ -s secretfile ] username
+ freeside-adduser [ -n ] [ -s ] [ -g groupnum ] username [ password ]
=head1 DESCRIPTION
Adds a user to the Freeside billing system. This is for adding users (internal
sales/tech folks) to the web interface, not for adding customer accounts.
- -h: Also call htpasswd for this user with the given filename
+This functionality is now available in the web interface as well, under
+B<Configuration | Employees | View/Edit employees>.
+
+ -g: initial groupnum
+
+ Development/multi-DB options:
+
+ -s: alternate secrets file
- -c: Passed to htpasswd(1)
+ -n: no ACL added, for bootstrapping
- -s: Specify an alternate secret file
+=head1 NOTE
- -b: same as htpasswd(1), probably insecure, not recommended
+No explicit htpasswd options are available in 1.7 - passwordsa are now
+maintained automatically.
=head1 SEE ALSO
-L<htpasswd>(1), base Freeside documentation
+Base Freeside documentation
=cut
diff --git a/FS/bin/freeside-bill b/FS/bin/freeside-bill
deleted file mode 100755
index 49ad4a768..000000000
--- a/FS/bin/freeside-bill
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/perl -w
-# don't take any world-facing input
-#!/usr/bin/perl -Tw
-
-use strict;
-use Fcntl qw(:flock);
-use Date::Parse;
-use Getopt::Std;
-use FS::UID qw(adminsuidsetup);
-use FS::Record qw(qsearch qsearchs);
-use FS::cust_main;
-
-&untaint_argv; #what it sounds like (eww)
-use vars qw($opt_a $opt_c $opt_d $opt_p);
-getopts("acd:p");
-my $user = shift or die &usage;
-
-adminsuidsetup $user;
-
-my %bill_only = map { $_ => 1 } (
- @ARGV ? @ARGV : ( map $_->custnum, qsearch('cust_main', {} ) )
-);
-
-#we're at now now (and later).
-my($time)= $opt_d ? str2time($opt_d) : $^T;
-
-# find packages w/ bill < time && cancel != '', and create corresponding
-# customer objects
-
-my($cust_main,%saw);
-foreach $cust_main (
- map {
- unless ( exists $saw{ $_->custnum } && defined $saw{ $_->custnum} ) {
- $saw{ $_->custnum } = 0; # to avoid 'use of uninitialized value' errors
- }
- if (
- ( $opt_a || ( ( $_->getfield('bill') || 0 ) <= $time ) )
- && $bill_only{ $_->custnum }
- && !$saw{ $_->custnum }++
- ) {
- qsearchs('cust_main',{'custnum'=> $_->custnum } );
- } else {
- ();
- }
- } ( qsearch('cust_pkg', { 'cancel' => '' }),
- qsearch('cust_pkg', { 'cancel' => 0 }),
- )
-) {
-
- # and bill them
-
- print "Billing customer #" . $cust_main->getfield('custnum') . "\n";
-
- my($error);
-
- $error=$cust_main->bill('time'=>$time);
- warn "Error billing, customer #" . $cust_main->getfield('custnum') .
- ":" . $error if $error;
-
- if ($opt_p) {
- $cust_main->apply_payments;
- $cust_main->apply_credits;
- }
-
- if ($opt_c) {
- $error=$cust_main->collect( 'invoice_time' => $time);
- warn "Error collecting from customer #" . $cust_main->custnum. ":$error"
- if $error;
-
- #sleep 1;
- }
-
-}
-
-# subroutines
-
-sub untaint_argv {
- foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
- #$ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
- # Date::Parse
- $ARGV[$_] =~ /^(.*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
- $ARGV[$_]=$1;
- }
-}
-
-sub usage {
- die "Usage:\n\n freeside-bill [ -c [ -p ] ] [ -d 'date' ] user [ custnum custnum ... ]\n";
-}
-
-=head1 NAME
-
-freeside-bill - Command line (crontab, script) interface to customer billing.
-
-=head1 SYNOPSIS
-
- freeside-bill [ -c [ -p ] [ -a ] ] [ -d 'date' ] user [ custnum custnum ... ]
-
-=head1 DESCRIPTION
-
-This script is deprecated in 1.4.0. You should use freeside-daily instead.
-
-Bills customers. Searches for customers who are due for billing and calls
-the bill and collect methods of a cust_main object. See L<FS::cust_main>.
-
- -c: Turn on collecting (you probably want this).
-
- -p: Apply unapplied payments and credits before collecting (you probably want
- this too)
-
- -a: Call collect even if there isn't a new invoice (probably a bad idea for
- daily use)
-
- -d: Pretend it's 'date'. Date is in any format Date::Parse is happy with,
- but be careful.
-
-user: From the mapsecrets file - see config.html from the base documentation
-
-custnum: if one or more customer numbers are specified, only bills those
-customers. Otherwise, bills all customers.
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<freeside-daily>, L<FS::cust_main>, config.html from the base documentation
-
-=cut
-
diff --git a/FS/bin/freeside-daily b/FS/bin/freeside-daily
index 603da12b8..a06a2b185 100755
--- a/FS/bin/freeside-daily
+++ b/FS/bin/freeside-daily
@@ -1,157 +1,32 @@
#!/usr/bin/perl -w
use strict;
-use Fcntl qw(:flock);
-use Date::Parse;
use Getopt::Std;
-use FS::UID qw(adminsuidsetup driver_name dbh datasrc);
-use FS::Record qw(qsearch qsearchs dbdef);
-use FS::Conf;
-use FS::cust_main;
+use FS::UID qw(adminsuidsetup);
&untaint_argv; #what it sounds like (eww)
-use vars qw($opt_d $opt_v $opt_p $opt_a $opt_s $opt_y);
-getopts("p:a:d:vsy:");
-my $user = shift or die &usage;
+#use vars qw($opt_d $opt_v $opt_p $opt_a $opt_s $opt_y);
+use vars qw(%opt);
+getopts("p:a:d:vsy:", \%opt);
+my $user = shift or die &usage;
adminsuidsetup $user;
-$FS::cust_main::DEBUG = 1 if $opt_v;
-
-my %search = ();
-$search{'payby'} = $opt_p if $opt_p;
-$search{'agentnum'} = $opt_a if $opt_a;
-
-#we're at now now (and later).
-my($time)= $opt_d ? str2time($opt_d) : $^T;
-$time += $opt_y * 86400 if $opt_y;
-
-# select * from cust_main where
-my $where_pkg = <<"END";
- 0 < ( select count(*) from cust_pkg
- where cust_main.custnum = cust_pkg.custnum
- and ( cancel is null or cancel = 0 )
- and ( setup is null or setup = 0
- or bill is null or bill <= $time
- or ( expire is not null and expire <= $^T )
- )
- )
-END
-
-# or
-my $where_bill_event = <<"END";
- 0 < ( select count(*) from cust_bill
- where cust_main.custnum = cust_bill.custnum
- and 0 < charged
- - coalesce(
- ( select sum(amount) from cust_bill_pay
- where cust_bill.invnum = cust_bill_pay.invnum )
- ,0
- )
- - coalesce(
- ( select sum(amount) from cust_credit_bill
- where cust_bill.invnum = cust_credit_bill.invnum )
- ,0
- )
- and 0 < ( select count(*) from part_bill_event
- where payby = cust_main.payby
- and ( disabled is null or disabled = '' )
- and seconds <= $time - cust_bill._date
- and 0 = ( select count(*) from cust_bill_event
- where cust_bill.invnum = cust_bill_event.invnum
- and part_bill_event.eventpart = cust_bill_event.eventpart
- and status = 'done'
- )
-
- )
- )
-END
-
-my $extra_sql = ( scalar(%search) ? ' AND ' : ' WHERE ' ). "( $where_pkg OR $where_bill_event )";
-
-my @cust_main;
-if ( @ARGV ) {
- @cust_main = map { qsearchs('cust_main', { custnum => $_, %search } ) } @ARGV
-} else {
- @cust_main = qsearch('cust_main', \%search, '', $extra_sql );
-}
-;
-
-my($cust_main,%saw);
-foreach $cust_main ( @cust_main ) {
-
- # $^T not $time because -d is for pre-printing invoices
- foreach my $cust_pkg (
- grep { $_->expire && $_->expire <= $^T } $cust_main->ncancelled_pkgs
- ) {
- my $error = $cust_pkg->cancel;
- warn "Error cancelling expired pkg ". $cust_pkg->pkgnum. " for custnum ".
- $cust_main->custnum. ": $error"
- if $error;
- }
- # $^T not $time because -d is for pre-printing invoices
- foreach my $cust_pkg (
- grep { $_->part_pkg->is_prepaid
- && $_->bill && $_->bill < $^T && ! $_->susp
- }
- $cust_main->ncancelled_pkgs
- ) {
- my $error = $cust_pkg->suspend;
- warn "Error suspending package ". $cust_pkg->pkgnum.
- " for custnum ". $cust_main->custnum.
- ": $error"
- if $error;
- }
-
- my $error = $cust_main->bill( 'time' => $time,
- 'resetup' => $opt_s, );
- warn "Error billing, custnum ". $cust_main->custnum. ": $error" if $error;
-
- $cust_main->apply_payments;
- $cust_main->apply_credits;
-
- $error = $cust_main->collect( 'invoice_time' => $time );
- warn "Error collecting, custnum". $cust_main->custnum. ": $error" if $error;
+use FS::Cron::bill qw(bill);
+bill(%opt);
-}
+use FS::Cron::notify qw(notify_flat_delay);
+notify_flat_delay(%opt);
-if ( driver_name eq 'Pg' ) {
- dbh->{AutoCommit} = 1; #so we can vacuum
- foreach my $table ( dbdef->tables ) {
- my $sth = dbh->prepare("VACUUM ANALYZE $table") or die dbh->errstr;
- $sth->execute or die $sth->errstr;
- }
-}
+use FS::Cron::vacuum qw(vacuum);
+vacuum();
-my $conf = new FS::Conf;
-my $dest = $conf->config('dump-scpdest');
-if ( $dest ) {
- datasrc =~ /dbname=([\w\.]+)$/ or die "unparsable datasrc ". datasrc;
- my $database = $1;
- eval "use Net::SCP qw(scp);";
- if ( driver_name eq 'Pg' ) {
- system("pg_dump $database >/var/tmp/$database.sql")
- } else {
- die "database dumps not yet supported for ". driver_name;
- }
- if ( $conf->config('dump-pgpid') ) {
- eval 'use GnuPG';
- my $gpg = new GnuPG;
- $gpg->encrypt( plaintext => "/var/tmp/$database.sql",
- output => "/var/tmp/$database.gpg",
- recipient => $conf->config('dump-pgpid'),
- );
- chmod 0600, '/var/tmp/$database.gpg';
- scp("/var/tmp/$database.gpg", $dest);
- unlink "/var/tmp/$database.gpg" or die $!;
- } else {
- chmod 0600, '/var/tmp/$database.sql';
- scp("/var/tmp/$database.sql", $dest);
- }
- unlink "/var/tmp/$database.sql" or die $!;
-}
+use FS::Cron::backup qw(backup_scp);
+backup_scp();
+###
# subroutines
+###
sub untaint_argv {
foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
@@ -166,6 +41,10 @@ sub usage {
die "Usage:\n\n freeside-daily [ -d 'date' ] user [ custnum custnum ... ]\n";
}
+###
+# documentation
+###
+
=head1 NAME
freeside-daily - Run daily billing and invoice collection events.
@@ -179,8 +58,6 @@ freeside-daily - Run daily billing and invoice collection events.
Bills customers and runs invoice collection events. Should be run from
crontab daily.
-This script replaces freeside-bill from 1.3.1.
-
Bills customers. Searches for customers who are due for billing and calls
the bill and collect methods of a cust_main object. See L<FS::cust_main>.
diff --git a/FS/bin/freeside-deloutsource b/FS/bin/freeside-deloutsource
index 561853539..afc3a0118 100644
--- a/FS/bin/freeside-deloutsource
+++ b/FS/bin/freeside-deloutsource
@@ -1,11 +1,14 @@
#!/bin/sh
domain=$1
+FREESIDE_CONF=%%%FREESIDE_CONF%%%
+FREESIDE_CACHE=%%%FREESIDE_CACHE%%%
+FREESIDE_EXPORT=%%%FREESIDE_EXPORT%%%
dropdb $domain && \
-rm -rf /usr/local/etc/freeside/conf.DBI:Pg:host=localhost\;dbname=$domain && \
-rm -rf /usr/local/etc/freeside/counters.DBI:Pg:host=localhost\;dbname=$domain && \
-rm -rf /usr/local/etc/freeside/cache.DBI:Pg:host=localhost\;dbname=$domain && \
-rm -rf /usr/local/etc/freeside/export.DBI:Pg:host=localhost\;dbname=$domain && \
-rm /usr/local/etc/freeside/dbdef.DBI:Pg:host=localhost\;dbname=$domain
+rm -rf $FREESIDE_CONF/conf.DBI:Pg:host=localhost\;dbname=$domain && \
+rm -rf $FREESIDE_CACHE/counters.DBI:Pg:host=localhost\;dbname=$domain && \
+rm -rf $FREESIDE_CACHE/cache.DBI:Pg:host=localhost\;dbname=$domain && \
+rm -rf $FREESIDE_EXPORT/export.DBI:Pg:host=localhost\;dbname=$domain && \
+rm $FREESIDE_CONF/dbdef.DBI:Pg:host=localhost\;dbname=$domain
diff --git a/FS/bin/freeside-deloutsourceuser b/FS/bin/freeside-deloutsourceuser
index 96871e50c..dc4ff9cdc 100644
--- a/FS/bin/freeside-deloutsourceuser
+++ b/FS/bin/freeside-deloutsourceuser
@@ -2,5 +2,5 @@
username=$1
-freeside-deluser -h /usr/local/etc/freeside/htpasswd $username 2>/dev/null
+freeside-deluser -h %%%FREESIDE_CONF%%%/htpasswd $username 2>/dev/null
diff --git a/FS/bin/freeside-deluser b/FS/bin/freeside-deluser
index 57d6ce165..a2a361a83 100644
--- a/FS/bin/freeside-deluser
+++ b/FS/bin/freeside-deluser
@@ -5,7 +5,7 @@ use vars qw($opt_h);
use Fcntl qw(:flock);
use Getopt::Std;
-my $FREESIDE_CONF = "/usr/local/etc/freeside";
+my $FREESIDE_CONF = "%%%FREESIDE_CONF%%%";
getopts("h:");
my $user = shift or die &usage;
diff --git a/FS/bin/freeside-email b/FS/bin/freeside-email
index 400dc2ac7..7a93f78ee 100755
--- a/FS/bin/freeside-email
+++ b/FS/bin/freeside-email
@@ -47,10 +47,6 @@ Prints the email addresses of all customers on STDOUT, separated by newlines.
user: From the mapsecrets file - see config.html from the base documentation
-=head1 VERSION
-
-$Id: freeside-email,v 1.2 2002-09-18 22:50:44 ivan Exp $
-
=head1 BUGS
=head1 SEE ALSO
diff --git a/FS/bin/freeside-expiration-alerter b/FS/bin/freeside-expiration-alerter
index 691fd3aa5..e49bd62aa 100755
--- a/FS/bin/freeside-expiration-alerter
+++ b/FS/bin/freeside-expiration-alerter
@@ -200,10 +200,6 @@ is about to expire. Usually run as a cron job.
user: From the mapsecrets file - see config.html from the base documentation
-=head1 VERSION
-
-$Id: freeside-expiration-alerter,v 1.5 2003-04-21 20:53:57 ivan Exp $
-
=head1 BUGS
Yes..... Use at your own risk. No guarantees or warrantees of any
diff --git a/FS/bin/freeside-monthly b/FS/bin/freeside-monthly
new file mode 100755
index 000000000..a6c75e715
--- /dev/null
+++ b/FS/bin/freeside-monthly
@@ -0,0 +1,91 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Getopt::Std;
+use FS::UID qw(adminsuidsetup);
+
+&untaint_argv; #what it sounds like (eww)
+#use vars qw($opt_d $opt_v $opt_p $opt_a $opt_s $opt_y);
+use vars qw(%opt);
+getopts("p:a:d:vsy:", \%opt);
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+use FS::Cron::bill qw(bill);
+bill(%opt, 'freq'=>'1m' );
+
+###
+# subroutines
+###
+
+sub untaint_argv {
+ foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
+ #$ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
+ # Date::Parse
+ $ARGV[$_] =~ /^(.*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
+ $ARGV[$_]=$1;
+ }
+}
+
+sub usage {
+ die "Usage:\n\n freeside-monthly [ -d 'date' ] user [ custnum custnum ... ]\n";
+}
+
+###
+# documentation
+###
+
+=head1 NAME
+
+freeside-monthly - Run monthly billing and invoice collection events.
+
+=head1 SYNOPSIS
+
+ freeside-monthly [ -d 'date' ] [ -y days ] [ -p 'payby' ] [ -a agentnum ] [ -s ] [ -v ] user [ custnum custnum ... ]
+
+=head1 DESCRIPTION
+
+Bills customers and runs invoice collection events, for the alternate monthly
+event chain. If you have defined monthly event checks, should be run from
+crontab monthly.
+
+Bills customers. Searches for customers who are due for billing and calls
+the bill and collect methods of a cust_main object. See L<FS::cust_main>.
+
+ -d: Pretend it's 'date'. Date is in any format Date::Parse is happy with,
+ but be careful.
+
+ -y: In addition to -d, which specifies an absolute date, the -y switch
+ specifies an offset, in days. For example, "-y 15" would increment the
+ "pretend date" 15 days from whatever was specified by the -d switch
+ (or now, if no -d switch was given).
+
+ -p: Only process customers with the specified payby (I<CARD>, I<DCRD>, I<CHEK>, I<DCHK>, I<BILL>, I<COMP>, I<LECB>)
+
+ -a: Only process customers with the specified agentnum
+
+ -s: re-charge setup fees
+
+ -v: enable debugging
+
+user: From the mapsecrets file - see config.html from the base documentation
+
+custnum: if one or more customer numbers are specified, only bills those
+customers. Otherwise, bills all customers.
+
+=head1 NOTE
+
+In most cases, you would use freeside-daily only and not freeside-monthly.
+freeside-monthly would only be used in cases where you have events that can
+only be run once each month, for example, batching invoices to a third-party
+print/mail provider.
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<freeside-daily>, L<FS::cust_main>, config.html from the base documentation
+
+=cut
+
diff --git a/FS/bin/freeside-prepaidd b/FS/bin/freeside-prepaidd
index e51a56350..73f7523c4 100644
--- a/FS/bin/freeside-prepaidd
+++ b/FS/bin/freeside-prepaidd
@@ -3,7 +3,7 @@
use strict;
use FS::Daemon qw(daemonize1 drop_root logfile daemonize2 sigint sigterm);
use FS::UID qw(adminsuidsetup);
-use FS::Record qw(qsearch); # qsearchs);
+use FS::Record qw(qsearch qsearchs);
use FS::cust_pkg;
my $user = shift or die &usage;
@@ -37,9 +37,38 @@ while (1) {
" AND ( cancel IS NULL OR cancel = 0)"
} )
) {
- my $error = $cust_pkg->suspend;
- warn "Error suspended package ". $cust_pkg->pkgnum.
- " for custnum ". $cust_pkg->custnum.
+
+ my $work_cust_pkg = $cust_pkg;
+
+ my $cust_main = $cust_pkg->cust_main;
+ if ( $cust_main->total_unapplied_payments > 0
+ or $cust_main->total_credited > 0
+ )
+ {
+ #this needs a flag to say only do the prepaid packages...
+ # and only try em if the renewal price matches.. but this will do for now
+ my $b_error = $cust_main->bill;
+ if ( $b_error ) {
+ warn "Error billing customer #". $cust_main->custnum;
+ next;
+ }
+ #$b_error = $cust_main->apply_payments_and_credits;
+ $b_error = $cust_main->apply_payments;
+ $b_error = $cust_main->apply_credits;
+
+ $work_cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $work_cust_pkg->pkgnum } );
+
+ next
+ if $cust_main->balance <= 0
+ and $work_cust_pkg->bill >= time;
+ }
+
+ my $action = $work_cust_pkg->part_pkg->option('recur_action') || 'suspend';
+
+ my $error = $work_cust_pkg->$action();
+
+ warn "Error ${action}ing package ". $work_cust_pkg->pkgnum.
+ " for custnum ". $work_cust_pkg->custnum.
": $error\n"
if $error;
}
@@ -65,8 +94,8 @@ freeside-prepaidd - Real-time daemon for prepaid packages
=head1 DESCRIPTION
-Runs continuously and suspendes any prepaid customer packages which have
-passed their renewal date (next bill date).
+Runs continuously and suspends or cancels any prepaid customer packages which
+have passed their renewal date (next bill date).
=head1 SEE ALSO
diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued
index 3a0a9b4e5..93d735d1a 100644
--- a/FS/bin/freeside-queued
+++ b/FS/bin/freeside-queued
@@ -10,11 +10,8 @@ use FS::Record qw(qsearch qsearchs);
use FS::queue;
use FS::queue_depend;
-# no autoloading just yet
-use FS::cust_main;
-use FS::svc_acct;
+# no autoloading for non-FS classes...
use Net::SSH 0.07;
-use FS::part_export;
$DEBUG = 0;
@@ -44,7 +41,7 @@ while ( $@ ) {
}
}
-logfile( "/usr/local/etc/freeside/queuelog.". $FS::UID::datasrc );
+logfile( "%%%FREESIDE_LOG%%%/queuelog.". $FS::UID::datasrc );
warn "completing daemonization (detaching))\n" if $DEBUG;
daemonize2();
diff --git a/FS/bin/freeside-reset-fixed b/FS/bin/freeside-reset-fixed
new file mode 100755
index 000000000..5829d441b
--- /dev/null
+++ b/FS/bin/freeside-reset-fixed
@@ -0,0 +1,69 @@
+#!/usr/bin/perl -w
+
+use strict;
+use vars qw($opt_p $opt_s $opt_r);
+use Getopt::Std;
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearch qsearchs);
+use FS::cust_svc;
+use FS::svc_Common;
+
+getopts('p:s:r');
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+die &usage
+ if ($opt_p && $opt_s);
+
+$FS::Record::nowarn_identical = 1;
+$FS::svc_Common::noexport_hack = 1
+ unless $opt_r;
+
+my @svc_x = ();
+if ( $opt_s ) {
+ $opt_s =~ /^(\d+)$/ or die "invalid svcnum";
+ my $cust_svc = qsearchs('cust_svc', { svcnum => $1 } )
+ or die "svcnum $opt_s not found\n";
+ push @svc_x, $cust_svc->svc_x;
+} elsif ( $opt_p ) {
+ $opt_p =~ /^(\d+)$/ or die "invalid svcpart";
+ push @svc_x, map { $_->svc_x } qsearch('cust_svc', { svcpart => $1 } );
+ die "no services with svcpart $opt_p found\n" unless @svc_x;
+} else {
+ push @svc_x, map { $_->svc_x } qsearch('cust_svc', {} );
+ die "no services found\n" unless @svc_x;
+}
+
+foreach my $svc_x ( @svc_x ) {
+ my $result = $svc_x->setfixed;
+ die $result unless ref($result);
+ my $error = $svc_x->replace
+ if $svc_x->modified;
+ die $error if $error;
+}
+
+
+sub usage {
+ die "Usage:\n\n freeside-reset-fixed user [ -s svcnum | -p svcpart ] [ -r ]\n";
+}
+
+=head1 NAME
+
+freeside-reset-fixed - Command line tool to set the fixed columns for existing services
+
+=head1 SYNOPSIS
+
+ freeside-reset-fixed user [ -s svcnum | -p svcpart ] [ -r ]
+
+=head1 DESCRIPTION
+
+ Resets the fixed columns for the specified service part or service number.
+ Re-exports the service if -r is specified.
+
+=head1 SEE ALSO
+
+L<freeside-reexport>, L<FS::part_svc>
+
+=cut
+
diff --git a/FS/bin/freeside-selfservice-server b/FS/bin/freeside-selfservice-server
index c73349a60..187bc1469 100644
--- a/FS/bin/freeside-selfservice-server
+++ b/FS/bin/freeside-selfservice-server
@@ -1,7 +1,8 @@
#!/usr/bin/perl -w
use strict;
-use vars qw( $Debug %kids $kids $max_kids $ssh_pid $keepalives );
+use vars qw( $FREESIDE_LOG $FREESIDE_LOCK );
+use vars qw( $Debug %kids $kids $max_kids $ssh_pid %old_ssh_pid $keepalives );
use subs qw( lock_write unlock_write myshutdown usage );
use Fcntl qw(:flock);
use POSIX qw(:sys_wait_h);
@@ -18,6 +19,9 @@ use FS::Conf;
use FS::cust_bill;
use FS::cust_pkg;
+$FREESIDE_LOG = "%%%FREESIDE_LOG%%%";
+$FREESIDE_LOCK = "%%%FREESIDE_LOCK%%%";
+
$Debug = 1; # 2 will turn on more logging
# 3 will log packet contents, including passwords
@@ -29,8 +33,7 @@ my $user = shift or die &usage;
my $machine = shift or die &usage;
my $tag = scalar(@ARGV) ? shift : '';
-my $lock_file = "/usr/local/etc/freeside/selfservice.$machine.writelock";
-
+my $lock_file = "$FREESIDE_LOCK/selfservice.$machine.writelock";
# to keep pid files unique w/multi machines (and installs!)
# $FS::UID::datasrc not posible
@@ -50,11 +53,10 @@ $ENV{HOME} = (getpwuid($>))[7]; #for ssh
adminsuidsetup $user;
#logfile("/usr/local/etc/freeside/selfservice.". $FS::UID::datasrc); #MACHINE
-logfile("/usr/local/etc/freeside/selfservice.$machine.log");
+logfile("$FREESIDE_LOG/selfservice.$machine.log");
daemonize2();
-
my $conf = new FS::Conf;
my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name?
@@ -102,6 +104,7 @@ while (1) {
if ( $ssh_pid ) {
warn "sending TERM signal to ssh process $ssh_pid\n" if $Debug;
kill 'TERM', $ssh_pid;
+ $old_ssh_pid{$ssh_pid} = 1;
$ssh_pid = 0;
}
last;
@@ -133,11 +136,11 @@ while (1) {
} else { #kid time
##get new db handle
- #$FS::UID::dbh->{InactiveDestroy} = 1;
- #forksuidsetup($user);
+ $FS::UID::dbh->{InactiveDestroy} = 1;
+ forksuidsetup($user);
#get db handle
- adminsuidsetup($user);
+ #adminsuidsetup($user);
my $type = $packet->{_packet};
warn "calling $type handler\n" if $Debug;
@@ -180,6 +183,10 @@ sub reap_kids {
delete $kids{$kid};
}
}
+
+ foreach my $pid ( keys %old_ssh_pid ) {
+ waitpid($pid, WNOHANG) and delete $old_ssh_pid{$pid};
+ }
#warn "done reaping\n";
}
diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup
index a16e51749..ddc210f50 100755
--- a/FS/bin/freeside-setup
+++ b/FS/bin/freeside-setup
@@ -4,28 +4,27 @@
BEGIN { $FS::Schema::setup_hack = 1; }
use strict;
-use vars qw($opt_s);
+use vars qw($opt_u $opt_d $opt_v);
use Getopt::Std;
-use Locale::Country;
-use Locale::SubCountry;
use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
+use FS::CurrentUser;
use FS::Schema qw( dbdef_dist reload_dbdef );
use FS::Record;
-use FS::cust_main_county;
#use FS::raddb;
-use FS::part_bill_event;
+use FS::Setup qw(create_initial_data);
die "Not running uid freeside!" unless checkeuid();
#my %attrib2db =
# map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib;
-getopts("s");
-my $user = shift or die &usage;
-getsecrets($user);
+getopts("u:vd:");
+#my $user = shift or die &usage;
+
+getsecrets($opt_u); #$user);
#needs to match FS::Record
-my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
+my($dbdef_file) = "%%%FREESIDE_CONF%%%/dbdef.". datasrc;
###
@@ -88,12 +87,14 @@ $dbdef->save($dbdef_file);
# create 'em
###
-my $dbh = adminsuidsetup $user;
+$FS::CurrentUser::upgrade_hack = 1;
+my $dbh = adminsuidsetup $opt_u; #$user;
#create tables
$|=1;
foreach my $statement ( $dbdef->sql($dbh) ) {
+ warn $statement if $statement =~ /TABLE cdr/;
$dbh->do( $statement )
or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
}
@@ -104,69 +105,14 @@ dbdef_create($dbh, $dbdef_file);
delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
reload_dbdef($dbdef_file);
-#cust_main_county
-foreach my $country ( sort map uc($_), all_country_codes ) {
-
- my $subcountry = eval { new Locale::SubCountry($country) };
- my @states = $subcountry ? $subcountry->all_codes : undef;
-
- if ( !scalar(@states) || ( scalar(@states) == 1 && !defined($states[0]) ) ) {
-
- my $cust_main_county = new FS::cust_main_county({
- 'tax' => 0,
- 'country' => $country,
- });
- my $error = $cust_main_county->insert;
- die $error if $error;
-
- } else {
-
- if ( $states[0] =~ /^(\d+|\w)$/ ) {
- @states = map $subcountry->full_name($_), @states
- }
-
- foreach my $state ( @states ) {
+create_initial_data('domain' => $opt_d);
- my $cust_main_county = new FS::cust_main_county({
- 'state' => $state,
- 'tax' => 0,
- 'country' => $country,
- });
- my $error = $cust_main_county->insert;
- die $error if $error;
-
- }
-
- }
-}
-
-#billing events
-foreach my $aref (
- #[ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
- [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
- [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
- [ 'DCRD', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
- [ 'DCHK', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
-) {
-
- my $part_bill_event = new FS::part_bill_event({
- 'payby' => $aref->[0],
- 'event' => $aref->[1],
- 'eventcode' => $aref->[2],
- 'seconds' => 0,
- 'weight' => $aref->[3],
- 'plan' => $aref->[4],
- });
- my($error);
- $error=$part_bill_event->insert;
- die $error if $error;
-
-}
+warn "Freeside database initialized - commiting transaction\n" if $opt_v;
$dbh->commit or die $dbh->errstr;
$dbh->disconnect or die $dbh->errstr;
-#print "Freeside database initialized sucessfully\n";
+warn "Database initialization committed successfully\n" if $opt_v;
sub dbdef_create { # reverse engineer the schema from the DB and save to file
my( $dbh, $file ) = @_;
@@ -175,8 +121,10 @@ sub dbdef_create { # reverse engineer the schema from the DB and save to file
}
sub usage {
- die "Usage:\n freeside-setup user\n";
+ die "Usage:\n freeside-setup -d domain.name [ -v ]\n"
+ # [ -u user ] for devel/multi-db installs
}
1;
+
diff --git a/FS/bin/freeside-sqlradius-radacctd b/FS/bin/freeside-sqlradius-radacctd
index e98eaa015..83fd4bfd1 100644
--- a/FS/bin/freeside-sqlradius-radacctd
+++ b/FS/bin/freeside-sqlradius-radacctd
@@ -23,7 +23,7 @@ drop_root();
adminsuidsetup $user;
-logfile( "/usr/local/etc/freeside/sqlradius-radacctd-log.". $FS::UID::datasrc );
+logfile( "%%%FREESIDE_LOG%%%/sqlradius-radacctd-log.". $FS::UID::datasrc );
daemonize2();
diff --git a/FS/bin/freeside-upgrade b/FS/bin/freeside-upgrade
index 419384c2a..3a4e4f8e3 100755
--- a/FS/bin/freeside-upgrade
+++ b/FS/bin/freeside-upgrade
@@ -1,88 +1,45 @@
#!/usr/bin/perl -w
use strict;
+use vars qw($opt_d $opt_q $opt_v);
use vars qw($DEBUG $DRY_RUN);
-use Term::ReadKey;
-use DBIx::DBSchema 0.27;
+use Getopt::Std;
+use DBIx::DBSchema 0.31;
use FS::UID qw(adminsuidsetup checkeuid datasrc ); #getsecrets);
+use FS::CurrentUser;
use FS::Schema qw( dbdef dbdef_dist reload_dbdef );
+die "Not running uid freeside!" unless checkeuid();
-$DEBUG = 1;
-$DRY_RUN = 0;
+getopts("dq");
+$DEBUG = !$opt_q;
+#$DEBUG = $opt_v;
-die "Not running uid freeside!" unless checkeuid();
+$DRY_RUN = $opt_d;
my $user = shift or die &usage;
+$FS::CurrentUser::upgrade_hack = 1;
my $dbh = adminsuidsetup($user);
#needs to match FS::Schema...
-my $dbdef_file = "/usr/local/etc/freeside/dbdef.". datasrc;
+my $dbdef_file = "%%%FREESIDE_CONF%%%/dbdef.". datasrc;
dbdef_create($dbh, $dbdef_file);
delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
reload_dbdef($dbdef_file);
+$DBIx::DBSchema::DEBUG = $DEBUG;
+$DBIx::DBSchema::Table::DEBUG = $DEBUG;
-foreach my $table ( dbdef_dist->tables ) {
-
- if ( dbdef->table($table) ) {
-
- warn "$table exists\n" if $DEBUG > 1;
-
- foreach my $column ( dbdef_dist->table($table)->columns ) {
- if ( dbdef->table($table)->column($column) ) {
- warn " $table.$column exists\n" if $DEBUG > 2;
- } else {
-
- if ( $DEBUG ) {
- print STDERR "column $table.$column does not exist. create?";
- next unless yesno();
- }
-
- foreach my $statement (
- dbdef_dist->table($table)->column($column)->sql_add_column( $dbh )
- ) {
- warn "$statement\n" if $DEBUG || $DRY_RUN;
- unless ( $DRY_RUN ) {
- $dbh->do( $statement)
- or die "CREATE error: ". $dbh->errstr. "\nexecuting: $statement";
- }
- }
-
- }
-
- }
-
- #should eventually check & create missing indices
-
- #should eventually drop columns not in dbdef_dist...
-
- } else {
-
- if ( $DEBUG ) {
- print STDERR "table $table does not exist. create?";
- next unless yesno();
- }
-
- foreach my $statement (
- dbdef_dist->table($table)->sql_create_table( $dbh )
- ) {
- warn "$statement\n" if $DEBUG || $DRY_RUN;
- unless ( $DRY_RUN ) {
- $dbh->do( $statement)
- or die "CREATE error: ". $dbh->errstr. "\nexecuting: $statement";
- }
- }
-
- }
-
+if ( $DRY_RUN ) {
+ print join(";\n", dbdef->sql_update_schema( dbdef_dist, $dbh ) ). ";\n";
+ exit;
+} else {
+ dbdef->update_schema( dbdef_dist, $dbh );
}
-# should eventually drop tables not in dbdef_dist too i guess...
-
$dbh->commit or die $dbh->errstr;
dbdef_create($dbh, $dbdef_file);
@@ -91,32 +48,6 @@ $dbh->disconnect or die $dbh->errstr;
###
-my $all = 0;
-sub yesno {
- print STDERR ' [yes/no/all] ';
- if ( $all ) {
- warn "yes\n";
- return 1;
- } else {
- while ( 1 ) {
- ReadMode 4;
- my $x = lc(ReadKey);
- ReadMode 0;
- if ( $x eq 'n' ) {
- warn "no\n";
- return 0;
- } elsif ( $x eq 'y' ) {
- warn "yes\n";
- return 1;
- } elsif ( $x eq 'a' ) {
- warn "yes\n";
- $all = 1;
- return 1;
- }
- }
- }
-}
-
sub dbdef_create { # reverse engineer the schema from the DB and save to file
my( $dbh, $file ) = @_;
my $dbdef = new_native DBIx::DBSchema $dbh;
@@ -124,8 +55,31 @@ sub dbdef_create { # reverse engineer the schema from the DB and save to file
}
sub usage {
- die "Usage:\n freeside-upgrade user\n";
+ die "Usage:\n freeside-upgrade [ -d ] [ -q | -v ] user\n";
}
-1;
+=head1 NAME
+
+freeside-upgrade - Upgrades database schema for new freeside verisons.
+
+=head1 SYNOPSIS
+
+ freeside-adduser [ -d ] [ -q | -v ]
+
+=head1 DESCRIPTION
+
+Reads your existing database schema and updates it to match the current schema,
+adding any columns or tables necessary.
+
+ [ -d ]: Dry run; output SQL statements (to STDOUT) only, but do not execute
+ them.
+
+ [ -q ]: Run quietly. This may become the default at some point.
+
+ [ -v ]: Run verbosely, sending debugging information to STDERR. This is the
+ current default.
+
+=head1 SEE ALSO
+
+=cut