X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=b241ecac2de9e40f4bf2a11bbc6512426b1ea395;hb=9208e850bf047eb4a4438ad3958b7891370d2cb1;hp=dff24139315e67748b7d03e5a7f82b927cb49baf;hpb=1fd215138eeed664b07d4347ce18a7a1a616419b;p=freeside.git diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index dff241393..b241ecac2 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -17,9 +17,31 @@ use FS::svc_acct; use FS::svc_acct_sm; use FS::svc_domain; use FS::svc_www; +use FS::svc_forward; @ISA = qw( FS::Record ); +sub _cache { + my $self = shift; + my ( $hashref, $cache ) = @_; + #if ( $hashref->{'pkgpart'} ) { + if ( $hashref->{'pkg'} ) { + # #@{ $self->{'_pkgnum'} } = (); + # my $subcache = $cache->subcache('pkgpart', 'part_pkg'); + # $self->{'_pkgpart'} = $subcache; + # #push @{ $self->{'_pkgnum'} }, + # FS::part_pkg->new_or_cached($hashref, $subcache); + $self->{'_pkgpart'} = FS::part_pkg->new($hashref); + } + if ( exists $hashref->{'svcnum'} ) { + #@{ $self->{'_pkgnum'} } = (); + my $subcache = $cache->subcache('svcnum', 'cust_svc', $hashref->{pkgnum}); + $self->{'_svcnum'} = $subcache; + #push @{ $self->{'_pkgnum'} }, + FS::cust_svc->new_or_cached($hashref, $subcache) if $hashref->{svcnum}; + } +} + =head1 NAME FS::cust_pkg - Object methods for cust_pkg objects @@ -49,6 +71,8 @@ FS::cust_pkg - Object methods for cust_pkg objects @labels = $record->labels; + $seconds = $record->seconds_since($timestamp); + $error = FS::cust_pkg::order( $custnum, \@pkgparts ); $error = FS::cust_pkg::order( $custnum, \@pkgparts, \@remove_pkgnums ] ); @@ -77,6 +101,9 @@ inherits from FS::Record. The following fields are currently supported: =item otaker - order taker (assigned automatically if null, see L) +=item manual_flag - If this field is set to 1, disables the automatic +unsuspension of this package when using the B config file. + =back Note: setup, bill, susp, expire and cancel are specified as UNIX timestamps; @@ -107,12 +134,12 @@ sub insert { # custnum might not have have been defined in sub check (for one-shot new # customers), so check it here instead + # (is this still necessary with transactions?) my $error = $self->ut_number('custnum'); - return $error if $error + return $error if $error; - return "Unknown customer" - unless qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); + return "Unknown customer ". $self->custnum unless $self->cust_main; $self->SUPER::insert; @@ -120,15 +147,16 @@ sub insert { =item delete -Currently unimplemented. You don't want to delete billing items, because there -would then be no record the customer ever purchased the item. Instead, see -the cancel method. +This method now works but you probably shouldn't use it. + +You don't want to delete billing items, because there would then be no record +the customer ever purchased the item. Instead, see the cancel method. =cut -sub delete { - return "Can't delete cust_pkg records!"; -} +#sub delete { +# return "Can't delete cust_pkg records!"; +#} =item replace OLD_RECORD @@ -154,9 +182,12 @@ sub replace { #return "Can't (yet?) change pkgpart!" if $old->pkgpart != $new->pkgpart; return "Can't change otaker!" if $old->otaker ne $new->otaker; - return "Can't change setup once it exists!" - if $old->getfield('setup') && - $old->getfield('setup') != $new->getfield('setup'); + + #allow this *sigh* + #return "Can't change setup once it exists!" + # if $old->getfield('setup') && + # $old->getfield('setup') != $new->getfield('setup'); + #some logic for bill, susp, cancel? $new->SUPER::replace($old); @@ -185,8 +216,7 @@ sub check { return $error if $error; if ( $self->custnum ) { - return "Unknown customer" - unless qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); + return "Unknown customer ". $self->custnum unless $self->cust_main; } return "Unknown pkgpart" @@ -196,6 +226,11 @@ sub check { $self->otaker =~ /^(\w{0,16})$/ or return "Illegal otaker"; $self->otaker($1); + if ( $self->dbdef_table->column('manual_flag') ) { + $self->manual_flag =~ /^([01]?)$/ or return "Illegal manual_flag"; + $self->manual_flag($1); + } + ''; #no error } @@ -409,7 +444,26 @@ L). sub part_pkg { my $self = shift; - qsearchs( 'part_pkg', { 'pkgpart' => $self->pkgpart } ); + #exists( $self->{'_pkgpart'} ) + $self->{'_pkgpart'} + ? $self->{'_pkgpart'} + : qsearchs( 'part_pkg', { 'pkgpart' => $self->pkgpart } ); +} + +=item cust_svc + +Returns the services for this package, as FS::cust_svc objects (see +L) + +=cut + +sub cust_svc { + my $self = shift; + if ( $self->{'_svcnum'} ) { + values %{ $self->{'_svcnum'}->cache }; + } else { + qsearch ( 'cust_svc', { 'pkgnum' => $self->pkgnum } ); + } } =item labels @@ -421,7 +475,42 @@ Returns a list of lists, calling the label method for all services sub labels { my $self = shift; - map { [ $_->label ] } qsearch ( 'cust_svc', { 'pkgnum' => $self->pkgnum } ); + map { [ $_->label ] } $self->cust_svc; +} + +=item cust_main + +Returns the parent customer object (see L). + +=cut + +sub cust_main { + my $self = shift; + qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); +} + +=item seconds_since TIMESTAMP + +Returns the number of seconds all accounts (see L) in this +package have been online since TIMESTAMP. + +TIMESTAMP is specified as a UNIX timestamp; see L. Also see +L and L for conversion functions. + +=cut + +sub seconds_since { + my($self, $since) = @_; + my $seconds = 0; + + foreach my $cust_svc ( + grep { $_->part_svc->svcdb eq 'svc_acct' } $self->cust_svc + ) { + $seconds += $cust_svc->seconds_since($since); + } + + $seconds; + } =back @@ -567,7 +656,7 @@ sub order { =head1 VERSION -$Id: cust_pkg.pm,v 1.7 2001-10-01 10:31:08 ivan Exp $ +$Id: cust_pkg.pm,v 1.16 2002-01-29 16:33:15 ivan Exp $ =head1 BUGS @@ -584,10 +673,13 @@ 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 ? + =head1 SEE ALSO -L, L, L, L -, L, schema.html from the base documentation +L, L, L, L, +L, schema.html from the base documentation =cut