input and output on data volume fields specified with k,m,g,or t
[freeside.git] / FS / FS / cust_pkg.pm
index 689ffed..616a480 100644 (file)
@@ -2,6 +2,7 @@ package FS::cust_pkg;
 
 use strict;
 use vars qw(@ISA $disable_agentcheck $DEBUG);
+use List::Util qw(max);
 use Tie::IxHash;
 use FS::UID qw( getotaker dbh );
 use FS::Misc qw( send_email );
@@ -17,6 +18,7 @@ use FS::h_cust_svc;
 use FS::reg_code;
 use FS::part_svc;
 use FS::cust_pkg_reason;
+use FS::reason;
 
 # need to 'use' these instead of 'require' in sub { cancel, suspend, unsuspend,
 # setup }
@@ -29,7 +31,7 @@ use FS::svc_forward;
 # for sending cancel emails in sub cancel
 use FS::Conf;
 
-@ISA = qw( FS::cust_main_Mixin FS::Record );
+@ISA = qw( FS::cust_main_Mixin FS::option_Common FS::Record );
 
 $DEBUG = 0;
 
@@ -173,7 +175,7 @@ sub insert {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $error = $self->SUPER::insert;
+  my $error = $self->SUPER::insert($options{options} ? %{$options{options}} : ());
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -317,7 +319,9 @@ sub replace {
 
   }
 
-  my $error = $new->SUPER::replace($old);
+  my $error = $new->SUPER::replace($old,
+                                   $options{options} ? ${options{options}} : ()
+                                  );
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -482,7 +486,7 @@ sub cancel {
     my %hash = $self->hash;
     $hash{'cancel'} = time;
     my $new = new FS::cust_pkg ( \%hash );
-    $error = $new->replace($self);
+    $error = $new->replace( $self, options => { $self->options } );
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error;
@@ -567,7 +571,7 @@ sub suspend {
     my %hash = $self->hash;
     $hash{'susp'} = time;
     my $new = new FS::cust_pkg ( \%hash );
-    $error = $new->replace($self);
+    $error = $new->replace( $self, options => { $self->options } );
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error;
@@ -648,7 +652,7 @@ sub unsuspend {
 
     $hash{'susp'} = '';
     my $new = new FS::cust_pkg ( \%hash );
-    $error = $new->replace($self);
+    $error = $new->replace( $self, options => { $self->options } );
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error;
@@ -689,7 +693,7 @@ sub last_reason {
   my $cust_pkg_reason = qsearchs( {
                                     'table' => 'cust_pkg_reason',
                                    'hashref' => { 'pkgnum' => $self->pkgnum, },
-                                   'extra_sql'=> 'ORDER BY date DESC',
+                                   'extra_sql'=> 'ORDER BY date DESC LIMIT 1',
                                  } );
   qsearchs ( 'reason', { 'reasonnum' => $cust_pkg_reason->reasonnum } )
     if $cust_pkg_reason;
@@ -795,6 +799,19 @@ sub cust_svc {
 
 }
 
+=item overlimit [ SVCPART ]
+
+Returns the services for this package which have exceeded their
+usage limit as FS::cust_svc objects (see L<FS::cust_svc>).  If a svcpart
+is specified, return only the matching services.
+
+=cut
+
+sub overlimit {
+  my $self = shift;
+  grep { $_->overlimit } $self->cust_svc;
+}
+
 =item h_cust_svc END_TIMESTAMP [ START_TIMESTAMP ] 
 
 Returns historical services for this package created before END TIMESTAMP and
@@ -898,7 +915,8 @@ sub part_svc {
     my $part_svc = $pkg_svc->part_svc;
     my $num_cust_svc = $self->num_cust_svc($part_svc->svcpart);
     $part_svc->{'Hash'}{'num_cust_svc'} = $num_cust_svc; #more evil
-    $part_svc->{'Hash'}{'num_avail'}    = $pkg_svc->quantity - $num_cust_svc;
+    $part_svc->{'Hash'}{'num_avail'}    =
+      max( 0, $pkg_svc->quantity - $num_cust_svc );
     $part_svc->{'Hash'}{'cust_pkg_svc'} = [ $self->cust_svc($part_svc->svcpart) ];
     $part_svc;
   } $self->part_pkg->pkg_svc;
@@ -1524,9 +1542,7 @@ sub order {
 sub insert_reason {
   my ($self, %options) = @_;
 
-  my $otaker = $FS::CurrentUser::CurrentUser->name;
-  $otaker = $FS::CurrentUser::CurrentUser->username
-    if (($otaker) eq "User, Legacy");
+  my $otaker = $FS::CurrentUser::CurrentUser->username;
 
   my $cust_pkg_reason =
     new FS::cust_pkg_reason({ 'pkgnum'    => $self->pkgnum,