summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorivan <ivan>2008-10-29 08:03:08 +0000
committerivan <ivan>2008-10-29 08:03:08 +0000
commit9e992baf49d7ac4372fd9dab88f41731f04e53b8 (patch)
tree26fe882a5ea8a0f8f0a85ebe4dc3fb9ddebb395c /FS
parentbd4151f99f8a2249977e65947cc8762ec50166e2 (diff)
prepaid cdr pickup & bill daemon, RT#4184
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/cust_main.pm76
-rw-r--r--FS/FS/part_pkg/voip_cdr.pm6
-rw-r--r--FS/bin/freeside-cdrd112
3 files changed, 160 insertions, 34 deletions
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index aa97d2233..db70dacc6 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -2399,9 +2399,13 @@ sub _make_lines {
my $recur = 0;
my $unitrecur = 0;
my $sdate;
- if ( $part_pkg->getfield('freq') ne '0' &&
- ! $cust_pkg->getfield('susp') &&
- ( $cust_pkg->getfield('bill') || 0 ) <= $time
+ if ( ! $cust_pkg->getfield('susp') and
+ ( $part_pkg->getfield('freq') ne '0' &&
+ ( $cust_pkg->getfield('bill') || 0 ) <= $time
+ )
+ || ( $part_pkg->plan eq 'voip_cdr'
+ && $part_pkg->option('bill_every_call')
+ )
) {
# XXX should this be a package event? probably. events are called
@@ -2418,42 +2422,50 @@ sub _make_lines {
$sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
#over two params! lets at least switch to a hashref for the rest...
- my %param = ( 'precommit_hooks' => $precommit_hooks, );
+ my $increment_next_bill = ( $part_pkg->freq ne '0'
+ && ( $cust_pkg->getfield('bill') || 0 ) <= $time
+ );
+ my %param = ( 'precommit_hooks' => $precommit_hooks,
+ 'increment_next_bill' => $increment_next_bill,
+ );
$recur = eval { $cust_pkg->calc_recur( \$sdate, \@details, \%param ) };
return "$@ running calc_recur for $cust_pkg\n"
if ( $@ );
+ if ( $increment_next_bill ) {
- #change this bit to use Date::Manip? CAREFUL with timezones (see
- # mailing list archive)
- my ($sec,$min,$hour,$mday,$mon,$year) =
- (localtime($sdate) )[0,1,2,3,4,5];
-
- #pro-rating magic - if $recur_prog fiddles $sdate, want to use that
- # only for figuring next bill date, nothing else, so, reset $sdate again
- # here
- $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
- #no need, its in $hash{last_bill}# my $last_bill = $cust_pkg->last_bill;
- $cust_pkg->last_bill($sdate);
-
- if ( $part_pkg->freq =~ /^\d+$/ ) {
- $mon += $part_pkg->freq;
- until ( $mon < 12 ) { $mon -= 12; $year++; }
- } elsif ( $part_pkg->freq =~ /^(\d+)w$/ ) {
- my $weeks = $1;
- $mday += $weeks * 7;
- } elsif ( $part_pkg->freq =~ /^(\d+)d$/ ) {
- my $days = $1;
- $mday += $days;
- } elsif ( $part_pkg->freq =~ /^(\d+)h$/ ) {
- my $hours = $1;
- $hour += $hours;
- } else {
- return "unparsable frequency: ". $part_pkg->freq;
+ #change this bit to use Date::Manip? CAREFUL with timezones (see
+ # mailing list archive)
+ my ($sec,$min,$hour,$mday,$mon,$year) =
+ (localtime($sdate) )[0,1,2,3,4,5];
+
+ #pro-rating magic - if $recur_prog fiddles $sdate, want to use that
+ # only for figuring next bill date, nothing else, so, reset $sdate again
+ # here
+ $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
+ #no need, its in $hash{last_bill}# my $last_bill = $cust_pkg->last_bill;
+ $cust_pkg->last_bill($sdate);
+
+ if ( $part_pkg->freq =~ /^\d+$/ ) {
+ $mon += $part_pkg->freq;
+ until ( $mon < 12 ) { $mon -= 12; $year++; }
+ } elsif ( $part_pkg->freq =~ /^(\d+)w$/ ) {
+ my $weeks = $1;
+ $mday += $weeks * 7;
+ } elsif ( $part_pkg->freq =~ /^(\d+)d$/ ) {
+ my $days = $1;
+ $mday += $days;
+ } elsif ( $part_pkg->freq =~ /^(\d+)h$/ ) {
+ my $hours = $1;
+ $hour += $hours;
+ } else {
+ return "unparsable frequency: ". $part_pkg->freq;
+ }
+ $cust_pkg->setfield('bill',
+ timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
+
}
- $cust_pkg->setfield('bill',
- timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
}
diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm
index 1b565f2c4..a3b54ee84 100644
--- a/FS/FS/part_pkg/voip_cdr.pm
+++ b/FS/FS/part_pkg/voip_cdr.pm
@@ -395,7 +395,7 @@ sub calc_recur {
# don't add it to invoice, don't set its status to NULL,
# don't call downstream_csv or something on it...
# but DO emit a warning...
- #if ( ! $rate_detail && ! scalar(@call_details) ) {
+ #if ( ! $rate_detail && ! scalar(@call_details) ) {}
if ( ! $rate_detail && $charge eq '' ) {
warn "no rate_detail found for CDR.acctid: ". $cdr->acctid.
@@ -509,8 +509,10 @@ sub calc_recur {
} #if ( $spool_cdr && length($downstream_cdr) )
- $self->option('recur_fee') + $charges;
+ $charges += $self->option('recur_fee')
+ if $param->{'increment_next_bill'};
+ $charges;
}
sub is_free {
diff --git a/FS/bin/freeside-cdrd b/FS/bin/freeside-cdrd
new file mode 100644
index 000000000..ef420b53b
--- /dev/null
+++ b/FS/bin/freeside-cdrd
@@ -0,0 +1,112 @@
+#!/usr/bin/perl -w
+
+use strict;
+use FS::Daemon qw(daemonize1 drop_root logfile daemonize2 sigint sigterm);
+use FS::UID qw(adminsuidsetup);
+use FS::Record qw(qsearch ); #qsearchs);
+#use FS::cdr;
+use FS::cust_pkg;
+
+my $user = shift or die &usage;
+
+#daemonize1('freeside-sprepaidd', $user); #keep unique pid files w/multi installs
+daemonize1('freeside-cdrd');
+
+drop_root();
+
+adminsuidsetup($user);
+
+logfile( "%%%FREESIDE_LOG%%%/cdrd-log.". $FS::UID::datasrc );
+
+daemonize2();
+
+#--
+
+my $addl_from =
+ 'LEFT JOIN part_pkg USING ( pkgpart ) '.
+ "LEFT JOIN part_pkg_option
+ ON ( cust_pkg.pkgpart = part_pkg_option.pkgpart
+ AND part_pkg_option.optionname = 'bill_every_call' )";
+
+#XXX should pay attention to disable_src for efficiency
+
+my $extra_sql =
+ "WHERE plan = 'voip_cdr' ".
+ " AND optionvalue = '1' ".
+ " AND ( susp IS NULL OR susp = 0)".
+ " AND ( cancel IS NULL OR cancel = 0)".
+ " AND 0 < (
+ SELECT COUNT(*) FROM svc_phone LEFT JOIN cust_svc USING (svcnum)
+ WHERE cust_pkg.pkgnum = cust_svc.pkgnum
+ AND 0 < ( SELECT COUNT(*) FROM cdr
+ WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
+ AND ( charged_party = svc_phone.phonenum
+ OR charged_party = svc_phone.countrycode
+ || svc_phone.phonenum
+ OR src = svc_phone.phonenum
+ OR src = svc_phone.countrycode
+ || svc_phone.phonenum
+ )
+ )
+ )
+ ";
+
+while (1) {
+
+ my $found = 0;
+ foreach my $cust_pkg (
+ qsearch( {
+ 'select' => 'cust_pkg.*, part_pkg.plan',
+ 'table' => 'cust_pkg',
+ 'addl_from' => $addl_from,
+ 'hashref' => {},
+ 'extra_sql' => $extra_sql,
+ } )
+ ) {
+
+ $found = 1;
+
+ my $work_cust_pkg = $cust_pkg;
+
+ my $cust_main = $cust_pkg->cust_main;
+
+ my $time = time;
+ $cust_main->bill_and_collect(
+ 'time' => $time,
+ 'invoice_time' => $time,
+ 'actual_time' => $time,
+ 'check_freq' => '1d', #well
+ #'debug' => 1,
+ );
+
+ }
+
+ die "exiting" if sigterm() || sigint();
+ sleep 5; # unless $found;
+
+}
+
+#--
+
+sub usage {
+ die "Usage:\n\n freeside-prepaidd user\n";
+}
+
+=head1 NAME
+
+freeside-prepaidd - Real-time daemon for prepaid packages
+
+=head1 SYNOPSIS
+
+ freeside-prepaidd
+
+=head1 DESCRIPTION
+
+Runs continuously and suspends or cancels any prepaid customer packages which
+have passed their renewal date (next bill date).
+
+=head1 SEE ALSO
+
+=cut
+
+1;