summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
Diffstat (limited to 'FS')
-rw-r--r--FS/FS.pm2
-rw-r--r--FS/FS/ClientAPI.pm4
-rw-r--r--FS/FS/ClientAPI/passwd.pm9
-rw-r--r--FS/FS/Conf.pm14
-rw-r--r--FS/FS/InitHandler.pm5
-rw-r--r--FS/FS/Record.pm152
-rw-r--r--FS/FS/UID.pm6
-rw-r--r--FS/FS/ac.pm148
-rwxr-xr-xFS/FS/ac_block.pm148
-rwxr-xr-xFS/FS/ac_field.pm138
-rwxr-xr-xFS/FS/ac_type.pm128
-rw-r--r--FS/FS/cust_bill.pm103
-rw-r--r--FS/FS/cust_main_invoice.pm9
-rw-r--r--FS/FS/cust_pkg.pm14
-rw-r--r--FS/FS/cust_svc.pm10
-rwxr-xr-xFS/FS/part_ac_field.pm102
-rw-r--r--FS/FS/part_export.pm7
-rw-r--r--FS/FS/part_pkg.pm2
-rw-r--r--FS/FS/part_svc.pm27
-rw-r--r--FS/FS/pkg_svc.pm2
-rw-r--r--FS/FS/svc_acct.pm23
-rw-r--r--FS/FS/svc_acct_sm.pm260
-rwxr-xr-xFS/FS/svc_broadband.pm295
-rw-r--r--FS/FS/svc_domain.pm4
-rw-r--r--FS/MANIFEST10
-rw-r--r--FS/bin/freeside-addoutsourceuser2
-rwxr-xr-xFS/bin/freeside-cc-receipts-report2
-rwxr-xr-xFS/bin/freeside-credit-report2
-rwxr-xr-xFS/bin/freeside-email6
-rwxr-xr-xFS/bin/freeside-expiration-alerter2
-rwxr-xr-xFS/bin/freeside-receivables-report2
-rwxr-xr-xFS/bin/freeside-setup193
-rwxr-xr-xFS/bin/freeside-tax-report2
-rw-r--r--FS/t/svc_acct_sm.t5
34 files changed, 606 insertions, 1232 deletions
diff --git a/FS/FS.pm b/FS/FS.pm
index c22557a2d..963c73548 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -62,6 +62,8 @@ L<FS::domain_record> - DNS zone entries
L<FS::svc_forward> - Mail forwarding class
+L<FS::svc_acct_sm> - (Depreciated) Vitual mail alias class
+
L<FS::svc_www> - Web virtual host class.
L<FS::part_svc> - Service definition class
diff --git a/FS/FS/ClientAPI.pm b/FS/FS/ClientAPI.pm
index 7cbbdbf67..f7b8eb028 100644
--- a/FS/FS/ClientAPI.pm
+++ b/FS/FS/ClientAPI.pm
@@ -1,13 +1,13 @@
package FS::ClientAPI;
use strict;
-use vars qw(%handler $domain);
+use vars qw(%handler);
%handler = ();
#find modules
foreach my $INC ( @INC ) {
- foreach my $file ( glob("$INC/FS/ClientAPI/*.pm") ) {
+ foreach my $file ( glob("$INC/FS/ClientAPI/*") ) {
$file =~ /\/(\w+)\.pm$/ or do {
warn "unrecognized ClientAPI file: $file";
next
diff --git a/FS/FS/ClientAPI/passwd.pm b/FS/FS/ClientAPI/passwd.pm
index 016ebff79..29606227d 100644
--- a/FS/FS/ClientAPI/passwd.pm
+++ b/FS/FS/ClientAPI/passwd.pm
@@ -15,9 +15,8 @@ FS::ClientAPI->register_handlers(
sub passwd {
my $packet = shift;
- my $domain = $FS::ClientAPI::domain || $packet->{'domain'};
- my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } )
- or return { error => "Domain $domain not found" };
+ #my $domain = qsearchs('svc_domain', { 'domain' => $packet->{'domain'} } )
+ # or return { error => "Domain $domain not found" };
my $old_password = $packet->{'old_password'};
my $new_password = $packet->{'new_password'};
@@ -28,11 +27,11 @@ sub passwd {
my $svc_acct =
( length($old_password) < 13
&& qsearchs( 'svc_acct', { 'username' => $packet->{'username'},
- 'domsvc' => $svc_domain->svcnum,
+ #'domsvc' => $svc_domain->svcnum,
'_password' => $old_password } )
)
|| qsearchs( 'svc_acct', { 'username' => $packet->{'username'},
- 'domsvc' => $svc_domain->svcnum,
+ #'domsvc' => $svc_domain->svcnum,
'_password' => $old_password } );
unless ( $svc_acct ) { return { error => 'Incorrect password.' } }
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index e9defdafd..e50cb29b9 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -290,6 +290,13 @@ httemplate/docs/config.html
},
{
+ 'key' => 'cybercash3.2',
+ 'section' => 'billing',
+ 'description' => '<a href="http://www.cybercash.com/cashregister/">CyberCash Cashregister v3.2</a> support. Two lines: the full path and name of your merchant_conf file, and the transaction type (`mauthonly\' or `mauthcapture\').',
+ 'type' => 'textarea',
+ },
+
+ {
'key' => 'cyrus',
'section' => 'deprecated',
'description' => '<b>DEPRECATED</b>, add a <i>cyrus</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to integrate with <a href="http://asg.web.cmu.edu/cyrus/imapd/">Cyrus IMAP Server</a>, three lines: IMAP server, admin username, and admin password. Cyrus::IMAP::Admin should be installed locally and the connection to the server secured.',
@@ -332,6 +339,13 @@ httemplate/docs/config.html
},
{
+ 'key' => 'domain',
+ 'section' => 'deprecated',
+ 'description' => 'Your domain name.',
+ 'type' => 'text',
+ },
+
+ {
'key' => 'editreferrals',
'section' => 'UI',
'description' => 'Enable advertising source modification for existing customers',
diff --git a/FS/FS/InitHandler.pm b/FS/FS/InitHandler.pm
index 5038cf352..87f507c22 100644
--- a/FS/FS/InitHandler.pm
+++ b/FS/FS/InitHandler.pm
@@ -1,9 +1,5 @@
package FS::InitHandler;
-# this leaks memory under graceful restarts and i wouldn't use it on any
-# modern server. useful for very slow machines with memory to spare, just
-# always do a full restart
-
use strict;
use vars qw($DEBUG);
use FS::UID qw(adminsuidsetup);
@@ -52,6 +48,7 @@ sub handler {
use FS::session;
use FS::svc_acct;
use FS::svc_acct_pop;
+ use FS::svc_acct_sm;
use FS::svc_domain;
use FS::svc_forward;
use FS::svc_www;
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index a23f37a62..e6126a13b 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -9,8 +9,8 @@ use Carp qw(carp cluck croak confess);
use File::CounterFile;
use Locale::Country;
use DBI qw(:sql_types);
-use DBIx::DBSchema 0.21;
-use FS::UID qw(dbh getotaker datasrc driver_name);
+use DBIx::DBSchema 0.19;
+use FS::UID qw(dbh checkruid getotaker datasrc driver_name);
use FS::SearchCache;
use FS::Msgcat qw(gettext);
@@ -60,12 +60,14 @@ FS::Record - Database record objects
$hashref = $record->hashref;
$error = $record->insert;
+ #$error = $record->add; #deprecated
$error = $record->delete;
+ #$error = $record->del; #deprecated
$error = $new_record->replace($old_record);
+ #$error = $new_record->rep($old_record); #deprecated
- # external use deprecated - handled by the database (at least for Pg, mysql)
$value = $record->unique('column');
$error = $record->ut_float('column');
@@ -86,7 +88,7 @@ FS::Record - Database record objects
$quoted_value = _quote($value,'table','field');
- #deprecated
+ #depriciated
$fields = hfields('table');
if ( $fields->{Field} ) { # etc.
@@ -165,7 +167,7 @@ sub create {
my $self = {};
bless ($self, $class);
if ( defined $self->table ) {
- cluck "create constructor is deprecated, use new!";
+ cluck "create constructor is depriciated, use new!";
$self->new(@_);
} else {
croak "FS::Record::create called (not from a subclass)!";
@@ -210,25 +212,25 @@ sub qsearch {
my $op = '=';
if ( ref($record->{$_}) ) {
$op = $record->{$_}{'op'} if $record->{$_}{'op'};
- $op = 'LIKE' if $op =~ /^ILIKE$/i && driver_name ne 'Pg';
+ $op = 'LIKE' if $op =~ /^ILIKE$/i && driver_name !~ /^Pg$/i;
$record->{$_} = $record->{$_}{'value'}
}
if ( ! defined( $record->{$_} ) || $record->{$_} eq '' ) {
if ( $op eq '=' ) {
- if ( driver_name eq 'Pg' ) {
+ if ( driver_name =~ /^Pg$/i ) {
qq-( $_ IS NULL OR $_ = '' )-;
} else {
qq-( $_ IS NULL OR $_ = "" )-;
}
} elsif ( $op eq '!=' ) {
- if ( driver_name eq 'Pg' ) {
+ if ( driver_name =~ /^Pg$/i ) {
qq-( $_ IS NOT NULL AND $_ != '' )-;
} else {
qq-( $_ IS NOT NULL AND $_ != "" )-;
}
} else {
- if ( driver_name eq 'Pg' ) {
+ if ( driver_name =~ /^Pg$/i ) {
qq-( $_ $op '' )-;
} else {
qq-( $_ $op "" )-;
@@ -343,7 +345,7 @@ Returns the table name.
=cut
sub table {
-# cluck "warning: FS::Record::table deprecated; supply one in subclass!";
+# cluck "warning: FS::Record::table depriciated; supply one in subclass!";
my $self = shift;
$self -> {'Table'};
}
@@ -470,40 +472,24 @@ sub insert {
return $error if $error;
#single-field unique keys are given a value if false
- #(like MySQL's AUTO_INCREMENT or Pg SERIAL)
+ #(like MySQL's AUTO_INCREMENT)
foreach ( $self->dbdef_table->unique->singles ) {
$self->unique($_) unless $self->getfield($_);
}
-
- #and also the primary key, if the database isn't going to
+ #and also the primary key
my $primary_key = $self->dbdef_table->primary_key;
- my $db_seq = 0;
- if ( $primary_key ) {
- my $col = $self->dbdef_table->column($primary_key);
-
- $db_seq =
- uc($col->type) eq 'SERIAL'
- || ( driver_name eq 'Pg'
- && defined($col->default)
- && $col->default =~ /^nextval\(/i
- )
- || ( driver_name eq 'mysql'
- && defined($col->local)
- && $col->local =~ /AUTO_INCREMENT/i
- );
- $self->unique($primary_key) unless $self->getfield($primary_key) || $db_seq;
- }
+ $self->unique($primary_key)
+ if $primary_key && ! $self->getfield($primary_key);
- my $table = $self->table;
#false laziness w/delete
my @fields =
grep defined($self->getfield($_)) && $self->getfield($_) ne "",
$self->fields
;
- my @values = map { _quote( $self->getfield($_), $table, $_) } @fields;
+ my @values = map { _quote( $self->getfield($_), $self->table, $_) } @fields;
#eslaf
- my $statement = "INSERT INTO $table ( ".
+ my $statement = "INSERT INTO ". $self->table. " ( ".
join( ', ', @fields ).
") VALUES (".
join( ', ', @values ).
@@ -512,6 +498,15 @@ sub insert {
warn "[debug]$me $statement\n" if $DEBUG > 1;
my $sth = dbh->prepare($statement) or return dbh->errstr;
+ my $h_sth;
+ if ( defined $dbdef->table('h_'. $self->table) ) {
+ my $h_statement = $self->_h_statement('insert');
+ warn "[debug]$me $h_statement\n" if $DEBUG > 2;
+ $h_sth = dbh->prepare($h_statement) or return dbh->errstr;
+ } else {
+ $h_sth = '';
+ }
+
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
local $SIG{QUIT} = 'IGNORE';
@@ -520,64 +515,7 @@ sub insert {
local $SIG{PIPE} = 'IGNORE';
$sth->execute or return $sth->errstr;
-
- if ( $db_seq ) { # get inserted id from the database, if applicable
- warn "[debug]$me retreiving sequence from database\n" if $DEBUG;
- my $insertid = '';
- if ( driver_name eq 'Pg' ) {
-
- my $oid = $sth->{'pg_oid_status'};
- my $i_sql = "SELECT $primary_key FROM $table WHERE oid = ?";
- my $i_sth = dbh->prepare($i_sql) or do {
- dbh->rollback if $FS::UID::AutoCommit;
- return dbh->errstr;
- };
- $i_sth->execute($oid) or do {
- dbh->rollback if $FS::UID::AutoCommit;
- return $i_sth->errstr;
- };
- $insertid = $i_sth->fetchrow_arrayref->[0];
-
- } elsif ( driver_name eq 'mysql' ) {
-
- $insertid = dbh->{'mysql_insertid'};
- # work around mysql_insertid being null some of the time, ala RT :/
- unless ( $insertid ) {
- warn "WARNING: DBD::mysql didn't return mysql_insertid; ".
- "using SELECT LAST_INSERT_ID();";
- my $i_sql = "SELECT LAST_INSERT_ID()";
- my $i_sth = dbh->prepare($i_sql) or do {
- dbh->rollback if $FS::UID::AutoCommit;
- return dbh->errstr;
- };
- $i_sth->execute or do {
- dbh->rollback if $FS::UID::AutoCommit;
- return $i_sth->errstr;
- };
- $insertid = $i_sth->fetchrow_arrayref->[0];
- }
-
- } else {
- dbh->rollback if $FS::UID::AutoCommit;
- return "don't know how to retreive inserted ids from ". driver_name.
- ", try using counterfiles (maybe run dbdef-create?)";
- }
- $self->setfield($primary_key, $insertid);
- }
-
- my $h_sth;
- if ( defined $dbdef->table('h_'. $table) ) {
- my $h_statement = $self->_h_statement('insert');
- warn "[debug]$me $h_statement\n" if $DEBUG > 2;
- $h_sth = dbh->prepare($h_statement) or do {
- dbh->rollback if $FS::UID::AutoCommit;
- return dbh->errstr;
- };
- } else {
- $h_sth = '';
- }
$h_sth->execute or return $h_sth->errstr if $h_sth;
-
dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit;
'';
@@ -590,7 +528,7 @@ Depriciated (use insert instead).
=cut
sub add {
- cluck "warning: FS::Record::add deprecated!";
+ cluck "warning: FS::Record::add depriciated!";
insert @_; #call method in this scope
}
@@ -608,7 +546,7 @@ sub delete {
map {
$self->getfield($_) eq ''
#? "( $_ IS NULL OR $_ = \"\" )"
- ? ( driver_name eq 'Pg'
+ ? ( driver_name =~ /^Pg$/i
? "$_ IS NULL"
: "( $_ IS NULL OR $_ = \"\" )"
)
@@ -654,7 +592,7 @@ Depriciated (use delete instead).
=cut
sub del {
- cluck "warning: FS::Record::del deprecated!";
+ cluck "warning: FS::Record::del depriciated!";
&delete(@_); #call method in this scope
}
@@ -694,7 +632,7 @@ sub replace {
map {
$old->getfield($_) eq ''
#? "( $_ IS NULL OR $_ = \"\" )"
- ? ( driver_name eq 'Pg'
+ ? ( driver_name =~ /^Pg$/i
? "$_ IS NULL"
: "( $_ IS NULL OR $_ = \"\" )"
)
@@ -747,7 +685,7 @@ Depriciated (use replace instead).
=cut
sub rep {
- cluck "warning: FS::Record::rep deprecated!";
+ cluck "warning: FS::Record::rep depriciated!";
replace @_; #call method in this scope
}
@@ -780,13 +718,8 @@ sub _h_statement {
=item unique COLUMN
-B<Warning>: External use is B<deprecated>.
-
-Replaces COLUMN in record with a unique number, using counters in the
-filesystem. Used by the B<insert> method on single-field unique columns
-(see L<DBIx::DBSchema::Table>) and also as a fallback for primary keys
-that aren't SERIAL (Pg) or AUTO_INCREMENT (mysql).
-
+Replaces COLUMN in record with a unique number. Called by the B<add> method
+on primary keys and single-field unique columns (see L<DBIx::DBSchema::Table>).
Returns the new value.
=cut
@@ -795,6 +728,8 @@ sub unique {
my($self,$field) = @_;
my($table)=$self->table;
+ #croak("&FS::UID::checkruid failed") unless &checkruid;
+
croak "Unique called on field $field, but it is ",
$self->getfield($field),
", not null!"
@@ -810,8 +745,9 @@ sub unique {
# my($counter) = new File::CounterFile "$user/$table.$field",0;
# endhack
- my $index = $counter->inc;
- $index = $counter->inc while qsearchs($table, { $field=>$index } );
+ my($index)=$counter->inc;
+ $index=$counter->inc
+ while qsearchs($table,{$field=>$index}); #just in case
$index =~ /^(\d*)$/;
$index=$1;
@@ -994,7 +930,7 @@ sub ut_ip {
$self->getfield($field) =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
or return "Illegal (IP address) $field: ". $self->getfield($field);
for ( $1, $2, $3, $4 ) { return "Illegal (IP address) $field" if $_ > 255; }
- $self->setfield($field, "$1.$2.$3.$4");
+ $self->setfield($field, "$1.$2.$3.$3");
'';
}
@@ -1229,14 +1165,14 @@ sub _quote {
=item hfields TABLE
-This is deprecated. Don't use it.
+This is depriciated. Don't use it.
It returns a hash-type list with the fields of this record's table set true.
=cut
sub hfields {
- carp "warning: hfields is deprecated";
+ carp "warning: hfields is depriciated";
my($table)=@_;
my(%hash);
foreach (fields($table)) {
@@ -1272,7 +1208,7 @@ sub DESTROY { return; }
This module should probably be renamed, since much of the functionality is
of general use. It is not completely unlike Adapter::DBI (see below).
-Exported qsearch and qsearchs should be deprecated in favor of method calls
+Exported qsearch and qsearchs should be depriciated in favor of method calls
(against an FS::Record object like the old search and searchs that qsearch
and qsearchs were on top of.)
@@ -1280,7 +1216,7 @@ The whole fields / hfields mess should be removed.
The various WHERE clauses should be subroutined.
-table string should be deprecated in favor of DBIx::DBSchema::Table.
+table string should be depriciated in favor of DBIx::DBSchema::Table.
No doubt we could benefit from a Tied hash. Documenting how exists / defined
true maps to the database (and WHERE clauses) would also help.
diff --git a/FS/FS/UID.pm b/FS/FS/UID.pm
index 6962b2768..8934d49fc 100644
--- a/FS/FS/UID.pm
+++ b/FS/FS/UID.pm
@@ -171,7 +171,9 @@ Returns the current Freeside user.
=cut
sub getotaker {
- $user;
+ #$user;
+ #stupid kludge until schema otaker fields are not 8 chars
+ substr($user,0,8);
}
=item cgisetotaker
@@ -256,7 +258,7 @@ coderef into the hash %FS::UID::callback :
=head1 VERSION
-$Id: UID.pm,v 1.20 2002-09-20 10:16:28 ivan Exp $
+$Id: UID.pm,v 1.19 2002-08-29 06:02:52 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/ac.pm b/FS/FS/ac.pm
deleted file mode 100644
index 5a2b36079..000000000
--- a/FS/FS/ac.pm
+++ /dev/null
@@ -1,148 +0,0 @@
-package FS::ac;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs qsearch );
-use FS::ac_type;
-use FS::ac_block;
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::ac - Object methods for ac records
-
-=head1 SYNOPSIS
-
- use FS::ac;
-
- $record = new FS::ac \%hash;
- $record = new FS::ac { 'column' => 'value' };
-
- $error = $record->insert;
-
- $error = $new_record->replace($old_record);
-
- $error = $record->delete;
-
- $error = $record->check;
-
-=head1 DESCRIPTION
-
-An FS::ac record describes a broadband Access Concentrator, such as a DSLAM
-or a wireless access point. FS::ac inherits from FS::Record. The following
-fields are currently supported:
-
-narf
-
-=over 4
-
-=item acnum - primary key
-
-=item actypenum - AC type, see L<FS::ac_type>
-
-=item acname - descriptive name for the AC
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record. To add the record to the database, see L<"insert">.
-
-=cut
-
-sub table { 'ac'; }
-
-=item insert
-
-Adds this record to the database. If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database. If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database. If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record. If there is an error,
-returns the error, otherwise returns false. Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
- my $self = shift;
-
- my $error =
- $self->ut_numbern('acnum')
- || $self->ut_number('actypenum')
- || $self->ut_text('acname');
- return $error if $error;
-
- return "Unknown actypenum"
- unless $self->ac_type;
- '';
-}
-
-=item ac_type
-
-Returns the L<FS::ac_type> object corresponding to this object.
-
-=cut
-
-sub ac_type {
- my $self = shift;
- return qsearchs('ac_type', { actypenum => $self->actypenum });
-}
-
-=item ac_block
-
-Returns a list of L<FS::ac_block> objects (address blocks) associated
-with this object.
-
-=cut
-
-sub ac_block {
- my $self = shift;
- return qsearch('ac_block', { acnum => $self->acnum });
-}
-
-=item ac_field
-
-Returns a hash of L<FS::ac_field> objects assigned to this object.
-
-=cut
-
-sub ac_field {
- my $self = shift;
-
- return qsearch('ac_field', { acnum => $self->acnum });
-}
-
-=back
-
-=head1 VERSION
-
-$Id:
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<FS::svc_broadband>, L<FS::ac>, L<FS::ac_block>, L<FS::ac_field>, schema.html
-from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/ac_block.pm b/FS/FS/ac_block.pm
deleted file mode 100755
index 09de6a4d8..000000000
--- a/FS/FS/ac_block.pm
+++ /dev/null
@@ -1,148 +0,0 @@
-package FS::ac_block;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs qsearch );
-use FS::ac_type;
-use FS::ac;
-use FS::svc_broadband;
-use NetAddr::IP;
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::ac - Object methods for ac records
-
-=head1 SYNOPSIS
-
- use FS::ac_block;
-
- $record = new FS::ac_block \%hash;
- $record = new FS::ac_block { 'column' => 'value' };
-
- $error = $record->insert;
-
- $error = $new_record->replace($old_record);
-
- $error = $record->delete;
-
- $error = $record->check;
-
-=head1 DESCRIPTION
-
-An FS::ac_block record describes an address block assigned for broadband
-access. FS::ac_block inherits from FS::Record. The following fields are
-currently supported:
-
-=over 4
-
-=item acnum - the access concentrator (see L<FS::ac_type>) to which this
-block is assigned.
-
-=item ip_gateway - the gateway address used by customers within this block.
-This functions as the primary key.
-
-=item ip_netmask - the netmask of the block, expressed as an integer.
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record. To add the record to the database, see L<"insert">.
-
-=cut
-
-sub table { 'ac_block'; }
-
-=item insert
-
-Adds this record to the database. If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database. If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database. If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record. If there is an error,
-returns the error, otherwise returns false. Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
- my $self = shift;
-
- my $error =
- $self->ut_number('acnum')
- || $self->ut_ip('ip_gateway')
- || $self->ut_number('ip_netmask')
- ;
- return $error if $error;
-
- return "Unknown acnum"
- unless $self->ac;
-
- my $self_addr = new NetAddr::IP ($self->ip_gateway, $self->ip_netmask);
- return "Cannot parse address: ". $self->ip_gateway . '/' . $self->ip_netmask
- unless $self_addr;
-
- my @block = grep {
- my $block_addr = new NetAddr::IP ($_->ip_gateway, $_->ip_netmask);
- if($block_addr->contains($self_addr)
- or $self_addr->contains($block_addr)) { $_; };
- } qsearch( 'ac_block', {});
-
- foreach(@block) {
- return "Block intersects existing block ".$_->ip_gateway."/".$_->ip_netmask;
- }
-
- '';
-}
-
-
-=item ac
-
-Returns the L<FS::ac> object corresponding to this object.
-
-=cut
-
-sub ac {
- my $self = shift;
- return qsearchs('ac', { acnum => $self->acnum });
-}
-
-=item svc_broadband
-
-Returns a list of L<FS::svc_broadband> objects associated
-with this object.
-
-=cut
-
-#sub svc_broadband {
-# my $self = shift;
-# my @svc = qsearch('svc_broadband', { actypenum => $self->ac->ac_type->actypenum });
-# return grep {
-# my $svc_addr = new NetAddr::IP($_->ip_addr, $_->ip_netmask);
-# $self_addr->contains($svc_addr);
-# } @svc;
-#}
-
-=back
-
-=cut
-
-1;
-
diff --git a/FS/FS/ac_field.pm b/FS/FS/ac_field.pm
deleted file mode 100755
index f6011192f..000000000
--- a/FS/FS/ac_field.pm
+++ /dev/null
@@ -1,138 +0,0 @@
-package FS::ac_field;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-use FS::part_ac_field;
-use FS::ac;
-
-use UNIVERSAL qw( can );
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::ac_field - Object methods for ac_field records
-
-=head1 SYNOPSIS
-
- use FS::ac_field;
-
- $record = new FS::ac_field \%hash;
- $record = new FS::ac_field { 'column' => 'value' };
-
- $error = $record->insert;
-
- $error = $new_record->replace($old_record);
-
- $error = $record->delete;
-
- $error = $record->check;
-
-=head1 DESCRIPTION
-
-L<FS::ac_field> contains values of fields defined by L<FS::part_ac_field>
-for an L<FS::ac>. Values must be of the data type defined by ut_type in
-L<FS::part_ac_field>.
-Supported fields as follows:
-
-=over 4
-
-=item acfieldpart - Type of ac_field as defined by L<FS::part_ac_field>
-
-=item acnum - The L<FS::ac> to which this value belongs.
-
-=item value - The contents of the field.
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record. To add the record to the database, see L<"insert">.
-
-=cut
-
-sub table { 'ac_field'; }
-
-=item insert
-
-Adds this record to the database. If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database. If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database. If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record. If there is an error,
-returns the error, otherwise returns false. Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
- my $self = shift;
-
- return "acnum must be defined" unless $self->acnum;
- return "acfieldpart must be defined" unless $self->acfieldpart;
-
- my $ut_func = $self->can("ut_" . $self->part_ac_field->ut_type);
- my $error = $self->$ut_func('value');
-
- return $error if $error;
-
- ''; #no error
-}
-
-=item part_ac_field
-
-Returns a reference to the L<FS:part_ac_field> that defines this L<FS::ac_field>
-
-=cut
-
-sub part_ac_field {
- my $self = shift;
-
- return qsearchs('part_ac_field', { acfieldpart => $self->acfieldpart });
-}
-
-=item ac
-
-Returns a reference to the L<FS::ac> to which this L<FS::ac_field> belongs.
-
-=cut
-
-sub ac {
- my $self = shift;
-
- return qsearchs('ac', { acnum => $self->acnum });
-}
-
-=back
-
-=head1 VERSION
-
-$Id:
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<FS::svc_broadband>, L<FS::ac>, L<FS::ac_block>, L<FS::ac_field>, schema.html
-from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/ac_type.pm b/FS/FS/ac_type.pm
deleted file mode 100755
index e83c5c5f0..000000000
--- a/FS/FS/ac_type.pm
+++ /dev/null
@@ -1,128 +0,0 @@
-package FS::ac_type;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-use FS::ac;
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::ac_type - Object methods for ac_type records
-
-=head1 SYNOPSIS
-
- use FS::ac_type;
-
- $record = new FS::ac_type \%hash;
- $record = new FS::ac_type { 'column' => 'value' };
-
- $error = $record->insert;
-
- $error = $new_record->replace($old_record);
-
- $error = $record->delete;
-
- $error = $record->check;
-
-=head1 DESCRIPTION
-
-L<FS::ac_type> refers to a type of access concentrator. L<FS::svc_broadband>
-records refer to a specific L<FS::ac_type> limiting the choice of access
-concentrator to one of the chosen type. This should be set as a fixed
-default in part_svc to prevent provisioning the wrong type of service for
-a given package or service type. Supported fields as follows:
-
-=over 4
-
-=item actypenum - Primary key. see L<FS::ac>
-
-=item actypename - Text identifier for access concentrator type.
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record. To add the record to the database, see L<"insert">.
-
-=cut
-
-sub table { 'ac_type'; }
-
-=item insert
-
-Adds this record to the database. If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database. If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database. If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record. If there is an error,
-returns the error, otherwise returns false. Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
- my $self = shift;
-
- # What do we check?
-
- ''; #no error
-}
-
-=item ac
-
-Returns a list of all L<FS::ac> records of this type.
-
-=cut
-
-sub ac {
- my $self = shift;
-
- return qsearch('ac', { actypenum => $self->actypenum });
-}
-
-=item part_ac_field
-
-Returns a list of all L<FS::part_ac_field> records of this type.
-
-=cut
-
-sub part_ac_field {
- my $self = shift;
-
- return qsearch('part_ac_field', { actypenum => $self->actypenum });
-}
-
-=back
-
-=head1 VERSION
-
-$Id:
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<FS::svc_broadband>, L<FS::ac>, L<FS::ac_block>, L<FS::ac_field>, schema.html
-from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm
index 258b32e15..ca0caf2e6 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -35,7 +35,28 @@ $FS::UID::callback{'FS::cust_bill'} = sub {
$invoice_from = $conf->config('invoice_from');
$smtpmachine = $conf->config('smtpmachine');
- if ( $conf->exists('business-onlinepayment') ) {
+ if ( $conf->exists('cybercash3.2') ) {
+ require CCMckLib3_2;
+ #qw($MCKversion %Config InitConfig CCError CCDebug CCDebug2);
+ require CCMckDirectLib3_2;
+ #qw(SendCC2_1Server);
+ require CCMckErrno3_2;
+ #qw(MCKGetErrorMessage $E_NoErr);
+ import CCMckErrno3_2 qw($E_NoErr);
+
+ my $merchant_conf;
+ ($merchant_conf,$xaction)= $conf->config('cybercash3.2');
+ my $status = &CCMckLib3_2::InitConfig($merchant_conf);
+ if ( $status != $E_NoErr ) {
+ warn "CCMckLib3_2::InitConfig error:\n";
+ foreach my $key (keys %CCMckLib3_2::Config) {
+ warn " $key => $CCMckLib3_2::Config{$key}\n"
+ }
+ my($errmsg) = &CCMckErrno3_2::MCKGetErrorMessage($status);
+ die "CCMckLib3_2::InitConfig fatal error: $errmsg\n";
+ }
+ $processor='cybercash3.2';
+ } elsif ( $conf->exists('business-onlinepayment') ) {
( $bop_processor,
$bop_login,
$bop_password,
@@ -779,6 +800,84 @@ sub realtime_card {
}
+=item realtime_card_cybercash
+
+Attempts to pay this invoice with the CyberCash CashRegister realtime gateway.
+
+=cut
+
+sub realtime_card_cybercash {
+ my $self = shift;
+ my $cust_main = $self->cust_main;
+ my $amount = $self->owed;
+
+ return "CyberCash CashRegister real-time card processing not enabled!"
+ unless $processor eq 'cybercash3.2';
+
+ my $address = $cust_main->address1;
+ $address .= ", ". $cust_main->address2 if $cust_main->address2;
+
+ #fix exp. date
+ #$cust_main->paydate =~ /^(\d+)\/\d*(\d{2})$/;
+ $cust_main->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
+ my $exp = "$2/$1";
+
+ #
+
+ my $paybatch = $self->invnum.
+ '-' . time2str("%y%m%d%H%M%S", time);
+
+ my $payname = $cust_main->payname ||
+ $cust_main->getfield('first').' '.$cust_main->getfield('last');
+
+ my $country = $cust_main->country eq 'US' ? 'USA' : $cust_main->country;
+
+ my @full_xaction = ( $xaction,
+ 'Order-ID' => $paybatch,
+ 'Amount' => "usd $amount",
+ 'Card-Number' => $cust_main->getfield('payinfo'),
+ 'Card-Name' => $payname,
+ 'Card-Address' => $address,
+ 'Card-City' => $cust_main->getfield('city'),
+ 'Card-State' => $cust_main->getfield('state'),
+ 'Card-Zip' => $cust_main->getfield('zip'),
+ 'Card-Country' => $country,
+ 'Card-Exp' => $exp,
+ );
+
+ my %result;
+ %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
+
+ if ( $result{'MStatus'} eq 'success' ) { #cybercash smps v.2 or 3
+ my $cust_pay = new FS::cust_pay ( {
+ 'invnum' => $self->invnum,
+ 'paid' => $amount,
+ '_date' => '',
+ 'payby' => 'CARD',
+ 'payinfo' => $cust_main->payinfo,
+ 'paybatch' => "$processor:$paybatch",
+ } );
+ my $error = $cust_pay->insert;
+ if ( $error ) {
+ # gah, even with transactions.
+ my $e = 'WARNING: Card debited but database not updated - '.
+ 'error applying payment, invnum #' . $self->invnum.
+ " (CyberCash Order-ID $paybatch): $error";
+ warn $e;
+ return $e;
+ } else {
+ return '';
+ }
+# } elsif ( $result{'Mstatus'} ne 'failure-bad-money'
+# || $options{'report_badcard'}
+# ) {
+ } else {
+ return 'Cybercash error, invnum #' .
+ $self->invnum. ':'. $result{'MErrMsg'};
+ }
+
+}
+
=item batch_card
Adds a payment for this invoice to the pending credit card batch (see
@@ -1031,7 +1130,7 @@ sub print_text {
=head1 VERSION
-$Id: cust_bill.pm,v 1.45 2002-09-17 10:21:47 ivan Exp $
+$Id: cust_bill.pm,v 1.41.2.3 2002-09-17 00:40:05 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/cust_main_invoice.pm b/FS/FS/cust_main_invoice.pm
index bcb1437af..a5533a088 100644
--- a/FS/FS/cust_main_invoice.pm
+++ b/FS/FS/cust_main_invoice.pm
@@ -134,6 +134,13 @@ sub checkdest {
unless qsearchs( 'svc_acct', { 'svcnum' => $self->dest } );
} elsif ( $self->dest =~ /^([\w\.\-\&\+]+)\@(([\w\.\-]+\.)+\w+)$/ ) {
my($user, $domain) = ($1, $2);
+# if ( $domain eq $mydomain ) {
+# my $svc_acct = qsearchs( 'svc_acct', { 'username' => $user } );
+# return "Unknown local account: $user\@$domain (specified literally)"
+# unless $svc_acct;
+# $svc_acct->svcnum =~ /^(\d+)$/ or die "Non-numeric svcnum?!";
+# $self->dest($1);
+# }
$self->dest("$1\@$2");
} else {
return gettext("illegal_email_invoice_address");
@@ -163,7 +170,7 @@ sub address {
=head1 VERSION
-$Id: cust_main_invoice.pm,v 1.13 2002-09-18 22:50:44 ivan Exp $
+$Id: cust_main_invoice.pm,v 1.12 2002-04-12 13:22:02 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 0c71435e1..12508e1aa 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -14,6 +14,7 @@ use FS::pkg_svc;
# setup }
# because they load configuraion by setting FS::UID::callback (see TODO)
use FS::svc_acct;
+use FS::svc_acct_sm;
use FS::svc_domain;
use FS::svc_www;
use FS::svc_forward;
@@ -678,7 +679,7 @@ sub order {
=head1 VERSION
-$Id: cust_pkg.pm,v 1.24 2002-09-17 09:19:06 ivan Exp $
+$Id: cust_pkg.pm,v 1.23 2002-08-26 20:40:55 ivan Exp $
=head1 BUGS
@@ -689,12 +690,11 @@ In sub order, the @pkgparts array (passed by reference) is clobbered.
Also in sub order, no money is adjusted. Once FS::part_pkg defines a standard
method to pass dates to the recur_prog expression, it should do so.
-FS::svc_acct, FS::svc_domain, FS::svc_www and FS::svc_forward are loaded via
-'use' at compile time, rather than via 'require' in sub
-{ setup, suspend, unsuspend, cancel } because they use %FS::UID::callback to
-load configuration values. Probably need a subroutine which decides what to
-do based on whether or not we've fetched the user yet, rather than a hash.
-See FS::UID and the TODO.
+FS::svc_acct, FS::svc_acct_sm, and FS::svc_domain are loaded via 'use' at
+compile time, rather than via 'require' in sub { setup, suspend, unsuspend,
+cancel } because they use %FS::UID::callback to load configuration values.
+Probably need a subroutine which decides what to do based on whether or not
+we've fetched the user yet, rather than a hash. See FS::UID and the TODO.
Now that things are transactional should the check in the insert method be
moved to check ?
diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm
index 9d510b38a..c7cc4b322 100644
--- a/FS/FS/cust_svc.pm
+++ b/FS/FS/cust_svc.pm
@@ -9,6 +9,7 @@ use FS::part_pkg;
use FS::part_svc;
use FS::pkg_svc;
use FS::svc_acct;
+use FS::svc_acct_sm;
use FS::svc_domain;
use FS::svc_forward;
use FS::domain_record;
@@ -275,6 +276,11 @@ sub label {
my $tag;
if ( $svcdb eq 'svc_acct' ) {
$tag = $svc_x->email;
+ } elsif ( $svcdb eq 'svc_acct_sm' ) {
+ my $domuser = $svc_x->domuser eq '*' ? '(anything)' : $svc_x->domuser;
+ my $svc_domain = qsearchs ( 'svc_domain', { 'svcnum' => $svc_x->domsvc } );
+ my $domain = $svc_domain->domain;
+ $tag = "$domuser\@$domain";
} elsif ( $svcdb eq 'svc_forward' ) {
my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $svc_x->srcsvc } );
$tag = $svc_acct->email. '->';
@@ -289,8 +295,6 @@ sub label {
} elsif ( $svcdb eq 'svc_www' ) {
my $domain = qsearchs( 'domain_record', { 'recnum' => $svc_x->recnum } );
$tag = $domain->reczone;
- } elsif ( $svcdb eq 'svc_broadband' ) {
- $tag = $svc_x->ip_addr . '/' . $svc_x->ip_netmask;
} else {
cluck "warning: asked for label of unsupported svcdb; using svcnum";
$tag = $svc_x->getfield('svcnum');
@@ -340,7 +344,7 @@ sub seconds_since {
=head1 VERSION
-$Id: cust_svc.pm,v 1.17 2002-09-18 22:39:01 ivan Exp $
+$Id: cust_svc.pm,v 1.15 2002-05-22 12:17:06 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/part_ac_field.pm b/FS/FS/part_ac_field.pm
deleted file mode 100755
index dcb445253..000000000
--- a/FS/FS/part_ac_field.pm
+++ /dev/null
@@ -1,102 +0,0 @@
-package FS::part_ac_field;
-
-use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs );
-use FS::ac_field;
-use FS::ac;
-
-
-@ISA = qw( FS::Record );
-
-=head1 NAME
-
-FS::part_ac_field - Object methods for part_ac_field records
-
-=head1 SYNOPSIS
-
- use FS::part_ac_field;
-
- $record = new FS::part_ac_field \%hash;
- $record = new FS::part_ac_field { 'column' => 'value' };
-
- $error = $record->insert;
-
- $error = $new_record->replace($old_record);
-
- $error = $record->delete;
-
- $error = $record->check;
-
-=head1 DESCRIPTION
-
-
-=over 4
-
-=item blank
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Create a new record. To add the record to the database, see L<"insert">.
-
-=cut
-
-sub table { 'part_ac_field'; }
-
-=item insert
-
-Adds this record to the database. If there is an error, returns the error,
-otherwise returns false.
-
-=item delete
-
-Deletes this record from the database. If there is an error, returns the
-error, otherwise returns false.
-
-=item replace OLD_RECORD
-
-Replaces OLD_RECORD with this one in the database. If there is an error,
-returns the error, otherwise returns false.
-
-=item check
-
-Checks all fields to make sure this is a valid record. If there is an error,
-returns the error, otherwise returns false. Called by the insert and replace
-methods.
-
-=cut
-
-sub check {
- my $self = shift;
- my $error = '';
-
- $self->name =~ /^([a-z0-9_\-\.]{1,15})$/i
- or return "Invalid field name for part_ac_field";
-
- ''; #no error
-}
-
-
-=back
-
-=head1 VERSION
-
-$Id:
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<FS::svc_broadband>, L<FS::ac>, L<FS::ac_block>, L<FS::ac_field>, schema.html
-from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm
index 1b402e014..bc6a4d735 100644
--- a/FS/FS/part_export.pm
+++ b/FS/FS/part_export.pm
@@ -274,6 +274,8 @@ sub check {
;
return $error if $error;
+ warn $self->machine. "!!!\n";
+
$self->machine =~ /^([\w\-\.]*)$/
or return "Illegal machine: ". $self->machine;
$self->machine($1);
@@ -817,6 +819,8 @@ tie my %sqlmail_options, 'Tie::IxHash',
},
+ 'svc_acct_sm' => {},
+
'svc_forward' => {
'sqlmail' => {
'desc' => 'Real-time export to SQL-backed mail server',
@@ -835,9 +839,6 @@ tie my %sqlmail_options, 'Tie::IxHash',
},
- 'svc_broadband' => {
- },
-
);
=back
diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm
index e914636e4..9c33e9a3b 100644
--- a/FS/FS/part_pkg.pm
+++ b/FS/FS/part_pkg.pm
@@ -297,7 +297,7 @@ sub payby {
=head1 VERSION
-$Id: part_pkg.pm,v 1.16 2002-06-10 01:39:50 khoff Exp $
+$Id: part_pkg.pm,v 1.14 2002-05-09 12:38:39 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm
index 7c6acdbcd..959a3f887 100644
--- a/FS/FS/part_svc.pm
+++ b/FS/FS/part_svc.pm
@@ -254,6 +254,31 @@ sub check {
my @fields = eval { fields( $recref->{svcdb} ) }; #might die
return "Unknown svcdb!" unless @fields;
+##REPLACED BY part_svc_column
+# my $svcdb;
+# foreach $svcdb ( qw(
+# svc_acct svc_acct_sm svc_domain
+# ) ) {
+# my @rows = map { /^${svcdb}__(.*)$/; $1 }
+# grep ! /_flag$/,
+# grep /^${svcdb}__/,
+# fields('part_svc');
+# foreach my $row (@rows) {
+# unless ( $svcdb eq $recref->{svcdb} ) {
+# $recref->{$svcdb.'__'.$row}='';
+# $recref->{$svcdb.'__'.$row.'_flag'}='';
+# next;
+# }
+# $recref->{$svcdb.'__'.$row.'_flag'} =~ /^([DF]?)$/
+# or return "Illegal flag for $svcdb $row";
+# $recref->{$svcdb.'__'.$row.'_flag'} = $1;
+#
+# my $error = $self->ut_anything($svcdb.'__'.$row);
+# return $error if $error;
+#
+# }
+# }
+
''; #no error
}
@@ -300,7 +325,7 @@ sub part_export {
=head1 VERSION
-$Id: part_svc.pm,v 1.14 2002-09-17 09:19:06 ivan Exp $
+$Id: part_svc.pm,v 1.13 2002-04-11 22:05:31 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/pkg_svc.pm b/FS/FS/pkg_svc.pm
index 3c544ffd8..1812dbf29 100644
--- a/FS/FS/pkg_svc.pm
+++ b/FS/FS/pkg_svc.pm
@@ -137,7 +137,7 @@ sub part_svc {
=head1 VERSION
-$Id: pkg_svc.pm,v 1.3 2002-06-10 01:39:50 khoff Exp $
+$Id: pkg_svc.pm,v 1.1 1999-08-04 09:03:53 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm
index 991bbef48..028df6fb5 100644
--- a/FS/FS/svc_acct.pm
+++ b/FS/FS/svc_acct.pm
@@ -7,6 +7,7 @@ use vars qw( @ISA $noexport_hack $conf
$username_ampersand $username_letter $username_letterfirst
$username_noperiod $username_nounderscore $username_nodash
$username_uppercase
+ $mydomain
$welcome_template $welcome_from $welcome_subject $welcome_mimetype
$smtpmachine
$dirhash
@@ -17,9 +18,11 @@ use FS::UID qw( datasrc );
use FS::Conf;
use FS::Record qw( qsearch qsearchs fields dbh );
use FS::svc_Common;
+use Net::SSH;
use FS::cust_svc;
use FS::part_svc;
use FS::svc_acct_pop;
+use FS::svc_acct_sm;
use FS::cust_main_invoice;
use FS::svc_domain;
use FS::raddb;
@@ -47,6 +50,7 @@ $FS::UID::callback{'FS::svc_acct'} = sub {
$username_nodash = $conf->exists('username-nodash');
$username_uppercase = $conf->exists('username-uppercase');
$username_ampersand = $conf->exists('username-ampersand');
+ $mydomain = $conf->config('domain');
$dirhash = $conf->config('dirhash') || 0;
if ( $conf->exists('welcome_email') ) {
$welcome_template = new Text::Template (
@@ -404,6 +408,11 @@ The corresponding FS::cust_svc record will be deleted as well.
sub delete {
my $self = shift;
+ if ( defined( $FS::Record::dbdef->table('svc_acct_sm') ) ) {
+ return "Can't delete an account which has (svc_acct_sm) mail aliases!"
+ if $self->uid && qsearch( 'svc_acct_sm', { 'domuid' => $self->uid } );
+ }
+
return "Can't delete an account which is a (svc_forward) source!"
if qsearch( 'svc_forward', { 'srcsvc' => $self->svcnum } );
@@ -871,10 +880,14 @@ Returns the domain associated with this account.
sub domain {
my $self = shift;
- die "svc_acct.domsvc is null for svcnum ". $self->svcnum unless $self->domsvc;
- my $svc_domain = $self->svc_domain
- or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
- $svc_domain->domain;
+ if ( $self->domsvc ) {
+ #$self->svc_domain->domain;
+ my $svc_domain = $self->svc_domain
+ or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
+ $svc_domain->domain;
+ } else {
+ $mydomain or die "svc_acct.domsvc is null and no legacy domain config file";
+ }
}
=item svc_domain
@@ -1133,7 +1146,7 @@ probably live somewhere else...
L<FS::svc_Common>, edit/part_svc.cgi from an installed web interface,
export.html from the base documentation, L<FS::Record>, L<FS::Conf>,
L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, L<FS::queue>,
-L<freeside-queued>), L<FS::svc_acct_pop>,
+L<freeside-queued>), L<Net::SSH>, L<ssh>, L<FS::svc_acct_pop>,
schema.html from the base documentation.
=cut
diff --git a/FS/FS/svc_acct_sm.pm b/FS/FS/svc_acct_sm.pm
new file mode 100644
index 000000000..c92f1421f
--- /dev/null
+++ b/FS/FS/svc_acct_sm.pm
@@ -0,0 +1,260 @@
+package FS::svc_acct_sm;
+
+use strict;
+use vars qw( @ISA $nossh_hack $conf $shellmachine @qmailmachines );
+use FS::Record qw( fields qsearch qsearchs );
+use FS::svc_Common;
+use FS::cust_svc;
+use Net::SSH qw(ssh);
+use FS::Conf;
+use FS::svc_acct;
+use FS::svc_domain;
+
+@ISA = qw( FS::svc_Common );
+
+#ask FS::UID to run this stuff for us later
+#$FS::UID::callback{'FS::svc_acct_sm'} = sub {
+# $conf = new FS::Conf;
+# $shellmachine = $conf->exists('qmailmachines')
+# ? $conf->config('shellmachine')
+# : '';
+#};
+
+=head1 NAME
+
+FS::svc_acct_sm - Object methods for svc_acct_sm records
+
+=head1 SYNOPSIS
+
+ use FS::svc_acct_sm;
+
+ $record = new FS::svc_acct_sm \%hash;
+ $record = new FS::svc_acct_sm { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+ $error = $record->suspend;
+
+ $error = $record->unsuspend;
+
+ $error = $record->cancel;
+
+=head1 WARNING
+
+FS::svc_acct_sm is B<depreciated>. This class is only included for migration
+purposes. See L<FS::svc_forward>.
+
+=head1 DESCRIPTION
+
+An FS::svc_acct_sm object represents a virtual mail alias. FS::svc_acct_sm
+inherits from FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item svcnum - primary key (assigned automatcially for new accounts)
+
+=item domsvc - svcnum of the virtual domain (see L<FS::svc_domain>)
+
+=item domuid - uid of the target account (see L<FS::svc_acct>)
+
+=item domuser - virtual username
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new virtual mail alias. To add the virtual mail alias to the
+database, see L<"insert">.
+
+=cut
+
+sub table { 'svc_acct_sm'; }
+
+=item insert
+
+Adds this virtual mail alias to the database. If there is an error, returns
+the error, otherwise returns false.
+
+The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be
+defined. An FS::cust_svc record will be created and inserted.
+
+ #If the configuration values (see L<FS::Conf>) shellmachine and qmailmachines
+ #exist, and domuser is `*' (meaning a catch-all mailbox), the command:
+ #
+ # [ -e $dir/.qmail-$qdomain-default ] || {
+ # touch $dir/.qmail-$qdomain-default;
+ # chown $uid:$gid $dir/.qmail-$qdomain-default;
+ # }
+ #
+ #is executed on shellmachine via ssh (see L<dot-qmail/"EXTENSION ADDRESSES">).
+ #This behaviour can be surpressed by setting $FS::svc_acct_sm::nossh_hack true.
+
+=cut
+
+sub insert {
+ my $self = shift;
+ my $error;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ $error=$self->check;
+ return $error if $error;
+
+ return "Domain username (domuser) in use for this domain (domsvc)"
+ if qsearchs('svc_acct_sm',{ 'domuser'=> $self->domuser,
+ 'domsvc' => $self->domsvc,
+ } );
+
+ return "First domain username (domuser) for domain (domsvc) must be " .
+ qq='*' (catch-all)!=
+ if $self->domuser ne '*'
+ && ! qsearch('svc_acct_sm',{ 'domsvc' => $self->domsvc } )
+ && ! $conf->exists('maildisablecatchall');
+
+ $error = $self->SUPER::insert;
+ return $error if $error;
+
+ #my $svc_domain = qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } );
+ #my $svc_acct = qsearchs( 'svc_acct', { 'uid' => $self->domuid } );
+ #my ( $uid, $gid, $dir, $domain ) = (
+ # $svc_acct->uid,
+ # $svc_acct->gid,
+ # $svc_acct->dir,
+ # $svc_domain->domain,
+ #);
+ #my $qdomain = $domain;
+ #$qdomain =~ s/\./:/g; #see manpage for 'dot-qmail': EXTENSION ADDRESSES
+ #ssh("root\@$shellmachine","[ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }")
+ # if ( ! $nossh_hack && $shellmachine && $dir && $self->domuser eq '*' );
+
+ ''; #no error
+
+}
+
+=item delete
+
+Deletes this virtual mail alias from the database. If there is an error,
+returns the error, otherwise returns false.
+
+The corresponding FS::cust_svc record will be deleted as well.
+
+=item replace OLD_RECORD
+
+Replaces OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+sub replace {
+ my ( $new, $old ) = ( shift, shift );
+ my $error;
+
+ return "Domain username (domuser) in use for this domain (domsvc)"
+ if ( $old->domuser ne $new->domuser
+ || $old->domsvc != $new->domsvc
+ ) && qsearchs('svc_acct_sm',{
+ 'domuser'=> $new->domuser,
+ 'domsvc' => $new->domsvc,
+ } )
+ ;
+
+ $new->SUPER::replace($old);
+
+}
+
+=item suspend
+
+Just returns false (no error) for now.
+
+Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
+
+=item unsuspend
+
+Just returns false (no error) for now.
+
+Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
+
+=item cancel
+
+Just returns false (no error) for now.
+
+Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
+
+=item check
+
+Checks all fields to make sure this is a valid virtual mail alias. If there is
+an error, returns the error, otherwise returns false. Called by the insert and
+replace methods.
+
+Sets any fixed values; see L<FS::part_svc>.
+
+=cut
+
+sub check {
+ my $self = shift;
+ my $error;
+
+ my $x = $self->setfixed;
+ return $x unless ref($x);
+ #my $part_svc = $x;
+
+ my($recref) = $self->hashref;
+
+ $recref->{domuser} =~ /^(\*|[a-z0-9_\-]{2,32})$/
+ or return "Illegal domain username (domuser)";
+ $recref->{domuser} = $1;
+
+ $recref->{domsvc} =~ /^(\d+)$/ or return "Illegal domsvc";
+ $recref->{domsvc} = $1;
+ my($svc_domain);
+ return "Unknown domsvc" unless
+ $svc_domain=qsearchs('svc_domain',{'svcnum'=> $recref->{domsvc} } );
+
+ $recref->{domuid} =~ /^(\d+)$/ or return "Illegal uid";
+ $recref->{domuid} = $1;
+ my($svc_acct);
+ return "Unknown uid" unless
+ $svc_acct=qsearchs('svc_acct',{'uid'=> $recref->{domuid} } );
+
+ ''; #no error
+}
+
+=back
+
+=head1 VERSION
+
+$Id: svc_acct_sm.pm,v 1.5 2001-09-06 20:41:59 ivan Exp $
+
+=head1 BUGS
+
+The remote commands should be configurable.
+
+The $recref stuff in sub check should be cleaned up.
+
+=head1 SEE ALSO
+
+L<FS::svc_forward>
+
+L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>,
+L<FS::svc_acct>, L<FS::svc_domain>, L<Net::SSH>, L<ssh>, L<dot-qmail>,
+schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm
deleted file mode 100755
index ab92fb3d7..000000000
--- a/FS/FS/svc_broadband.pm
+++ /dev/null
@@ -1,295 +0,0 @@
-package FS::svc_broadband;
-
-use strict;
-use vars qw(@ISA $conf);
-#use FS::Record qw( qsearch qsearchs );
-use FS::Record qw( qsearchs qsearch dbh );
-use FS::svc_Common;
-use FS::cust_svc;
-use NetAddr::IP;
-
-@ISA = qw( FS::svc_Common );
-
-$FS::UID::callback{'FS::svc_broadband'} = sub {
- $conf = new FS::Conf;
-};
-
-=head1 NAME
-
-FS::svc_broadband - Object methods for svc_broadband records
-
-=head1 SYNOPSIS
-
- use FS::svc_broadband;
-
- $record = new FS::svc_broadband \%hash;
- $record = new FS::svc_broadband { 'column' => 'value' };
-
- $error = $record->insert;
-
- $error = $new_record->replace($old_record);
-
- $error = $record->delete;
-
- $error = $record->check;
-
- $error = $record->suspend;
-
- $error = $record->unsuspend;
-
- $error = $record->cancel;
-
-=head1 DESCRIPTION
-
-An FS::svc_broadband object represents a 'broadband' Internet connection, such
-as a DSL, cable modem, or fixed wireless link. These services are assumed to
-have the following properties:
-
-=over 2
-
-=item
-The network consists of one or more 'Access Concentrators' (ACs), such as
-DSLAMs or wireless access points. (See L<FS::ac>.)
-
-=item
-Each AC provides connectivity to one or more contiguous blocks of IP addresses,
-each described by a gateway address and a netmask. (See L<FS::ac_block>.)
-
-=item
-Each connection has one or more static IP addresses within one of these blocks.
-
-=item
-The details of configuring routers and other devices are to be handled by a
-site-specific L<FS::part_export> subclass.
-
-=back
-
-FS::svc_broadband inherits from FS::svc_Common. The following fields are
-currently supported:
-
-=over 4
-
-=item svcnum - primary key
-
-=item
-actypenum - access concentrator type; see L<FS::ac_type>. This is included here
-so that a part_svc can specifically be a 'wireless' or 'DSL' service by
-designating actypenum as a fixed field. It does create a redundant functional
-dependency between this table and ac_type, in that the matching ac_type could
-be found by looking up the IP address in ac_block and then finding the block's
-AC, but part_svc can't do that, and we don't feel like hacking it so that it
-can.
-
-=item
-speed_up - maximum upload speed, in bits per second. If set to zero, upload
-speed will be unlimited. Exports that do traffic shaping should handle this
-correctly, and not blindly set the upload speed to zero and kill the customer's
-connection.
-
-=item
-speed_down - maximum download speed, as above
-
-=item
-ip_addr - the customer's IP address. If the customer needs more than one IP
-address, set this to the address of the customer's router. As a result, the
-customer's router will have the same address for both it's internal and external
-interfaces thus saving address space. This has been found to work on most NAT
-routers available.
-
-=item
-ip_netmask - the customer's netmask, as a single integer in the range 0-32.
-(E.g. '24', not '255.255.255.0'. We assume that address blocks are contiguous.)
-This should be 32 unless the customer has multiple IP addresses.
-
-=item
-mac_addr - the MAC address of the customer's router or other device directly
-connected to the network, if needed. Some systems (e.g. DHCP, MAC address-based
-access control) may need this. If not, you may leave it blank.
-
-=item
-location - a human-readable description of the location of the connected site,
-such as its address. This should not be used for billing or contact purposes;
-that information is stored in L<FS::cust_main>.
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF
-
-Creates a new svc_broadband. To add the record to the database, see
-L<"insert">.
-
-Note that this stores the hash reference, not a distinct copy of the hash it
-points to. You can ask the object for a copy with the I<hash> method.
-
-=cut
-
-sub table { 'svc_broadband'; }
-
-=item insert
-
-Adds this record to the database. If there is an error, returns the error,
-otherwise returns false.
-
-The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be
-defined. An FS::cust_svc record will be created and inserted.
-
-=cut
-
-# sub insert {}
-# Standard FS::svc_Common::insert
-# (any necessary Deep Magic is handled by exports)
-
-=item delete
-
-Delete this record from the database.
-
-=cut
-
-# Standard FS::svc_Common::delete
-
-=item replace OLD_RECORD
-
-Replaces the OLD_RECORD with this one in the database. If there is an error,
-returns the error, otherwise returns false.
-
-=cut
-
-# Standard FS::svc_Common::replace
-# Notice a pattern here?
-
-=item suspend
-
-Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
-
-=item unsuspend
-
-Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
-
-=item cancel
-
-Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
-
-=item check
-
-Checks all fields to make sure this is a valid broadband service. If there is
-an error, returns the error, otherwise returns false. Called by the insert
-and replace methods.
-
-=cut
-
-sub check {
- my $self = shift;
- my $x = $self->setfixed;
-
- return $x unless ref($x);
-
- my $error =
- $self->ut_numbern('svcnum')
- || $self->ut_foreign_key('actypenum', 'ac_type', 'actypenum')
- || $self->ut_number('speed_up')
- || $self->ut_number('speed_down')
- || $self->ut_ip('ip_addr')
- || $self->ut_numbern('ip_netmask')
- || $self->ut_textn('mac_addr')
- || $self->ut_textn('location')
- ;
- return $error if $error;
-
- if($self->speed_up < 0) { return 'speed_up must be positive'; }
- if($self->speed_down < 0) { return 'speed_down must be positive'; }
-
- # This should catch errors in the ip_addr and ip_netmask. If it doesn't,
- # they'll almost certainly not map into a valid block anyway.
- my $self_addr = new NetAddr::IP ($self->ip_addr, $self->ip_netmask);
- return 'Cannot parse address: ' . $self->ip_addr . '/' . $self->ip_netmask unless $self_addr;
-
- my @block = grep {
- my $block_addr = new NetAddr::IP ($_->ip_gateway, $_->ip_netmask);
- if ($block_addr->contains($self_addr)) { $_ };
- } qsearch( 'ac_block', { acnum => $self->acnum });
-
- if(scalar @block == 0) {
- return 'Block not found for address '.$self->ip_addr.' in actype '.$self->actypenum;
- } elsif(scalar @block > 1) {
- return 'ERROR: Intersecting blocks found for address '.$self->ip_addr.' :'.
- join ', ', map {$_->ip_addr . '/' . $_->ip_netmask} @block;
- }
- # OK, we've found a valid block. We don't actually _do_ anything with it, though; we
- # just take comfort in the knowledge that it exists.
-
- # A simple qsearchs won't work here. Since we can assign blocks to customers,
- # we have to make sure the new address doesn't fall within someone else's
- # block. Ugh.
-
- my @conflicts = grep {
- my $cust_addr = new NetAddr::IP($_->ip_addr, $_->ip_netmask);
- if (($cust_addr->contains($self_addr)) and
- ($_->svcnum ne $self->svcnum)) { $_; };
- } qsearch('svc_broadband', {});
-
- if (scalar @conflicts > 0) {
- return 'Address in use by existing service';
- }
-
- # Are we trying to use a network, broadcast, or the AC's address?
- foreach (qsearch('ac_block', { acnum => $self->acnum })) {
- my $block_addr = new NetAddr::IP($_->ip_gateway, $_->ip_netmask);
- if ($block_addr->network->addr eq $self_addr->addr) {
- return 'Address is network address for block '. $block_addr->network;
- }
- if ($block_addr->broadcast->addr eq $self_addr->addr) {
- return 'Address is broadcast address for block '. $block_addr->network;
- }
- if ($block_addr->addr eq $self_addr->addr) {
- return 'Address belongs to the access concentrator: '. $block_addr->addr;
- }
- }
-
- ''; #no error
-}
-
-=item ac_block
-
-Returns the FS::ac_block record (i.e. the address block) for this broadband service.
-
-=cut
-
-sub ac_block {
- my $self = shift;
- my $self_addr = new NetAddr::IP ($self->ip_addr, $self->ip_netmask);
-
- foreach my $block (qsearch( 'ac_block', {} )) {
- my $block_addr = new NetAddr::IP ($block->ip_addr, $block->ip_netmask);
- if($block_addr->contains($self_addr)) { return $block; }
- }
- return '';
-}
-
-=item ac_type
-
-Returns the FS::ac_type record for this broadband service.
-
-=cut
-
-sub ac_type {
- my $self = shift;
- return qsearchs('ac_type', { actypenum => $self->actypenum });
-}
-
-=back
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-L<FS::svc_Common>, L<FS::Record>, L<FS::ac_type>, L<FS::ac_block>,
-L<FS::part_svc>, schema.html from the base documentation.
-
-=cut
-
-1;
-
diff --git a/FS/FS/svc_domain.pm b/FS/FS/svc_domain.pm
index 0d71b2775..637d0493c 100644
--- a/FS/FS/svc_domain.pm
+++ b/FS/FS/svc_domain.pm
@@ -251,6 +251,10 @@ sub delete {
return "Can't delete a domain which has accounts!"
if qsearch( 'svc_acct', { 'domsvc' => $self->svcnum } );
+ return "Can't delete a domain with (svc_acct_sm) mail aliases!"
+ if defined( $FS::Record::dbdef->table('svc_acct_sm') )
+ && qsearch('svc_acct_sm', { 'domsvc' => $self->svcnum } );
+
#return "Can't delete a domain with (domain_record) zone entries!"
# if qsearch('domain_record', { 'svcnum' => $self->svcnum } );
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 24fef1748..fff95c8c8 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -9,11 +9,8 @@ bin/freeside-email
bin/freeside-queued
bin/freeside-addoutsource
bin/freeside-addoutsourceuser
-bin/freeside-deloutsource
-bin/freeside-deloutsourceuser
bin/freeside-apply-credits
bin/freeside-adduser
-bin/freeside-deluser
bin/freeside-setup
bin/freeside-setinvoice
bin/freeside-overdue
@@ -39,9 +36,6 @@ FS/UI/Gtk.pm
FS/UI/agent.pm
FS/UID.pm
FS/Msgcat.pm
-FS/ac.pm
-FS/ac_block.pm
-FS/ac_type.pm
FS/agent.pm
FS/agent_type.pm
FS/cust_bill.pm
@@ -60,7 +54,6 @@ FS/cust_refund.pm
FS/cust_credit_refund.pm
FS/cust_svc.pm
FS/part_bill_event.pm
-FS/part_ac_field.pm
FS/export_svc.pm
FS/part_export.pm
FS/part_export_option.pm
@@ -90,7 +83,7 @@ FS/pkg_svc.pm
FS/svc_Common.pm
FS/svc_acct.pm
FS/svc_acct_pop.pm
-FS/svc_broadband.pm
+FS/svc_acct_sm.pm
FS/svc_domain.pm
FS/type_pkgs.pm
FS/nas.pm
@@ -167,6 +160,7 @@ t/radius_usergroup.t
t/session.t
t/svc_acct.t
t/svc_acct_pop.t
+t/svc_acct_sm.t
t/svc_Common.t
t/svc_domain.t
t/svc_forward.t
diff --git a/FS/bin/freeside-addoutsourceuser b/FS/bin/freeside-addoutsourceuser
index 180cd9399..bbad8aa3f 100644
--- a/FS/bin/freeside-addoutsourceuser
+++ b/FS/bin/freeside-addoutsourceuser
@@ -11,5 +11,5 @@ freeside-adduser -h /usr/local/etc/freeside/htpasswd \
[ -e /usr/local/etc/freeside/dbdef.DBI:Pg:host=localhost\;dbname=$domain ] \
|| ( freeside-setup $username 2>/dev/null; \
- /home/ivan/freeside/bin/populate-msgcat $username )
+ /home/ivan/freeside/bin/populate-msgcat $username; 2>/dev/null )
diff --git a/FS/bin/freeside-cc-receipts-report b/FS/bin/freeside-cc-receipts-report
index 136851aec..f4225d28a 100755
--- a/FS/bin/freeside-cc-receipts-report
+++ b/FS/bin/freeside-cc-receipts-report
@@ -245,7 +245,7 @@ user: From the mapsecrets file - see config.html from the base documentation
=head1 VERSION
-$Id: freeside-cc-receipts-report,v 1.5 2002-09-09 22:57:34 ivan Exp $
+$Id: freeside-cc-receipts-report,v 1.4.4.1 2002-09-09 22:57:32 ivan Exp $
=head1 BUGS
diff --git a/FS/bin/freeside-credit-report b/FS/bin/freeside-credit-report
index 410dabe8f..da01d3bd5 100755
--- a/FS/bin/freeside-credit-report
+++ b/FS/bin/freeside-credit-report
@@ -199,7 +199,7 @@ user: From the mapsecrets file - see config.html from the base documentation
=head1 VERSION
-$Id: freeside-credit-report,v 1.5 2002-09-09 22:57:34 ivan Exp $
+$Id: freeside-credit-report,v 1.4.4.1 2002-09-09 22:57:32 ivan Exp $
=head1 BUGS
diff --git a/FS/bin/freeside-email b/FS/bin/freeside-email
index 400dc2ac7..c7ff41114 100755
--- a/FS/bin/freeside-email
+++ b/FS/bin/freeside-email
@@ -12,9 +12,11 @@ my $user = shift or die &usage;
adminsuidsetup $user;
my $conf = new FS::Conf;
+my $domain = $conf->config('domain');
my @svc_acct = qsearch('svc_acct', {});
-my @emails = map $_->email, @svc_acct;
+my @usernames = map $_->username, @svc_acct;
+my @emails = map "$_\@$domain", @usernames;
print join("\n", @emails), "\n";
@@ -49,7 +51,7 @@ 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 $
+$Id: freeside-email,v 1.1 2001-05-15 07:52:34 ivan Exp $
=head1 BUGS
diff --git a/FS/bin/freeside-expiration-alerter b/FS/bin/freeside-expiration-alerter
index 5399f6d22..2c89bef20 100755
--- a/FS/bin/freeside-expiration-alerter
+++ b/FS/bin/freeside-expiration-alerter
@@ -202,7 +202,7 @@ user: From the mapsecrets file - see config.html from the base documentation
=head1 VERSION
-$Id: freeside-expiration-alerter,v 1.4 2002-09-16 09:27:14 ivan Exp $
+$Id: freeside-expiration-alerter,v 1.3.4.1 2002-09-16 09:27:12 ivan Exp $
=head1 BUGS
diff --git a/FS/bin/freeside-receivables-report b/FS/bin/freeside-receivables-report
index f3ad2a1a6..033e83c52 100755
--- a/FS/bin/freeside-receivables-report
+++ b/FS/bin/freeside-receivables-report
@@ -192,7 +192,7 @@ user: From the mapsecrets file - see config.html from the base documentation
=head1 VERSION
-$Id: freeside-receivables-report,v 1.6 2002-09-09 22:57:34 ivan Exp $
+$Id: freeside-receivables-report,v 1.5.4.1 2002-09-09 22:57:32 ivan Exp $
=head1 BUGS
diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup
index e8bb7ec62..78a03385c 100755
--- a/FS/bin/freeside-setup
+++ b/FS/bin/freeside-setup
@@ -7,7 +7,7 @@ use strict;
use vars qw($opt_s);
use Getopt::Std;
use DBI;
-use DBIx::DBSchema 0.21;
+use DBIx::DBSchema 0.20;
use DBIx::DBSchema::Table;
use DBIx::DBSchema::Column;
use DBIx::DBSchema::ColGroup::Unique;
@@ -138,6 +138,33 @@ foreach $attribute (@check_attributes) {
));
}
+##make part_svc table (but now as object)
+#
+#my($part_svc)=$dbdef->table('part_svc');
+#
+##because of svc_acct_pop
+##foreach (grep /^svc_/, $dbdef->tables) {
+##foreach (qw(svc_acct svc_acct_sm svc_charge svc_domain svc_wo)) {
+#foreach (qw(svc_acct svc_domain svc_forward svc_www)) {
+# my($table)=$dbdef->table($_);
+# my($col);
+# foreach $col ( $table->columns ) {
+# next if $col =~ /^svcnum$/;
+# $part_svc->addcolumn( new DBIx::DBSchema::Column (
+# $table->name. '__' . $table->column($col)->name,
+# 'varchar', #$table->column($col)->type,
+# 'NULL',
+# $char_d, #$table->column($col)->length,
+# ));
+# $part_svc->addcolumn ( new DBIx::DBSchema::Column (
+# $table->name. '__'. $table->column($col)->name . "_flag",
+# 'char',
+# 'NULL',
+# 1,
+# ));
+# }
+#}
+
#create history tables (false laziness w/create-history-tables)
foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
my $tableobj = $dbdef->table($table)
@@ -312,7 +339,7 @@ sub tables_hash_hack {
'agent' => {
'columns' => [
- 'agentnum', 'serial', '', '',
+ 'agentnum', 'int', '', '',
'agent', 'varchar', '', $char_d,
'typenum', 'int', '', '',
'freq', 'int', 'NULL', '',
@@ -325,7 +352,7 @@ sub tables_hash_hack {
'agent_type' => {
'columns' => [
- 'typenum', 'serial', '', '',
+ 'typenum', 'int', '', '',
'atype', 'varchar', '', $char_d,
],
'primary_key' => 'typenum',
@@ -345,7 +372,7 @@ sub tables_hash_hack {
'cust_bill' => {
'columns' => [
- 'invnum', 'serial', '', '',
+ 'invnum', 'int', '', '',
'custnum', 'int', '', '',
'_date', @date_type,
'charged', @money_type,
@@ -359,7 +386,7 @@ sub tables_hash_hack {
'cust_bill_event' => {
'columns' => [
- 'eventnum', 'serial', '', '',
+ 'eventnum', 'int', '', '',
'invnum', 'int', '', '',
'eventpart', 'int', '', '',
'_date', @date_type,
@@ -374,7 +401,7 @@ sub tables_hash_hack {
'part_bill_event' => {
'columns' => [
- 'eventpart', 'serial', '', '',
+ 'eventpart', 'int', '', '',
'payby', 'char', '', 4,
'event', 'varchar', '', $char_d,
'eventcode', @perl_type,
@@ -405,11 +432,11 @@ sub tables_hash_hack {
'cust_credit' => {
'columns' => [
- 'crednum', 'serial', '', '',
+ 'crednum', 'int', '', '',
'custnum', 'int', '', '',
'_date', @date_type,
'amount', @money_type,
- 'otaker', 'varchar', '', 32,
+ 'otaker', 'varchar', '', 8,
'reason', 'text', 'NULL', '',
'closed', 'char', 'NULL', 1,
],
@@ -420,7 +447,7 @@ sub tables_hash_hack {
'cust_credit_bill' => {
'columns' => [
- 'creditbillnum', 'serial', '', '',
+ 'creditbillnum', 'int', '', '',
'crednum', 'int', '', '',
'invnum', 'int', '', '',
'_date', @date_type,
@@ -433,7 +460,7 @@ sub tables_hash_hack {
'cust_main' => {
'columns' => [
- 'custnum', 'serial', '', '',
+ 'custnum', 'int', '', '',
'agentnum', 'int', '', '',
# 'titlenum', 'int', 'NULL', '',
'last', 'varchar', '', $char_d,
@@ -471,7 +498,7 @@ sub tables_hash_hack {
'paydate', 'varchar', 'NULL', 10,
'payname', 'varchar', 'NULL', $char_d,
'tax', 'char', 'NULL', 1,
- 'otaker', 'varchar', '', 32,
+ 'otaker', 'varchar', '', 8,
'refnum', 'int', '', '',
'referral_custnum', 'int', 'NULL', '',
'comments', 'text', 'NULL', '',
@@ -484,7 +511,7 @@ sub tables_hash_hack {
'cust_main_invoice' => {
'columns' => [
- 'destnum', 'serial', '', '',
+ 'destnum', 'int', '', '',
'custnum', 'int', '', '',
'dest', 'varchar', '', $char_d,
],
@@ -497,7 +524,7 @@ sub tables_hash_hack {
#cust_main_county for validation and to provide
# a tax rate.
'columns' => [
- 'taxnum', 'serial', '', '',
+ 'taxnum', 'int', '', '',
'state', 'varchar', 'NULL', $char_d,
'county', 'varchar', 'NULL', $char_d,
'country', 'char', '', 2,
@@ -513,7 +540,7 @@ sub tables_hash_hack {
'cust_pay' => {
'columns' => [
- 'paynum', 'serial', '', '',
+ 'paynum', 'int', '', '',
#now cust_bill_pay #'invnum', 'int', '', '',
'custnum', 'int', '', '',
'paid', @money_type,
@@ -531,7 +558,7 @@ sub tables_hash_hack {
'cust_bill_pay' => {
'columns' => [
- 'billpaynum', 'serial', '', '',
+ 'billpaynum', 'int', '', '',
'invnum', 'int', '', '',
'paynum', 'int', '', '',
'amount', @money_type,
@@ -545,7 +572,7 @@ sub tables_hash_hack {
'cust_pay_batch' => { #what's this used for again? list of customers
#in current CARD batch? (necessarily CARD?)
'columns' => [
- 'paybatchnum', 'serial', '', '',
+ 'paybatchnum', 'int', '', '',
'invnum', 'int', '', '',
'custnum', 'int', '', '',
'last', 'varchar', '', $char_d,
@@ -570,10 +597,10 @@ sub tables_hash_hack {
'cust_pkg' => {
'columns' => [
- 'pkgnum', 'serial', '', '',
+ 'pkgnum', 'int', '', '',
'custnum', 'int', '', '',
'pkgpart', 'int', '', '',
- 'otaker', 'varchar', '', 32,
+ 'otaker', 'varchar', '', 8,
'setup', @date_type,
'bill', @date_type,
'susp', @date_type,
@@ -588,12 +615,12 @@ sub tables_hash_hack {
'cust_refund' => {
'columns' => [
- 'refundnum', 'serial', '', '',
+ 'refundnum', 'int', '', '',
#now cust_credit_refund #'crednum', 'int', '', '',
'custnum', 'int', '', '',
'_date', @date_type,
'refund', @money_type,
- 'otaker', 'varchar', '', 32,
+ 'otaker', 'varchar', '', 8,
'reason', 'varchar', '', $char_d,
'payby', 'char', '', 4, # CARD/BILL/COMP, should be index
# into payment type table.
@@ -608,7 +635,7 @@ sub tables_hash_hack {
'cust_credit_refund' => {
'columns' => [
- 'creditrefundnum', 'serial', '', '',
+ 'creditrefundnum', 'int', '', '',
'crednum', 'int', '', '',
'refundnum', 'int', '', '',
'amount', @money_type,
@@ -622,7 +649,7 @@ sub tables_hash_hack {
'cust_svc' => {
'columns' => [
- 'svcnum', 'serial', '', '',
+ 'svcnum', 'int', '', '',
'pkgnum', 'int', 'NULL', '',
'svcpart', 'int', '', '',
],
@@ -633,7 +660,7 @@ sub tables_hash_hack {
'part_pkg' => {
'columns' => [
- 'pkgpart', 'serial', '', '',
+ 'pkgpart', 'int', '', '',
'pkg', 'varchar', '', $char_d,
'comment', 'varchar', '', $char_d,
'setup', @perl_type,
@@ -674,7 +701,7 @@ sub tables_hash_hack {
'part_referral' => {
'columns' => [
- 'refnum', 'serial', '', '',
+ 'refnum', 'int', '', '',
'referral', 'varchar', '', $char_d,
],
'primary_key' => 'refnum',
@@ -684,7 +711,7 @@ sub tables_hash_hack {
'part_svc' => {
'columns' => [
- 'svcpart', 'serial', '', '',
+ 'svcpart', 'int', '', '',
'svc', 'varchar', '', $char_d,
'svcdb', 'varchar', '', $char_d,
'disabled', 'char', 'NULL', 1,
@@ -696,7 +723,7 @@ sub tables_hash_hack {
'part_svc_column' => {
'columns' => [
- 'columnnum', 'serial', '', '',
+ 'columnnum', 'int', '', '',
'svcpart', 'int', '', '',
'columnname', 'varchar', '', 64,
'columnvalue', 'varchar', 'NULL', $char_d,
@@ -710,7 +737,7 @@ sub tables_hash_hack {
#(this should be renamed to part_pop)
'svc_acct_pop' => {
'columns' => [
- 'popnum', 'serial', '', '',
+ 'popnum', 'int', '', '',
'city', 'varchar', '', $char_d,
'state', 'varchar', '', $char_d,
'ac', 'char', '', 3,
@@ -724,7 +751,7 @@ sub tables_hash_hack {
'part_pop_local' => {
'columns' => [
- 'localnum', 'serial', '', '',
+ 'localnum', 'int', '', '',
'popnum', 'int', '', '',
'city', 'varchar', 'NULL', $char_d,
'state', 'char', 'NULL', 2,
@@ -759,6 +786,18 @@ sub tables_hash_hack {
'index' => [ ['username'], ['domsvc'] ],
},
+# 'svc_acct_sm' => {
+# 'columns' => [
+# 'svcnum', 'int', '', '',
+# 'domsvc', 'int', '', '',
+# 'domuid', 'int', '', '',
+# 'domuser', 'varchar', '', $char_d,
+# ],
+# 'primary_key' => 'svcnum',
+# 'unique' => [ [] ],
+# 'index' => [ ['domsvc'], ['domuid'] ],
+# },
+
#'svc_charge' => {
# 'columns' => [
# 'svcnum', 'int', '', '',
@@ -782,7 +821,7 @@ sub tables_hash_hack {
'domain_record' => {
'columns' => [
- 'recnum', 'serial', '', '',
+ 'recnum', 'int', '', '',
'svcnum', 'int', '', '',
'reczone', 'varchar', '', $char_d,
'recaf', 'char', '', 2,
@@ -832,7 +871,7 @@ sub tables_hash_hack {
'prepay_credit' => {
'columns' => [
- 'prepaynum', 'serial', '', '',
+ 'prepaynum', 'int', '', '',
'identifier', 'varchar', '', $char_d,
'amount', @money_type,
'seconds', 'int', 'NULL', '',
@@ -844,7 +883,7 @@ sub tables_hash_hack {
'port' => {
'columns' => [
- 'portnum', 'serial', '', '',
+ 'portnum', 'int', '', '',
'ip', 'varchar', 'NULL', 15,
'nasport', 'int', 'NULL', '',
'nasnum', 'int', '', '',
@@ -856,7 +895,7 @@ sub tables_hash_hack {
'nas' => {
'columns' => [
- 'nasnum', 'serial', '', '',
+ 'nasnum', 'int', '', '',
'nas', 'varchar', '', $char_d,
'nasip', 'varchar', '', 15,
'nasfqdn', 'varchar', '', $char_d,
@@ -869,7 +908,7 @@ sub tables_hash_hack {
'session' => {
'columns' => [
- 'sessionnum', 'serial', '', '',
+ 'sessionnum', 'int', '', '',
'portnum', 'int', '', '',
'svcnum', 'int', '', '',
'login', @date_type,
@@ -882,7 +921,7 @@ sub tables_hash_hack {
'queue' => {
'columns' => [
- 'jobnum', 'serial', '', '',
+ 'jobnum', 'int', '', '',
'job', 'text', '', '',
'_date', 'int', '', '',
'status', 'varchar', '', $char_d,
@@ -896,7 +935,7 @@ sub tables_hash_hack {
'queue_arg' => {
'columns' => [
- 'argnum', 'serial', '', '',
+ 'argnum', 'int', '', '',
'jobnum', 'int', '', '',
'arg', 'text', 'NULL', '',
],
@@ -907,7 +946,7 @@ sub tables_hash_hack {
'queue_depend' => {
'columns' => [
- 'dependnum', 'serial', '', '',
+ 'dependnum', 'int', '', '',
'jobnum', 'int', '', '',
'depend_jobnum', 'int', '', '',
],
@@ -918,7 +957,7 @@ sub tables_hash_hack {
'export_svc' => {
'columns' => [
- 'exportsvcnum' => 'serial', '', '',
+ 'exportsvcnum' => 'int', '', '',
'exportnum' => 'int', '', '',
'svcpart' => 'int', '', '',
],
@@ -929,7 +968,7 @@ sub tables_hash_hack {
'part_export' => {
'columns' => [
- 'exportnum', 'serial', '', '',
+ 'exportnum', 'int', '', '',
#'svcpart', 'int', '', '',
'machine', 'varchar', '', $char_d,
'exporttype', 'varchar', '', $char_d,
@@ -942,7 +981,7 @@ sub tables_hash_hack {
'part_export_option' => {
'columns' => [
- 'optionnum', 'serial', '', '',
+ 'optionnum', 'int', '', '',
'exportnum', 'int', '', '',
'optionname', 'varchar', '', $char_d,
'optionvalue', 'text', 'NULL', '',
@@ -954,7 +993,7 @@ sub tables_hash_hack {
'radius_usergroup' => {
'columns' => [
- 'usergroupnum', 'serial', '', '',
+ 'usergroupnum', 'int', '', '',
'svcnum', 'int', '', '',
'groupname', 'varchar', '', $char_d,
],
@@ -965,7 +1004,7 @@ sub tables_hash_hack {
'msgcat' => {
'columns' => [
- 'msgnum', 'serial', '', '',
+ 'msgnum', 'int', '', '',
'msgcode', 'varchar', '', $char_d,
'locale', 'varchar', '', 16,
'msg', 'text', '', '',
@@ -977,7 +1016,7 @@ sub tables_hash_hack {
'cust_tax_exempt' => {
'columns' => [
- 'exemptnum', 'serial', '', '',
+ 'exemptnum', 'int', '', '',
'custnum', 'int', '', '',
'taxnum', 'int', '', '',
'year', 'int', '', '',
@@ -989,77 +1028,7 @@ sub tables_hash_hack {
'index' => [],
},
- 'ac_type' => {
- 'columns' => [
- 'actypenum', 'serial', '', '',
- 'actypename', 'varchar', '', $char_d,
- ],
- 'primary_key' => 'actypenum',
- 'unique' => [],
- 'index' => [],
- },
-
- 'ac' => {
- 'columns' => [
- 'acnum', 'serial', '', '',
- 'actypenum', 'int', '', '',
- 'acname', 'varchar', '', $char_d,
- ],
- 'primary_key' => 'acnum',
- 'unique' => [],
- 'index' => [ [ 'actypenum' ] ],
- },
-
- 'part_ac_field' => {
- 'columns' => [
- 'acfieldpart', 'serial', '', '',
- 'actypenum', 'int', '', '',
- 'name', 'varchar', '', $char_d,
- 'ut_type', 'varchar', '', $char_d,
- ],
- 'primary_key' => 'acfieldpart',
- 'unique' => [],
- 'index' => [ [ 'actypenum' ] ],
- },
-
- 'ac_field' => {
- 'columns' => [
- 'acfieldpart', 'int', '', '',
- 'acnum', 'int', '', '',
- 'value', 'text', '', '',
- ],
- 'primary_key' => '',
- 'unique' => [ [ 'acfieldpart', 'acnum' ] ],
- 'index' => [ [ 'acnum' ] ],
- },
-
- 'ac_block' => {
- 'columns' => [
- 'acnum', 'int', '', '',
- 'ip_gateway', 'varchar', '', 15,
- 'ip_netmask', 'int', '', '',
- ],
- 'primary_key' => '',
- 'unique' => [],
- 'index' => [ [ 'acnum' ] ],
- },
- 'svc_broadband' => {
- 'columns' => [
- 'svcnum', 'int', '', '',
- 'actypenum', 'int', '', '',
- 'speed_up', 'int', '', '',
- 'speed_down', 'int', '', '',
- 'acnum', 'int', '', '',
- 'ip_addr', 'varchar', '', 15,
- 'ip_netmask', 'int', '', '',
- 'mac_addr', 'char', '', 17,
- 'location', 'varchar', '', $char_d,
- ],
- 'primary_key' => 'svcnum',
- 'unique' => [],
- 'index' => [ [ 'actypenum' ] ],
- },
);
diff --git a/FS/bin/freeside-tax-report b/FS/bin/freeside-tax-report
index 240f3ad37..d48da87a6 100755
--- a/FS/bin/freeside-tax-report
+++ b/FS/bin/freeside-tax-report
@@ -267,7 +267,7 @@ user: From the mapsecrets file - see config.html from the base documentation
=head1 VERSION
-$Id: freeside-tax-report,v 1.5 2002-09-09 22:57:34 ivan Exp $
+$Id: freeside-tax-report,v 1.4.4.1 2002-09-09 22:57:32 ivan Exp $
=head1 BUGS
diff --git a/FS/t/svc_acct_sm.t b/FS/t/svc_acct_sm.t
new file mode 100644
index 000000000..1082f2cdb
--- /dev/null
+++ b/FS/t/svc_acct_sm.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::svc_acct_sm;
+$loaded=1;
+print "ok 1\n";