summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan>2005-06-02 09:29:56 +0000
committerivan <ivan>2005-06-02 09:29:56 +0000
commit684a478c0f88e5bf6d1d3f32f4618089146b5709 (patch)
tree1f0c8e23048aa20e872ff10f07a134436968ac43
parent14cc10e34e277f4761be76d67d621b5a5d10a87f (diff)
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
-rw-r--r--FS/FS/UI/Web.pm13
-rw-r--r--FS/FS/cust_bill.pm149
-rw-r--r--FS/FS/cust_bill_event.pm96
-rw-r--r--FS/FS/part_bill_event.pm23
-rw-r--r--FS/FS/part_pkg.pm11
-rw-r--r--FS/bin/freeside-queued2
-rw-r--r--htetc/global.asa1
-rw-r--r--htetc/handler.pl1
-rw-r--r--httemplate/elements/progress-init.html12
-rw-r--r--httemplate/elements/progress-popup.html11
-rw-r--r--httemplate/index.html6
-rwxr-xr-xhttemplate/misc/email-invoice.cgi12
-rw-r--r--httemplate/misc/email_invoices.cgi6
-rwxr-xr-xhttemplate/misc/fax-invoice.cgi10
-rw-r--r--httemplate/misc/fax_invoices.cgi6
-rwxr-xr-xhttemplate/misc/print-invoice.cgi15
-rw-r--r--httemplate/misc/print_invoices.cgi6
-rw-r--r--httemplate/search/cust_bill_event.cgi166
-rwxr-xr-xhttemplate/search/cust_bill_event.html18
-rw-r--r--httemplate/search/elements/search.html1
-rwxr-xr-xhttemplate/view/cust_bill.cgi7
21 files changed, 421 insertions, 151 deletions
diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm
index 46e904b00..e701141ec 100644
--- a/FS/FS/UI/Web.pm
+++ b/FS/FS/UI/Web.pm
@@ -4,6 +4,19 @@ package FS::UI::Web;
#use FS::UI
#@ISA = qw( FS::UI );
+use Date::Parse;
+sub parse_beginning_ending {
+ my($cgi) = @_;
+
+ $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/;
+ my $beginning = str2time($1) || 0;
+
+ #need an option to turn off the + 86399 ???
+ $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/;
+ my $ending = ( $1 ? str2time($1) : 4294880896 ) + 86399;
+
+ ( $beginning, $ending );
+}
# begin JSRPC code...
diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm
index 2c25c6ff2..888687e68 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -20,6 +20,9 @@ use FS::cust_pkg;
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 @@ sub send {
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 @@ sub print_text {
( 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 @@ sub _items_cust_bill_pkg {
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 } );
diff --git a/FS/FS/cust_bill_event.pm b/FS/FS/cust_bill_event.pm
index ddd676281..7b981391e 100644
--- a/FS/FS/cust_bill_event.pm
+++ b/FS/FS/cust_bill_event.pm
@@ -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
@@ -165,6 +167,98 @@ sub retry {
=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
+
=head1 BUGS
Far too early in the morning.
diff --git a/FS/FS/part_bill_event.pm b/FS/FS/part_bill_event.pm
index b7c8b6a2d..0d03ebf29 100644
--- a/FS/FS/part_bill_event.pm
+++ b/FS/FS/part_bill_event.pm
@@ -171,11 +171,32 @@ sub check {
$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
diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm
index bf040c8e5..f9b36e2ec 100644
--- a/FS/FS/part_pkg.pm
+++ b/FS/FS/part_pkg.pm
@@ -2,7 +2,7 @@ package FS::part_pkg;
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 @@ on how to create new price plans, but until then, see L</NEW PLAN CLASSES>.
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 @@ sub calc_cancel { 0; }
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 {
diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued
index b9ef09cd1..3a0a9b4e5 100644
--- a/FS/bin/freeside-queued
+++ b/FS/bin/freeside-queued
@@ -186,7 +186,7 @@ while (1) {
}
my $eval = "&". $ljob->job. '(@args);';
- warn "running $eval";
+ warn 'running "&'. $ljob->job. '('. join(', ', @args). ")\n" if $DEBUG;
eval $eval; #throw away return value? suppose so
if ( $@ ) {
warn "job $eval failed";
diff --git a/htetc/global.asa b/htetc/global.asa
index 3781f947d..39ec898de 100644
--- a/htetc/global.asa
+++ b/htetc/global.asa
@@ -12,6 +12,7 @@ use Date::Parse;
use Time::Local;
use Time::Duration;
use Tie::IxHash;
+use URI::Escape;
use HTML::Entities;
use IO::Handle;
use IO::File;
diff --git a/htetc/handler.pl b/htetc/handler.pl
index b44e3f2d4..ad671d6c7 100644
--- a/htetc/handler.pl
+++ b/htetc/handler.pl
@@ -95,6 +95,7 @@ sub handler
use Time::Local;
use Time::Duration;
use Tie::IxHash;
+ use URI::Escape;
use HTML::Entities;
use IO::Handle;
use IO::File;
diff --git a/httemplate/elements/progress-init.html b/httemplate/elements/progress-init.html
index 41feaac4b..a8268c12c 100644
--- a/httemplate/elements/progress-init.html
+++ b/httemplate/elements/progress-init.html
@@ -1,6 +1,14 @@
<%
- my( $formname, $fields, $action, $success_url, $key ) = @_;
+ my( $formname, $fields, $action, $url_or_message, $key ) = @_;
$key = '' unless defined $key;
+
+ my $url_or_message_link;
+ if ( ref($url_or_message) ) { #its a message or something
+ $url_or_message_link =
+ 'message='. uri_escape( $url_or_message->{'message'} )
+ } else {
+ $url_or_message_link = "url=$url_or_message";
+ }
%>
<SCRIPT TYPE="text/javascript" SRC="../elements/jsrsClient.js"></SCRIPT>
@@ -52,7 +60,7 @@ function <%=$key%>process () {
function <%=$key%>myCallback( jobnum ) {
- overlib( OLiframeContent('<%=$p%>elements/progress-popup.html?jobnum=' + jobnum + ';url=<%=$success_url%>;formname=<%=$formname%>' , 432, 136, 'progress_popup'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 );
+ overlib( OLiframeContent('<%=$p%>elements/progress-popup.html?jobnum=' + jobnum + ';<%=$url_or_message_link%>;formname=<%=$formname%>' , 432, 136, 'progress_popup'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 );
}
diff --git a/httemplate/elements/progress-popup.html b/httemplate/elements/progress-popup.html
index d180c17d4..20bb5fc5a 100644
--- a/httemplate/elements/progress-popup.html
+++ b/httemplate/elements/progress-popup.html
@@ -1,6 +1,7 @@
<%
my $jobnum = $cgi->param('jobnum');
my $url = $cgi->param('url');
+ my $message = $cgi->param('message');
my $formname = scalar($cgi->param('formname'));
%>
<HTML>
@@ -29,7 +30,17 @@ function updateStatus( status_statustext ) {
bar1.update;
jsrsExecute( '<%=$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<%= $jobnum %>' );
} else if ( status.indexOf('complete') > -1 ) {
+<% if ( $message ) { %>
+ document.getElementById("progress_message").innerHTML = "<%= $message %>";
+ document.getElementById("progress_bar").innerHTML = '';
+ document.getElementById("progress_percent").innerHTML = '<INPUT TYPE="button" VALUE="OK" onClick="parent.nd(1);">';
+ document.getElementById("progress_jobnum").innerHTML = '';
+ parent.document.<%=$formname%>.submit.disabled=false;
+<% } elsif ( $url ) { %>
window.top.location.href = '<%= $url %>';
+<% } else { %>
+ alert('job done but no url or message specified');
+<% } %>
} else if ( status.indexOf('error') > -1 ) {
document.getElementById("progress_message").innerHTML = '<FONT SIZE="+1" COLOR="#FF0000">Error: ' + statustext + '</FONT>';
document.getElementById("progress_bar").innerHTML = '';
diff --git a/httemplate/index.html b/httemplate/index.html
index 90a14b1d5..d70c32a44 100644
--- a/httemplate/index.html
+++ b/httemplate/index.html
@@ -128,7 +128,6 @@
<BR><A HREF="browse/cust_pay_batch.cgi">View pending credit card batch</A> <BR><BR><A HREF="search/cust_pkg_report.cgi">Packages (by next bill date range)</A>
<BR><BR>Invoice reports
<UL>
- <LI><a href="search/cust_bill_event.html">Invoice event errors (failed credit cards, processor or printer problems, etc.)</a>
<LI>open invoices (<A HREF="search/cust_bill.html?OPEN_invnum">by invoice number</A>) (<A HREF="search/cust_bill.html?OPEN_date">by date</A>) (<A HREF="search/cust_bill.html?OPEN_custnum">by customer number</A>)
<LI>15 day open invoices (<A HREF="search/cust_bill.html?OPEN15_invnum">by invoice number</A>) (<A HREF="search/cust_bill.html?OPEN15_date">by date</A>) (<A HREF="search/cust_bill.html?OPEN15_custnum">by customer number</A>)
<LI>30 day open invoices (<A HREF="search/cust_bill.html?OPEN30_invnum">by invoice number</A>) (<A HREF="search/cust_bill.html?OPEN30_date">by date</A>) (<A HREF="search/cust_bill.html?OPEN30_custnum">by customer number</A>)
@@ -137,6 +136,11 @@
<LI>120 day open invoices (<A HREF="search/cust_bill.html?OPEN120_invnum">by invoice number</A>) (<A HREF="search/cust_bill.html?OPEN120_date">by date</A>) (<A HREF="search/cust_bill.html?OPEN120_custnum">by customer number</A>)
<LI>all invoices (<A HREF="search/cust_bill.html?invnum">by invoice number</A>) (<A HREF="search/cust_bill.html?date">by date</A>) (<A HREF="search/cust_bill.html?custnum">by customer number</A>)
</UL>
+ Invoice event reports
+ <UL>
+ <LI><a href="search/cust_bill_event.html">All invoice events for a date range</a>
+ <LI><a href="search/cust_bill_event.html?failed=1">Invoice event errors for a date range (failed credit cards, processor or printer problems, etc.)</a>
+ </UL>
<A HREF="search/report_cust_pay.html">Payment report (by type and/or date range)</A>
<BR><BR><A HREF="search/report_cust_credit.html">Credit report (by employee and/or date range)</A>
<BR><BR><A HREF="graph/money_time.cgi">Sales, Credits and Receipts Summary</A>
diff --git a/httemplate/misc/email-invoice.cgi b/httemplate/misc/email-invoice.cgi
index 34afa9084..ad9ba1abb 100755
--- a/httemplate/misc/email-invoice.cgi
+++ b/httemplate/misc/email-invoice.cgi
@@ -1,7 +1,5 @@
<%
-my $conf = new FS::Conf;
-
#untaint invnum
my($query) = $cgi->keywords;
$query =~ /^((.+)-)?(\d+)$/;
@@ -10,16 +8,10 @@ my $invnum = $3;
my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
die "Can't find invoice!\n" unless $cust_bill;
-my $error = send_email(
- $cust_bill->generate_email(
- 'from' =>
- ( $cust_bill->_agent_invoice_from || $conf->config('invoice_from') ),
- 'template' => $template,
- )
-);
-eidiot($error) if $error;
+$cust_bill->email($template);
my $custnum = $cust_bill->getfield('custnum');
+
print $cgi->redirect("${p}view/cust_main.cgi?$custnum");
%>
diff --git a/httemplate/misc/email_invoices.cgi b/httemplate/misc/email_invoices.cgi
new file mode 100644
index 000000000..12d58d608
--- /dev/null
+++ b/httemplate/misc/email_invoices.cgi
@@ -0,0 +1,6 @@
+<%
+
+my $server = new FS::UI::Web::JSRPC 'FS::cust_bill_event::process_reemail';
+$server->process;
+
+%>
diff --git a/httemplate/misc/fax-invoice.cgi b/httemplate/misc/fax-invoice.cgi
index d490b8e79..94fee2cf2 100755
--- a/httemplate/misc/fax-invoice.cgi
+++ b/httemplate/misc/fax-invoice.cgi
@@ -1,8 +1,5 @@
<%
-my $conf = new FS::Conf;
-my $lpr = $conf->config('lpr');
-
#untaint invnum
my($query) = $cgi->keywords;
$query =~ /^((.+)-)?(\d+)$/;
@@ -11,12 +8,7 @@ my $invnum = $3;
my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
die "Can't find invoice!\n" unless $cust_bill;
-my $error = &FS::Misc::send_fax(
- dialstring => $cust_bill->cust_main->getfield('fax'),
- docdata => [ $cust_bill->print_ps('', $template) ],
-);
-
-die $error if $error;
+$cust_bill->fax($template);
my $custnum = $cust_bill->getfield('custnum');
diff --git a/httemplate/misc/fax_invoices.cgi b/httemplate/misc/fax_invoices.cgi
new file mode 100644
index 000000000..a8ded0550
--- /dev/null
+++ b/httemplate/misc/fax_invoices.cgi
@@ -0,0 +1,6 @@
+<%
+
+my $server = new FS::UI::Web::JSRPC 'FS::cust_bill_event::process_refax';
+$server->process;
+
+%>
diff --git a/httemplate/misc/print-invoice.cgi b/httemplate/misc/print-invoice.cgi
index 5eeef3482..6a4c2d7f1 100755
--- a/httemplate/misc/print-invoice.cgi
+++ b/httemplate/misc/print-invoice.cgi
@@ -1,8 +1,5 @@
<%
-my $conf = new FS::Conf;
-my $lpr = $conf->config('lpr');
-
#untaint invnum
my($query) = $cgi->keywords;
$query =~ /^((.+)-)?(\d+)$/;
@@ -11,17 +8,7 @@ my $invnum = $3;
my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
die "Can't find invoice!\n" unless $cust_bill;
- open(LPR,"|$lpr") or die "Can't open $lpr: $!";
-
- if ( $conf->exists('invoice_latex') ) {
- print LPR $cust_bill->print_ps('', $template); #( date )
- } else {
- print LPR $cust_bill->print_text('', $template); #( date )
- }
-
- close LPR
- or die $! ? "Error closing $lpr: $!"
- : "Exit status $? from $lpr";
+$cust_bill->print($template);
my $custnum = $cust_bill->getfield('custnum');
diff --git a/httemplate/misc/print_invoices.cgi b/httemplate/misc/print_invoices.cgi
new file mode 100644
index 000000000..c6a7885a4
--- /dev/null
+++ b/httemplate/misc/print_invoices.cgi
@@ -0,0 +1,6 @@
+<%
+
+my $server = new FS::UI::Web::JSRPC 'FS::cust_bill_event::process_reprint';
+$server->process;
+
+%>
diff --git a/httemplate/search/cust_bill_event.cgi b/httemplate/search/cust_bill_event.cgi
index 7c2b3a24c..253aa78ad 100644
--- a/httemplate/search/cust_bill_event.cgi
+++ b/httemplate/search/cust_bill_event.cgi
@@ -1,62 +1,120 @@
-<!-- mason kludge -->
<%
-#false laziness with view/cust_bill.cgi
+my $title = $cgi->param('failed') ? 'Failed invoice events' : 'Invoice events';
-$cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/;
-my $beginning = str2time($1) || 0;
+my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
-$cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/;
-my $ending = ( $1 ? str2time($1) : 4294880896 ) + 86399;
+##tie my %hash, 'Tie::DxHash',
+#my %hash = (
+# _date => { op=> '>=', value=>$beginning },
+## i wish...
+## _date => { op=> '<=', value=>$ending },
+#);
+#$hash{'statustext'} = { op=> '!=', value=>'' }
+# if $cgi->param('failed');
-my @cust_bill_event =
- sort { $a->_date <=> $b->_date }
- qsearch('cust_bill_event', {
- _date => { op=> '>=', value=>$beginning },
- statustext => { op=> '!=', value=>'' },
-# i wish...
-# _date => { op=> '<=', value=>$ending },
- }, '', "AND _date <= $ending");
+my $where = " WHERE cust_bill_event._date >= $beginning".
+ " AND cust_bill_event._date <= $ending";
+$where .= " AND statustext != '' AND statustext IS NOT NULL"
+ if $cgi->param('failed');
+
+my $sql_query = {
+ 'table' => 'cust_bill_event',
+ #'hashref' => \%hash,
+ 'hashref' => {},
+ 'select' => join(', ',
+ 'cust_bill_event.*',
+ 'part_bill_event.event',
+ 'cust_bill.custnum',
+ 'cust_bill._date AS cust_bill_date',
+ map "cust_main.$_", qw(last first company)
+
+ ),
+ 'extra_sql' => "$where ORDER BY _date ASC",
+ 'addl_from' => 'LEFT JOIN part_bill_event USING ( eventpart ) '.
+ 'LEFT JOIN cust_bill USING ( invnum ) '.
+ 'LEFT JOIN cust_main USING ( custnum ) ',
+};
+
+my $count_sql = "select count(*) from cust_bill_event $where";
+
+my $conf = new FS::Conf;
+
+my $failed = $cgi->param('failed');
+
+my $html_init = join("\n", map {
+ ( my $action = $_ ) =~ s/_$//;
+ include('/elements/progress-init.html',
+ $_.'form',
+ [ 'action', 'beginning', 'ending', 'failed' ],
+ "../misc/${_}invoices.cgi",
+ { 'message' => "Invoices re-${action}ed" }, #would be nice to show the number of them, but...
+ $_, #key
+ ),
+ qq!<FORM NAME="${_}form">!,
+ qq!<INPUT TYPE="hidden" NAME="action" VALUE="$_">!, #not used though
+ qq!<INPUT TYPE="hidden" NAME="beginning" VALUE="$beginning">!,
+ qq!<INPUT TYPE="hidden" NAME="ending" VALUE="$ending">!,
+ qq!<INPUT TYPE="hidden" NAME="failed" VALUE="$failed">!,
+ qq!</FORM>!
+} qw( print_ email_ fax_ ) );
+
+my $menubar = [
+ 'Main menu' => $p,
+ 'Re-print these events' =>
+ "javascript:print_process()",
+ 'Re-email these events' =>
+ "javascript:email_process()",
+ ];
+
+push @$menubar, 'Re-fax these events' =>
+ "javascript:fax_process()"
+ if $conf->exists('hylafax');
+
+%><%= include( 'elements/search.html',
+ 'title' => $title,
+ 'html_init' => $html_init,
+ 'menubar' => $menubar,
+ 'name' => 'billing events',
+ 'query' => $sql_query,
+ 'count_query' => $count_sql,
+ 'header' => [ qw( Event Date Status ),
+ #'Inv #', 'Inv Date', 'Cust #',
+ 'Invoice', 'Cust #',
+ ],
+ 'fields' => [
+ 'event',
+ sub { time2str("%b %d %Y %T", $_[0]->_date) },
+ sub {
+ #my $cust_bill_event = shift;
+ my $status = $_[0]->status;
+ $status .= ': '.$_[0]->statustext
+ if $_[0]->statustext;
+ $status;
+ },
+ sub {
+ #my $cust_bill_event = shift;
+ 'Invoice #'. $_[0]->invnum.
+ ' ('.
+ time2str("%D", $_[0]->cust_bill_date).
+ ')';
+ },
+ sub { FS::cust_main::name($_[0]) },
-%>
-<%= header('Failed billing events') %>
-
-<%= table() %>
-<TR>
- <TH>Event</TH>
- <TH>Date</TH>
- <TH>Status</TH>
- <TH>Invoice</TH>
- <TH>(bill) name</TH>
- <TH>company</TH>
-<% if ( defined dbdef->table('cust_main')->column('ship_last') ) { %>
- <TH>(service) name</TH>
- <TH>company</TH>
-<% } %>
-</TR>
-
-<% foreach my $cust_bill_event ( @cust_bill_event ) {
- my $status = $cust_bill_event->status;
- $status .= ': '.$cust_bill_event->statustext if $cust_bill_event->statustext;
- my $cust_bill = $cust_bill_event->cust_bill;
- my $cust_main = $cust_bill->cust_main;
- my $invlink = "${p}view/cust_bill.cgi?". $cust_bill->invnum;
- my $custlink = "${p}view/cust_main.cgi?". $cust_main->custnum;
+ ],
+ 'links' => [
+ '',
+ '',
+ '',
+ sub {
+ my $part_bill_event = shift;
+ my $template = $part_bill_event->templatename;
+ $template .= '-' if $template;
+ [ "${p}view/cust_bill.cgi?$template", 'invnum'];
+ },
+ [ "${p}view/cust_main.cgi?", 'custnum' ],
+ [ "${p}view/cust_main.cgi?", 'custnum' ],
+ ],
+ )
%>
-<TR>
- <TD><%= $cust_bill_event->part_bill_event->event %></TD>
- <TD><%= time2str("%a %b %e %T %Y", $cust_bill_event->_date) %></TD>
- <TD><%= $status %></TD>
- <TD><A HREF="<%=$invlink%>">Invoice #<%= $cust_bill->invnum %> (<%= time2str("%D", $cust_bill->_date ) %>)</A></TD>
- <TD><A HREF="<%=$custlink%>"><%= $cust_main->last. ', '. $cust_main->first %></A></TD>
- <TD><A HREF="<%=$custlink%>"><%= $cust_main->company %></A></TD>
- <% if ( defined dbdef->table('cust_main')->column('ship_last') ) { %>
- <TD><A HREF="<%=$custlink%>"><%= $cust_main->ship_last. ', '. $cust_main->ship_first %></A></TD>
- <TD><A HREF="<%=$custlink%>"><%= $cust_main->ship_company %></A></TD>
- <% } %>
-</TR>
-<% } %>
-</TABLE>
-
-</BODY></HTML>
diff --git a/httemplate/search/cust_bill_event.html b/httemplate/search/cust_bill_event.html
index 6de27091f..cebb3035f 100755
--- a/httemplate/search/cust_bill_event.html
+++ b/httemplate/search/cust_bill_event.html
@@ -1,14 +1,19 @@
-<HTML>
- <HEAD>
- <TITLE>Invoice event errors</TITLE>
+<%= include(
+ '/elements/header.html',
+ ( $cgi->param('failed') ? 'Failed invoice events' : 'invoice events' ),
+ include('/elements/menubar.html',
+ 'Main menu' => $p, # popurl(2),
+ ),
+
+ )
+%>
<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
- </HEAD>
- <BODY BGCOLOR="#e8e8e8">
- <H1>Invoice event errors</H1>
+
<FORM ACTION="cust_bill_event.cgi" METHOD="GET">
+ <INPUT TYPE="hidden" NAME="failed" VALUE="<%= $cgi->param('failed') %>">
<TABLE>
<!--<TR>
<TD ALIGN="right">Customer type</TD>
@@ -51,4 +56,3 @@
</FORM>
</BODY>
</HTML>
-
diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html
index 529f48f20..47d619444 100644
--- a/httemplate/search/elements/search.html
+++ b/httemplate/search/elements/search.html
@@ -189,6 +189,7 @@
include( '/elements/menubar.html', @menubar )
)
%>
+ <%= defined($opt{'html_init'}) ? $opt{'html_init'} : '' %>
<% my $pager = include ( '/elements/pager.html',
'offset' => $offset,
'num_rows' => scalar(@$rows),
diff --git a/httemplate/view/cust_bill.cgi b/httemplate/view/cust_bill.cgi
index 38c57ec18..d149cf172 100755
--- a/httemplate/view/cust_bill.cgi
+++ b/httemplate/view/cust_bill.cgi
@@ -67,11 +67,8 @@ my $link = $templatename ? "$templatename-$invnum" : $invnum;
<TR>
<TD><%= $part_bill_event->event %>
- <% if (
- $part_bill_event->plan eq 'send_alternate'
- && $part_bill_event->plandata =~ /^(agent_)?templatename (.*)$/m
- ) {
- my $alt_templatename = $2;
+ <% if ( $part_bill_event->templatename ) {
+ my $alt_templatename = $part_bill_event->templatename;
my $alt_link = "$alt_templatename-$invnum";
%>
( <A HREF="<%= $p %>view/cust_bill.cgi?<%= $alt_link %>">view</A>