diff options
Diffstat (limited to 'FS')
34 files changed, 606 insertions, 1232 deletions
@@ -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"; |