},
);
+# takes the reason class (C, R, S) as an argument
+sub reason_type_options {
+ my $reason_class = shift;
+
+ 'type' => 'select-sub',
+ 'options_sub' => sub {
+ map { $_->typenum => $_->type }
+ qsearch('reason_type', { class => $reason_class });
+ },
+ 'option_sub' => sub {
+ my $type = FS::reason_type->by_key(shift);
+ $type ? $type->type : '';
+ }
+}
+
#Billing (81 items)
#Invoicing (50 items)
#UI (69 items)
'key' => 'cancel_credit_type',
'section' => 'billing',
'description' => 'The group to use for new, automatically generated credit reasons resulting from cancellation.',
- 'type' => 'select-sub',
- 'options_sub' => sub { require FS::Record;
- require FS::reason_type;
- map { $_->typenum => $_->type }
- FS::Record::qsearch('reason_type', { class=>'R' } );
- },
- 'option_sub' => sub { require FS::Record;
- require FS::reason_type;
- my $reason_type = FS::Record::qsearchs(
- 'reason_type', { 'typenum' => shift }
- );
- $reason_type ? $reason_type->type : '';
- },
+ reason_type_options('R'),
+ },
+
+ {
+ 'key' => 'suspend_credit_type',
+ 'section' => 'billing',
+ 'description' => 'The group to use for new, automatically generated credit reasons resulting from package suspension.',
+ reason_type_options('R'),
},
{
'key' => 'referral_credit_type',
'section' => 'deprecated',
'description' => 'Used to be the group to use for new, automatically generated credit reasons resulting from referrals. Now set in a package billing event for the referral.',
- 'type' => 'select-sub',
- 'options_sub' => sub { require FS::Record;
- require FS::reason_type;
- map { $_->typenum => $_->type }
- FS::Record::qsearch('reason_type', { class=>'R' } );
- },
- 'option_sub' => sub { require FS::Record;
- require FS::reason_type;
- my $reason_type = FS::Record::qsearchs(
- 'reason_type', { 'typenum' => shift }
- );
- $reason_type ? $reason_type->type : '';
- },
+ reason_type_options('R'),
},
{
'key' => 'signup_credit_type',
'section' => 'billing', #self-service?
'description' => 'The group to use for new, automatically generated credit reasons resulting from signup and self-service declines.',
- 'type' => 'select-sub',
- 'options_sub' => sub { require FS::Record;
- require FS::reason_type;
- map { $_->typenum => $_->type }
- FS::Record::qsearch('reason_type', { class=>'R' } );
- },
- 'option_sub' => sub { require FS::Record;
- require FS::reason_type;
- my $reason_type = FS::Record::qsearchs(
- 'reason_type', { 'typenum' => shift }
- );
- $reason_type ? $reason_type->type : '';
- },
+ reason_type_options('R'),
},
{
'key' => 'prepayment_discounts-credit_type',
'section' => 'billing',
'description' => 'Enables the offering of prepayment discounts and establishes the credit reason type.',
- 'type' => 'select-sub',
- 'options_sub' => sub { require FS::Record;
- require FS::reason_type;
- map { $_->typenum => $_->type }
- FS::Record::qsearch('reason_type', { class=>'R' } );
- },
- 'option_sub' => sub { require FS::Record;
- require FS::reason_type;
- my $reason_type = FS::Record::qsearchs(
- 'reason_type', { 'typenum' => shift }
- );
- $reason_type ? $reason_type->type : '';
- },
-
+ reason_type_options('R'),
},
{
$do_credit = $self->part_pkg->option('unused_credit_cancel', 1);
}
if ( $do_credit ) {
- my $error = $self->credit_remaining($cancel_time);
+ my $error = $self->credit_remaining('cancel', $cancel_time);
if ($error) {
$dbh->rollback if $oldAutoCommit;
return $error;
unless ( $date ) {
# credit remaining time if appropriate
if ( $self->part_pkg->option('unused_credit_suspend', 1) ) {
- my $error = $self->credit_remaining($suspend_time);
+ my $error = $self->credit_remaining('suspend', $suspend_time);
if ($error) {
$dbh->rollback if $oldAutoCommit;
return $error;
''; #no errors
}
+=item credit_remaining MODE TIME
+
+Generate a credit for this package for the time remaining in the current
+billing period. MODE is either "suspend" or "cancel" (determines the
+credit type). TIME is the time of suspension/cancellation. Both options
+are mandatory.
+
+=cut
+
sub credit_remaining {
# Add a credit for remaining service
- my $self = shift;
- my $time = shift or die 'no suspend/cancel time';
+ my ($self, $mode, $time) = @_;
+ die 'credit_remaining requires suspend or cancel'
+ unless $mode eq 'suspend' or $mode eq 'cancel';
+ die 'no suspend/cancel time' unless $time > 0;
+
my $conf = FS::Conf->new;
+ my $reason_type = $conf->config($mode.'_credit_type');
+
my $last_bill = $self->getfield('last_bill') || 0;
my $next_bill = $self->getfield('bill') || 0;
if ( $last_bill > 0 # the package has been billed
my $error = $self->cust_main->credit(
$remaining_value,
'Credit for unused time on '. $self->part_pkg->pkg,
- 'reason_type' => $conf->config('cancel_credit_type'),
- ); # need 'suspend_credit_type'?
+ 'reason_type' => $reason_type,
+ );
return "Error crediting customer \$$remaining_value for unused time".
" on ". $self->part_pkg->pkg. ": $error"
if $error;