freeside/FS/FS part_bill_event.pm,1.17,1.18 cust_bill_event.pm,1.10,1.11 cust_bill.pm,1.119,1.120 part_pkg.pm,1.39,1.40
Ivan Kohler
ivan at pouncequick.420.am
Thu Jun 2 02:30:30 PDT 2005
Update of /home/cvs/cvsroot/freeside/FS/FS
In directory pouncequick:/tmp/cvs-serv23604/FS/FS
Modified Files:
part_bill_event.pm cust_bill_event.pm cust_bill.pm part_pkg.pm
Log Message:
add ability to search on a date range of invoice events and then reprint or reemail (boy was that a bit more work than i expected), closes: Bug#946
Index: cust_bill_event.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill_event.pm,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- cust_bill_event.pm 5 Aug 2003 00:20:40 -0000 1.10
+++ cust_bill_event.pm 2 Jun 2005 09:29:52 -0000 1.11
@@ -1,13 +1,15 @@
package FS::cust_bill_event;
use strict;
-use vars qw( @ISA );
+use vars qw( @ISA $DEBUG );
use FS::Record qw( qsearch qsearchs );
use FS::cust_bill;
use FS::part_bill_event;
@ISA = qw(FS::Record);
+$DEBUG = 0;
+
=head1 NAME
FS::cust_bill_event - Object methods for cust_bill_event records
@@ -161,6 +163,98 @@
my $old = ref($self)->new( { $self->hash } );
$self->status('failed');
$self->replace($old);
+}
+
+=back
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item reprint
+
+=cut
+
+sub process_reprint {
+ process_re_X('print', @_);
+}
+
+=item reemail
+
+=cut
+
+sub process_reemail {
+ process_re_X('email', @_);
+}
+
+=item refax
+
+=cut
+
+sub process_refax {
+ process_re_X('fax', @_);
+}
+
+use Storable qw(thaw);
+use Data::Dumper;
+use MIME::Base64;
+sub process_re_X {
+ my( $method, $job ) = ( shift, shift );
+
+ my $param = thaw(decode_base64(shift));
+ warn Dumper($param) if $DEBUG;
+
+ re_X(
+ $method,
+ $param->{'beginning'},
+ $param->{'ending'},
+ $param->{'failed'},
+ $job,
+ );
+
+}
+
+sub re_X {
+ my($method, $beginning, $ending, $failed, $job) = @_;
+
+ my $where = " WHERE plan LIKE 'send%'".
+ " AND cust_bill_event._date >= $beginning".
+ " AND cust_bill_event._date <= $ending";
+ $where .= " AND statustext != '' AND statustext IS NOT NULL"
+ if $failed;
+
+ my $from = 'LEFT JOIN part_bill_event USING ( eventpart )';
+
+ my @cust_bill_event = qsearch( 'cust_bill_event', {}, '', $where, '', $from );
+
+ my( $num, $last, $min_sec ) = (0, time, 5); #progresbar foo
+ foreach my $cust_bill_event ( @cust_bill_event ) {
+
+ $cust_bill_event->cust_bill->$method(
+ $cust_bill_event->part_bill_event->templatename
+ );
+
+ if ( $job ) { #progressbar foo
+ $num++;
+ if ( time - $min_sec > $last ) {
+ my $error = $job->update_statustext(
+ int( 100 * $num / scalar(@cust_bill_event) )
+ );
+ die $error if $error;
+ $last = time;
+ }
+ }
+
+ }
+
+ #this doesn't work, but it would be nice
+ #if ( $job ) { #progressbar foo
+ # my $error = $job->update_statustext(
+ # scalar(@cust_bill_event). " invoices re-${method}ed"
+ # );
+ # die $error if $error;
+ #}
+
}
=back
Index: cust_bill.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill.pm,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -d -r1.119 -r1.120
--- cust_bill.pm 18 May 2005 10:43:59 -0000 1.119
+++ cust_bill.pm 2 Jun 2005 09:29:53 -0000 1.120
@@ -20,6 +20,9 @@
use FS::cust_credit_bill;
use FS::cust_pay_batch;
use FS::cust_bill_event;
+use FS::part_pkg;
+use FS::cust_bill_pay;
+use FS::part_bill_event;
@ISA = qw( FS::Record );
@@ -557,63 +560,121 @@
my $self = shift;
my $template = scalar(@_) ? shift : '';
return 'N/A' if scalar(@_) && $_[0] && $self->cust_main->agentnum != shift;
+
my $invoice_from =
scalar(@_)
? shift
: ( $self->_agent_invoice_from || $conf->config('invoice_from') );
- #my @print_text = $self->print_text('', $template);
my @invoicing_list = $self->cust_main->invoicing_list;
- if ( grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list or !@invoicing_list ) {
- #email
+ $self->send_email($template, $invoice_from)
+ if grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list or !@invoicing_list;
- #better to notify this person than silence
- @invoicing_list = ($invoice_from) unless @invoicing_list;
+ $self->send_print($template)
+ if grep { $_ eq 'POST' } @invoicing_list; #postal
- my $error = send_email(
- $self->generate_email(
- 'from' => $invoice_from,
- 'to' => [ grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ],
- #'print_text' => [ @print_text ],
- 'template' => $template,
- )
- );
- die "can't email invoice: $error\n" if $error;
- #die "$error\n" if $error;
+ $self->send_fax($template)
+ if grep { $_ eq 'FAX' } @invoicing_list; #fax
- }
+ '';
- if ( grep { $_ =~ /^(POST|FAX)$/ } @invoicing_list ) {
- my $lpr_data;
- if ($conf->config('invoice_latex')) {
- $lpr_data = [ $self->print_ps('', $template) ];
- } else {
- $lpr_data = [ $self->print_text('', $template) ];
- }
+}
- if ( grep { $_ eq 'POST' } @invoicing_list ) { #postal
- my $lpr = $conf->config('lpr');
- open(LPR, "|$lpr")
- or die "Can't open pipe to $lpr: $!\n";
- print LPR @{$lpr_data};
- close LPR
- or die $! ? "Error closing $lpr: $!\n"
- : "Exit status $? from $lpr\n";
- }
+=item email [ TEMPLATENAME [ , INVOICE_FROM ] ]
- if ( grep { $_ eq 'FAX' } @invoicing_list ) { #fax
- die 'FAX invoice destination not supported with plain text invoices.'
- unless $conf->exists('invoice_latex');
- my $dialstring = $self->cust_main->getfield('fax');
- #Check $dialstring?
- my $error = send_fax(docdata => $lpr_data, dialstring => $dialstring);
- die $error if $error;
- }
+Emails this invoice.
- }
+TEMPLATENAME, if specified, is the name of a suffix for alternate invoices.
- '';
+INVOICE_FROM, if specified, overrides the default email invoice From: address.
+
+=cut
+
+sub email {
+ my $self = shift;
+ my $template = scalar(@_) ? shift : '';
+ my $invoice_from =
+ scalar(@_)
+ ? shift
+ : ( $self->_agent_invoice_from || $conf->config('invoice_from') );
+
+ my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ }
+ $self->cust_main->invoicing_list;
+
+ #better to notify this person than silence
+ @invoicing_list = ($invoice_from) unless @invoicing_list;
+
+ my $error = send_email(
+ $self->generate_email(
+ 'from' => $invoice_from,
+ 'to' => [ grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ],
+ 'template' => $template,
+ )
+ );
+ die "can't email invoice: $error\n" if $error;
+ #die "$error\n" if $error;
+
+}
+
+=item lpr_data [ TEMPLATENAME ]
+
+Returns the postscript or plaintext for this invoice.
+
+TEMPLATENAME, if specified, is the name of a suffix for alternate invoices.
+
+=cut
+
+sub lpr_data {
+ my( $self, $template) = @_;
+ $conf->exists('invoice_latex')
+ ? [ $self->print_ps('', $template) ]
+ : [ $self->print_text('', $template) ];
+}
+
+=item print [ TEMPLATENAME ]
+
+Prints this invoice.
+
+TEMPLATENAME, if specified, is the name of a suffix for alternate invoices.
+
+=cut
+
+sub print {
+ my $self = shift;
+ my $template = scalar(@_) ? shift : '';
+
+ my $lpr = $conf->config('lpr');
+ open(LPR, "|$lpr")
+ or die "Can't open pipe to $lpr: $!\n";
+ print LPR @{ $self->lpr_data($template) };
+ close LPR
+ or die $! ? "Error closing $lpr: $!\n"
+ : "Exit status $? from $lpr\n";
+}
+
+=item fax [ TEMPLATENAME ]
+
+Faxes this invoice.
+
+TEMPLATENAME, if specified, is the name of a suffix for alternate invoices.
+
+=cut
+
+sub fax {
+ my $self = shift;
+ my $template = scalar(@_) ? shift : '';
+
+ die 'FAX invoice destination not (yet?) supported with plain text invoices.'
+ unless $conf->exists('invoice_latex');
+
+ my $dialstring = $self->cust_main->getfield('fax');
+ #Check $dialstring?
+
+ my $error = send_fax( 'docdata' => $self->lpr_data($template),
+ 'dialstring' => $dialstring,
+ );
+ die $error if $error;
}
@@ -1024,7 +1085,7 @@
( grep { ! $_->pkgnum } $self->cust_bill_pkg ), #then taxes
) {
- if ( $cust_bill_pkg->pkgnum ) {
+ if ( $cust_bill_pkg->pkgnum > 0 ) {
my $cust_pkg = qsearchs('cust_pkg', { pkgnum =>$cust_bill_pkg->pkgnum } );
my $part_pkg = qsearchs('part_pkg', { pkgpart=>$cust_pkg->pkgpart } );
@@ -1919,7 +1980,7 @@
my @b = ();
foreach my $cust_bill_pkg ( @$cust_bill_pkg ) {
- if ( $cust_bill_pkg->pkgnum ) {
+ if ( $cust_bill_pkg->pkgnum > 0 ) {
my $cust_pkg = qsearchs('cust_pkg', { pkgnum =>$cust_bill_pkg->pkgnum } );
my $part_pkg = qsearchs('part_pkg', { pkgpart=>$cust_pkg->pkgpart } );
Index: part_pkg.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/part_pkg.pm,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- part_pkg.pm 4 May 2005 09:33:09 -0000 1.39
+++ part_pkg.pm 2 Jun 2005 09:29:53 -0000 1.40
@@ -2,7 +2,7 @@
use strict;
use vars qw( @ISA %freq %plans $DEBUG );
-use Carp qw(carp cluck);
+use Carp qw(carp cluck confess);
use Tie::IxHash;
use FS::Conf;
use FS::Record qw( qsearch qsearchs dbh dbdef );
@@ -643,9 +643,15 @@
sub _rebless {
my $self = shift;
my $plan = $self->plan;
+ unless ( $plan ) {
+ confess "no price plan found for pkgpart ". $self->pkgpart. "\n"
+ if $DEBUG;
+ return $self;
+ }
my $class = ref($self). "::$plan";
+ warn "reblessing $self into $class" if $DEBUG;
eval "use $class;";
- #die $@ if $@;
+ die $@ if $@;
bless($self, $class) unless $@;
$self;
}
@@ -697,6 +703,7 @@
my %info;
foreach my $INC ( @INC ) {
+ warn "globbing $INC/FS/part_pkg/*.pm\n" if $DEBUG;
foreach my $file ( glob("$INC/FS/part_pkg/*.pm") ) {
warn "attempting to load plan info from $file\n" if $DEBUG;
$file =~ /\/(\w+)\.pm$/ or do {
Index: part_bill_event.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/part_bill_event.pm,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- part_bill_event.pm 14 May 2005 16:27:26 -0000 1.17
+++ part_bill_event.pm 2 Jun 2005 09:29:52 -0000 1.18
@@ -171,11 +171,32 @@
$self->SUPER::check;
}
+=item templatename
+
+Returns the alternate invoice template name, if any, or false if there is
+no alternate template for this invoice event.
+
+=cut
+
+sub templatename {
+ my $self = shift;
+ if ( $self->plan =~ /^send_(alternate|agent)$/
+ && $self->plandata =~ /^(agent_)?templatename (.*)$/m
+ )
+ {
+ $2;
+ } else {
+ '';
+ }
+}
+
+
=back
=head1 BUGS
-Alas.
+The whole "eventcode" idea is bunk. This should be refactored with subclasses
+like part_pkg/ and part_export/
=head1 SEE ALSO
More information about the freeside-commits
mailing list