sub all_pkgs {
my $self = shift;
+
+ return $self->num_pkgs unless wantarray;
+
+ my @cust_pkg = ();
if ( $self->{'_pkgnum'} ) {
- values %{ $self->{'_pkgnum'}->cache };
+ @cust_pkg = values %{ $self->{'_pkgnum'}->cache };
} else {
- qsearch( 'cust_pkg', { 'custnum' => $self->custnum });
+ @cust_pkg = qsearch( 'cust_pkg', { 'custnum' => $self->custnum });
}
+
+ sort sort_packages @cust_pkg;
}
=item ncancelled_pkgs
sub ncancelled_pkgs {
my $self = shift;
+
+ return $self->num_ncancelled_pkgs unless wantarray;
+
+ my @cust_pkg = ();
if ( $self->{'_pkgnum'} ) {
- grep { ! $_->getfield('cancel') } values %{ $self->{'_pkgnum'}->cache };
+
+ @cust_pkg = grep { ! $_->getfield('cancel') }
+ values %{ $self->{'_pkgnum'}->cache };
+
} else {
- @{ [ # force list context
+
+ @cust_pkg =
qsearch( 'cust_pkg', {
- 'custnum' => $self->custnum,
- 'cancel' => '',
- }),
+ 'custnum' => $self->custnum,
+ 'cancel' => '',
+ });
+ push @cust_pkg,
qsearch( 'cust_pkg', {
- 'custnum' => $self->custnum,
- 'cancel' => 0,
- }),
- ] };
+ 'custnum' => $self->custnum,
+ 'cancel' => 0,
+ });
+ }
+
+ sort sort_packages @cust_pkg;
+
+}
+
+# This should be generalized to use config options to determine order.
+sub sort_packages {
+ if ( $a->get('cancel') and $b->get('cancel') ) {
+ $a->pkgnum <=> $b->pkgnum;
+ } elsif ( $a->get('cancel') or $b->get('cancel') ) {
+ return -1 if $b->get('cancel');
+ return 1 if $a->get('cancel');
+ return 0;
+ } else {
+ $a->pkgnum <=> $b->pkgnum;
}
}
=cut
sub num_cancelled_pkgs {
- my $self = shift;
- $self->num_pkgs("cancel IS NOT NULL AND cust_pkg.cancel != 0");
+ shift->num_pkgs("cust_pkg.cancel IS NOT NULL AND cust_pkg.cancel != 0");
+}
+
+sub num_ncancelled_pkgs {
+ shift->num_pkgs("( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )");
}
sub num_pkgs {
my( $self, $sql ) = @_;
+ $sql = "AND $sql" if $sql && $sql !~ /^\s*$/ && $sql !~ /^\s*AND/i;
my $sth = dbh->prepare(
- "SELECT COUNT(*) FROM cust_pkg WHERE custnum = ? AND $sql"
+ "SELECT COUNT(*) FROM cust_pkg WHERE custnum = ? $sql"
) or die dbh->errstr;
$sth->execute($self->custnum) or die $sth->errstr;
$sth->fetchrow_arrayref->[0];
{
'payby' => $payby2ban{$self->payby},
'payinfo' => md5_base64($self->payinfo),
- #'reason' =>
+ #don't ever *search* on reason! #'reason' =>
};
}
warn " bill setup\n" if $DEBUG > 1;
- $setup = eval { $cust_pkg->calc_setup( $time ) };
+ $setup = eval { $cust_pkg->calc_setup( $time, \@details ) };
if ( $@ ) {
$dbh->rollback if $oldAutoCommit;
return "$@ running calc_setup for $cust_pkg\n";
=cut
sub charge {
- my ( $self, $amount ) = ( shift, shift );
- my $pkg = @_ ? shift : 'One-time charge';
- my $comment = @_ ? shift : '$'. sprintf("%.2f",$amount);
- my $taxclass = @_ ? shift : '';
+ my $self = shift;
+ my ( $amount, $pkg, $comment, $taxclass, $additional );
+ if ( ref( $_[0] ) ) {
+ $amount = $_[0]->{amount};
+ $pkg = exists($_[0]->{pkg}) ? $_[0]->{pkg} : 'One-time charge';
+ $comment = exists($_[0]->{comment}) ? $_[0]->{comment}
+ : '$'. sprintf("%.2f",$amount);
+ $taxclass = exists($_[0]->{taxclass}) ? $_[0]->{taxclass} : '';
+ $additional = $_[0]->{additional};
+ }else{
+ $amount = shift;
+ $pkg = @_ ? shift : 'One-time charge';
+ $comment = @_ ? shift : '$'. sprintf("%.2f",$amount);
+ $taxclass = @_ ? shift : '';
+ $additional = [];
+ }
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
my $part_pkg = new FS::part_pkg ( {
'pkg' => $pkg,
'comment' => $comment,
- #'setup' => $amount,
- #'recur' => '0',
'plan' => 'flat',
- 'plandata' => "setup_fee=$amount",
'freq' => 0,
'disabled' => 'Y',
'taxclass' => $taxclass,
} );
- my $error = $part_pkg->insert;
+ my %options = ( ( map { ("additional_info$_" => $additional->[$_] ) }
+ ( 0 .. @$additional - 1 )
+ ),
+ 'additional_count' => scalar(@$additional),
+ 'setup_fee' => $amount,
+ );
+
+ my $error = $part_pkg->insert( options => \%options );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;