RT# 83450 - fixed rateplan export
[freeside.git] / FS / FS / cust_bill_pkg_discount.pm
index e7dd5f2..2a638a9 100644 (file)
@@ -1,10 +1,8 @@
 package FS::cust_bill_pkg_discount;
+use base qw( FS::cust_main_Mixin FS::Record );
 
 use strict;
-use base qw( FS::cust_main_Mixin FS::Record );
-use FS::Record qw( qsearch qsearchs );
-use FS::cust_bill_pkg;
-use FS::cust_pkg_discount;
+use FS::Record qw( dbh );
 
 =head1 NAME
 
@@ -28,8 +26,8 @@ FS::cust_bill_pkg_discount - Object methods for cust_bill_pkg_discount records
 =head1 DESCRIPTION
 
 An FS::cust_bill_pkg_discount object represents the slice of a customer
-applied to a line item.  FS::cust_bill_pkg_discount inherits from
-FS::Record.  The following fields are currently supported:
+discount applied to a specific line item.  FS::cust_bill_pkg_discount inherits
+from FS::Record.  The following fields are currently supported:
 
 =over 4
 
@@ -125,24 +123,81 @@ sub check {
 
 Returns the associated line item (see L<FS::cust_bill_pkg>).
 
-=cut
-
-sub cust_bill_pkg {
-  my $self = shift;
-  qsearchs( 'cust_bill_pkg', { 'billpkgnum' => $self->billpkgnum } ) ;
-}
-
 =item cust_pkg_discount
 
 Returns the associated customer discount (see L<FS::cust_pkg_discount>).
 
+=item description
+
+Returns a string describing the discount (for use on an invoice).
+
 =cut
 
-sub cust_pkg_discount {
+sub description {
   my $self = shift;
-  qsearchs( 'cust_pkg_discount', { 'pkgdiscountnum' => $self->pkgdiscountnum });
+  my $discount = $self->cust_pkg_discount->discount;
+
+  if ( $self->months == 0 ) {
+    # then this is a setup discount
+    my $desc = $discount->name;
+    if ( $desc ) {
+      $desc .= ': ';
+    } else {
+      $desc = $self->mt('Setup discount of ');
+    }
+    if ( (my $percent = $discount->percent) > 0 ) {
+      $percent = sprintf('%.1f', $percent) if $percent > int($percent);
+      $percent =~ s/\.0+$//;
+      $desc .= $percent . '%';
+    } else {
+      # note "$self->amount", not $discount->amount. if a flat discount
+      # is applied to the setup fee, show the amount actually discounted.
+      # we might do this for all types of discounts.
+      my $money_char = FS::Conf->new->config('money_char') || '$';
+      $desc .= $money_char . sprintf('%.2f', $self->amount);
+    }
+  
+    # don't show "/month", months remaining or used, etc., as for setup
+    # discounts it doesn't matter.
+    return $desc;
+  }
+
+  my $desc = $discount->description_short;
+  $desc .= $self->mt(' each') if $self->cust_bill_pkg->quantity > 1;
+
+  if ( $discount->months and $self->months > 0 ) {
+    # calculate months remaining on this cust_pkg_discount after this invoice
+    my $date = $self->cust_bill_pkg->cust_bill->_date;
+    my $used = FS::Record->scalar_sql(
+      'SELECT SUM(months) FROM cust_bill_pkg_discount
+      JOIN cust_bill_pkg USING (billpkgnum)
+      JOIN cust_bill USING (invnum)
+      WHERE pkgdiscountnum = ? AND _date <= ?',
+      $self->pkgdiscountnum,
+      $date
+    );
+    $used ||= 0;
+    my $remaining = sprintf('%.2f', $discount->months - $used);
+    $desc .= $self->mt(' for [quant,_1,month] ([quant,_2,month] remaining)',
+              sprintf('%.2f', $self->months),
+              $remaining
+             );
+  }
+  return $desc;
 }
 
+sub _upgrade_schema {
+  my ($class, %opts) = @_;
+
+  my $sql = '
+    DELETE FROM cust_bill_pkg_discount WHERE NOT EXISTS
+      ( SELECT 1 FROM cust_bill_pkg WHERE cust_bill_pkg.billpkgnum = cust_bill_pkg_discount.billpkgnum )
+  ';
+
+  my $sth = dbh->prepare($sql) or die dbh->errstr;
+  $sth->execute or die $sth->errstr;
+  '';
+}
 
 =back