use Time::Local qw( timelocal timelocal_nocheck );
use MIME::Entity;
use FS::UID qw( dbh driver_name );
-use FS::Misc qw( send_email );
use FS::Record qw( qsearch qsearchs fields );
use FS::CurrentUser;
use FS::cust_svc;
# for modify_charge
use FS::cust_credit;
+# temporary fix; remove this once (un)suspend admin notices are cleaned up
+use FS::Misc qw(send_email);
+
# need to 'use' these instead of 'require' in sub { cancel, suspend, unsuspend,
# setup }
# because they load configuration by setting FS::UID::callback (see TODO)
}
}
- if ( $self->discountnum ) {
+ if ( $self->setup_discountnum || $self->recur_discountnum ) {
my $error = $self->insert_discount();
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
$error = $msg_template->send( 'cust_main' => $self->cust_main,
'object' => $self );
}
- else {
- $error = send_email(
- 'from' => $conf->invoice_from_full( $self->cust_main->agentnum ),
- 'to' => \@invoicing_list,
- 'subject' => ( $conf->config('cancelsubject') || 'Cancellation Notice' ),
- 'body' => [ map "$_\n", $conf->config('cancelmessage') ],
- 'custnum' => $self->custnum,
- 'msgtype' => '', #admin?
- );
- }
#should this do something on errors?
}
}
}
- # transfer usage pricing add-ons, if we're not changing pkgpart
- if ( $same_pkgpart ) {
- foreach my $old_cust_pkg_usageprice ($self->cust_pkg_usageprice) {
+ # transfer usage pricing add-ons, if we're not changing pkgpart or if they were specified
+ if ( $same_pkgpart || $opt->{'cust_pkg_usageprice'}) {
+ my @old_cust_pkg_usageprice;
+ if ($opt->{'cust_pkg_usageprice'}) {
+ @old_cust_pkg_usageprice = @{ $opt->{'cust_pkg_usageprice'} };
+ } else {
+ @old_cust_pkg_usageprice = $self->cust_pkg_usageprice;
+ }
+ foreach my $old_cust_pkg_usageprice (@old_cust_pkg_usageprice) {
my $new_cust_pkg_usageprice = new FS::cust_pkg_usageprice {
'pkgnum' => $cust_pkg->pkgnum,
'usagepricepart' => $old_cust_pkg_usageprice->usagepricepart,
package but not yet provisioned. Each FS::part_svc object also has an extra
field, I<num_avail>, which specifies the number of available services.
+Accepts option I<provision_hold>; if true, only returns part_svc for which the
+associated pkg_svc has the provision_hold flag set.
+
=cut
sub available_part_svc {
my $self = shift;
+ my %opt = @_;
my $pkg_quantity = $self->quantity || 1;
grep { $_->num_avail > 0 }
- map {
- my $part_svc = $_->part_svc;
- $part_svc->{'Hash'}{'num_avail'} = #evil encapsulation-breaking
- $pkg_quantity * $_->quantity - $self->num_cust_svc($_->svcpart);
-
- # more evil encapsulation breakage
- if($part_svc->{'Hash'}{'num_avail'} > 0) {
- my @exports = $part_svc->part_export_did;
- $part_svc->{'Hash'}{'can_get_dids'} = scalar(@exports);
- }
-
- $part_svc;
- }
- $self->part_pkg->pkg_svc;
+ map {
+ my $part_svc = $_->part_svc;
+ $part_svc->{'Hash'}{'num_avail'} = #evil encapsulation-breaking
+ $pkg_quantity * $_->quantity - $self->num_cust_svc($_->svcpart);
+
+ # more evil encapsulation breakage
+ if ($part_svc->{'Hash'}{'num_avail'} > 0) {
+ my @exports = $part_svc->part_export_did;
+ $part_svc->{'Hash'}{'can_get_dids'} = scalar(@exports);
+ }
+
+ $part_svc;
+ }
+ grep { $opt{'provision_hold'} ? $_->provision_hold : 1 }
+ $self->part_pkg->pkg_svc;
}
=item part_svc [ OPTION => VALUE ... ]
Associates this package with a discount (see L<FS::cust_pkg_discount>, possibly
inserting a new discount on the fly (see L<FS::discount>).
-Available options are:
-
-=over 4
-
-=item discountnum
-
-=back
+This will look at the cust_pkg for a pseudo-field named "setup_discountnum",
+and if present, will create a setup discount. If the discountnum is -1,
+a new discount definition will be inserted using the value in
+"setup_discountnum_amount" or "setup_discountnum_percent". Likewise for recur.
If there is an error, returns the error, otherwise returns false.
#my ($self, %options) = @_;
my $self = shift;
- my $cust_pkg_discount = new FS::cust_pkg_discount {
- 'pkgnum' => $self->pkgnum,
- 'discountnum' => $self->discountnum,
- 'months_used' => 0,
- 'end_date' => '', #XXX
- #for the create a new discount case
- '_type' => $self->discountnum__type,
- 'amount' => $self->discountnum_amount,
- 'percent' => $self->discountnum_percent,
- 'months' => $self->discountnum_months,
- 'setup' => $self->discountnum_setup,
- #'disabled' => $self->discountnum_disabled,
- };
+ foreach my $x (qw(setup recur)) {
+ if ( my $discountnum = $self->get("${x}_discountnum") ) {
+ my $cust_pkg_discount = FS::cust_pkg_discount->new( {
+ 'pkgnum' => $self->pkgnum,
+ 'discountnum' => $discountnum,
+ 'setuprecur' => $x,
+ 'months_used' => 0,
+ 'end_date' => '', #XXX
+ #for the create a new discount case
+ 'amount' => $self->get("${x}_discountnum_amount"),
+ 'percent' => $self->get("${x}_discountnum_percent"),
+ 'months' => $self->get("${x}_discountnum_months"),
+ } );
+ if ( $x eq 'setup' ) {
+ $cust_pkg_discount->setup('Y');
+ $cust_pkg_discount->months('');
+ }
+ my $error = $cust_pkg_discount->insert;
+ return $error if $error;
+ }
+ }
- $cust_pkg_discount->insert;
+ '';
}
=item set_usage USAGE_VALUE_HASHREF