+=item cust_pkg
+
+Returns the customer package (see L<FS::cust_pkg>).
+
+=cut
+
+sub cust_pkg {
+ my $self = shift;
+ qsearchs('cust_pkg', { 'pkgnum' => $self->pkgnum } );
+}
+
+=item discount
+
+Returns the discount (see L<FS::discount>).
+
+=cut
+
+sub discount {
+ my $self = shift;
+ qsearchs('discount', { 'discountnum' => $self->discountnum } );
+}
+
+=item increment_months_used MONTHS
+
+Increments months_used by the given parameter
+
+=cut
+
+sub increment_months_used {
+ my( $self, $used ) = @_;
+ #UPDATE cust_pkg_discount SET months_used = months_used + ?
+ #leaves no history, and billing is mutexed per-customer, so the dum way is ok
+ $self->months_used( $self->months_used + $used );
+ $self->replace();
+}
+
+=item decrement_months_used MONTHS
+
+Decrement months_used by the given parameter
+
+(Note: as in, extending the length of the discount. Typically only used to
+stack/extend a discount when the customer package has one active already.)
+
+=cut
+
+sub decrement_months_used {
+ my( $self, $recharged ) = @_;
+ #UPDATE cust_pkg_discount SET months_used = months_used - ?
+ #leaves no history, and billing is mutexed per-customer
+
+ #we're run from part_event/Action/referral_pkg_discount on behalf of a
+ # different customer, so we need to grab this customer's mutex.
+ # incidentally, that's some inelegant encapsulation breaking shit, and a
+ # great argument in favor of native-DB trigger history so we can trust
+ # in normal ACID like the SQL above instead of this
+ $self->cust_pkg->cust_main->select_for_update;
+
+ $self->months_used( $self->months_used - $recharged );
+ $self->replace();
+}
+
+=item status
+
+=cut
+
+sub status {
+ my $self = shift;
+ my $discount = $self->discount;
+
+ if ( $self->disabled ne 'Y'
+ and ( ! $discount->months || $self->months_used < $discount->months )
+ #XXX also end date
+ ) {
+ 'active';
+ } else {
+ 'expired';
+ }
+}
+
+# Used by FS::Upgrade to migrate to a new database.
+sub _upgrade_data { # class method
+ my ($class, %opts) = @_;
+ $class->_upgrade_otaker(%opts);
+}
+