summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/ClientAPI/MyAccount.pm2
-rw-r--r--FS/FS/Conf.pm7
-rw-r--r--FS/FS/Misc.pm76
-rw-r--r--FS/FS/cust_bill.pm46
-rw-r--r--FS/FS/cust_main.pm5
-rw-r--r--FS/FS/cust_main_invoice.pm6
-rw-r--r--FS/FS/cust_pay.pm4
-rw-r--r--FS/FS/cust_pkg.pm2
-rw-r--r--FS/FS/part_export/http.pm2
-rw-r--r--FS/FS/part_export/infostreet.pm2
-rw-r--r--FS/FS/part_export/shellcommands.pm2
-rw-r--r--FS/FS/svc_acct.pm2
-rw-r--r--htetc/handler.pl2
-rw-r--r--httemplate/docs/install.html1
-rwxr-xr-xhttemplate/edit/cust_main.cgi7
-rwxr-xr-xhttemplate/edit/process/cust_main.cgi1
-rwxr-xr-xhttemplate/misc/fax-invoice.cgi25
-rwxr-xr-xhttemplate/view/cust_bill.cgi6
-rw-r--r--httemplate/view/cust_main/billing.html8
-rw-r--r--httemplate/view/cust_main/tickets.html2
20 files changed, 176 insertions, 32 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index d18a6e4ff..478973396 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -131,7 +131,7 @@ sub customer_info {
}
$return{'invoicing_list'} =
- join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list );
+ join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list );
$return{'postal_invoicing'} =
0 < ( grep { $_ eq 'POST' } $cust_main->invoicing_list );
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index e21e58322..4a9762672 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -1433,6 +1433,13 @@ httemplate/docs/config.html
'select_enum' => [ 'Cache::SharedMemoryCache', 'Cache::FileCache', ], # '_Database' ],
},
+ {
+ 'key' => 'hylafax',
+ 'section' => '',
+ 'description' => 'Options for a HylaFAX server to enable the FAX invoice destination. They should be in the form of a space separated list of arguments to the Fax::Hylafax::Client::sendfax subroutine. You probably shouldn\'t override things like \'docfile\'. *Note* Only supported when using typeset invoices (see the invoice_latex configuration option).',
+ 'type' => [qw( checkbox textarea )],
+ },
+
);
1;
diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm
index 71fe7e712..a7cd47176 100644
--- a/FS/FS/Misc.pm
+++ b/FS/FS/Misc.pm
@@ -5,7 +5,7 @@ use vars qw ( @ISA @EXPORT_OK );
use Exporter;
@ISA = qw( Exporter );
-@EXPORT_OK = qw( send_email );
+@EXPORT_OK = qw( send_email send_fax );
=head1 NAME
@@ -50,6 +50,7 @@ use Date::Format;
use Mail::Header;
use Mail::Internet 1.44;
use MIME::Entity;
+use Fax::Hylafax::Client;
use FS::UID;
FS::UID->install_callback( sub {
@@ -111,6 +112,77 @@ sub send_email {
}
+=item send_fax OPTION => VALUE ...
+
+Options:
+
+I<dialstring> - (required) 10-digit phone number w/ area code
+
+I<docdata> - (required) Array ref containing PostScript or TIFF Class F document
+
+-or-
+
+I<docfile> - (required) Filename of PostScript TIFF Class F document
+
+...any other options will be passed to L<Fax::Hylafax::Client::sendfax>
+
+
+=cut
+
+sub send_fax {
+
+ my %options = @_;
+
+ die 'HylaFAX support has not been configured.'
+ unless $conf->exists('hylafax');
+
+ my %hylafax_opts = map { split /\s+/ } $conf->config('hylafax');
+
+ die 'Called send_fax without a \'dialstring\'.'
+ unless exists($options{'dialstring'});
+
+ if (exists($options{'docdata'}) and ref($options{'docdata'}) eq 'ARRAY') {
+ my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+ my $fh = new File::Temp(
+ TEMPLATE => 'faxdoc.'. $options{'dialstring'} . '.XXXXXXXX',
+ DIR => $dir,
+ UNLINK => 0,
+ ) or die "can't open temp file: $!\n";
+
+ $options{docfile} = $fh->filename;
+
+ print $fh @{$options{'docdata'}};
+ close $fh;
+
+ delete $options{'docdata'};
+ }
+
+ die 'Called send_fax without a \'docfile\' or \'docdata\'.'
+ unless exists($options{'docfile'});
+
+ #FIXME: Need to send canonical dialstring to HylaFAX, but this only
+ # works in the US.
+
+ $options{'dialstring'} =~ s/[^\d\+]//g;
+ if ($options{'dialstring'} =~ /^\d{10}$/) {
+ $options{dialstring} = '+1' . $options{'dialstring'};
+ } else {
+ return 'Invalid dialstring ' . $options{'dialstring'} . '.';
+ }
+
+ my $faxjob = &Fax::Hylafax::Client::sendfax(%options, %hylafax_opts);
+
+ if ($faxjob->success) {
+ warn "Successfully queued fax to '$options{dialstring}' with jobid " .
+ $faxjob->jobid;
+ } else {
+ return 'Error while sending FAX: ' . $faxjob->trace;
+ }
+
+ return '';
+
+}
+
package Mail::Internet;
use Mail::Address;
@@ -191,6 +263,8 @@ This package exists.
L<FS::UID>, L<FS::CGI>, L<FS::Record>, the base documentation.
+L<Fax::Hylafax::Client>
+
=cut
1;
diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm
index e70bb3247..10b4928cb 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -9,7 +9,7 @@ use File::Temp 0.14;
use String::ShellQuote;
use FS::UID qw( datasrc );
use FS::Record qw( qsearch qsearchs );
-use FS::Misc qw( send_email );
+use FS::Misc qw( send_email send_fax );
use FS::cust_main;
use FS::cust_bill_pkg;
use FS::cust_credit;
@@ -378,7 +378,7 @@ sub generate_email {
if (ref($args{'to'} eq 'ARRAY')) {
@invoicing_list = @{$args{'to'}};
} else {
- @invoicing_list = grep { $_ ne 'POST' } $self->cust_main->invoicing_list;
+ @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ } $self->cust_main->invoicing_list;
}
return (
@@ -418,7 +418,7 @@ sub send {
my @print_text = $self->print_text('', $template);
my @invoicing_list = $self->cust_main->invoicing_list;
- if ( grep { $_ ne 'POST' } @invoicing_list or !@invoicing_list ) { #email
+ if ( grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list or !@invoicing_list ) { #email
#better to notify this person than silence
@invoicing_list = ($invoice_from) unless @invoicing_list;
@@ -426,7 +426,7 @@ sub send {
my $error = send_email(
$self->generate_email(
'from' => $invoice_from,
- 'to' => [ grep { $_ ne 'POST' } @invoicing_list ],
+ 'to' => [ grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ],
'print_text' => [ @print_text ],
)
);
@@ -435,16 +435,34 @@ sub send {
}
- if ( grep { $_ eq 'POST' } @invoicing_list ) { #postal
- @print_text = $self->print_ps('', $template)
- if $conf->config('invoice_latex');
- my $lpr = $conf->config('lpr');
- open(LPR, "|$lpr")
- or die "Can't open pipe to $lpr: $!\n";
- print LPR @print_text;
- close LPR
- or die $! ? "Error closing $lpr: $!\n"
- : "Exit status $? from $lpr\n";
+ if ( grep { $_ =~ /^(POST|FAX)$/ } @invoicing_list ) {
+ my $lpr_data;
+ if ($conf->config('invoice_latex')) {
+ $lpr_data = [ $self->print_ps('', $template) ];
+ } else {
+ $lpr_data = \@print_text;
+ }
+
+ 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";
+ }
+
+ if ( grep { $_ eq 'FAX' } @invoicing_list ) { #fax
+ unless ($conf->exists('invoice_latex')) {
+ die 'FAX invoice destination not supported with plain text invoices.'
+ }
+ my $dialstring = $self->cust_main->getfield('fax');
+ #Check $dialstring?
+ my $error = send_fax(docdata => $lpr_data, dialstring => $dialstring);
+ die $error if $error;
+ }
+
}
'';
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 8246b93f5..4fcb22681 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -2655,6 +2655,11 @@ is an error, returns the error, otherwise returns false.
sub check_invoicing_list {
my( $self, $arrayref ) = @_;
foreach my $address ( @{$arrayref} ) {
+
+ if ($address eq 'FAX' and $self->getfield('fax') eq '') {
+ return 'Can\'t add FAX invoice destination with a blank FAX number.';
+ }
+
my $cust_main_invoice = new FS::cust_main_invoice ( {
'custnum' => $self->custnum,
'dest' => $address,
diff --git a/FS/FS/cust_main_invoice.pm b/FS/FS/cust_main_invoice.pm
index 3cabd3a64..03863b83f 100644
--- a/FS/FS/cust_main_invoice.pm
+++ b/FS/FS/cust_main_invoice.pm
@@ -43,7 +43,7 @@ FS::Record. The following fields are currently supported:
=item custnum - customer (see L<FS::cust_main>)
-=item dest - Invoice destination: If numeric, a svcnum (see L<FS::svc_acct>), if string, a literal email address, or `POST' to enable mailing (the default if no cust_main_invoice records exist)
+=item dest - Invoice destination: If numeric, a svcnum (see L<FS::svc_acct>), if string, a literal email address, `POST' to enable mailing (the default if no cust_main_invoice records exist), or `FAX' to enable faxing via a HylaFAX server.
=back
@@ -127,7 +127,7 @@ sub checkdest {
my $error = $self->ut_text('dest');
return $error if $error;
- if ( $self->dest eq 'POST' ) {
+ if ( $self->dest =~ /^(POST|FAX)$/ ) {
#contemplate our navel
} elsif ( $self->dest =~ /^(\d+)$/ ) {
return "Unknown local account (specified by svcnum: ". $self->dest. ")"
@@ -144,7 +144,7 @@ sub checkdest {
=item address
-Returns the literal email address for this record (or `POST').
+Returns the literal email address for this record (or `POST' or `FAX').
=cut
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index 80d4a140b..fa97ba9eb 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -167,7 +167,7 @@ sub insert {
#my $cust_main = $self->cust_main;
if ( $conf->exists('payment_receipt_email')
- && grep { $_ ne 'POST' } $cust_main->invoicing_list
+ && grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list
) {
my $receipt_template = new Text::Template (
@@ -178,7 +178,7 @@ sub insert {
return '';
};
- my @invoicing_list = grep { $_ ne 'POST' } $cust_main->invoicing_list;
+ my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list;
my $payby = $self->payby;
my $payinfo = $self->payinfo;
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index e3724a3ef..f5c1de3e2 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -423,7 +423,7 @@ sub cancel {
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
my $conf = new FS::Conf;
- my @invoicing_list = grep { $_ ne 'POST' } $self->cust_main->invoicing_list;
+ my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ } $self->cust_main->invoicing_list;
if ( !$options{'quiet'} && $conf->exists('emailcancel') && @invoicing_list ) {
my $conf = new FS::Conf;
my $error = send_email(
diff --git a/FS/FS/part_export/http.pm b/FS/FS/part_export/http.pm
index 0be2a0f36..55d832966 100644
--- a/FS/FS/part_export/http.pm
+++ b/FS/FS/part_export/http.pm
@@ -18,7 +18,7 @@ tie my %options, 'Tie::IxHash',
type => 'textarea',
default => join("\n",
'DomainName $svc_x->domain',
- 'Email ( grep { $_ ne "POST" } $svc_x->cust_svc->cust_pkg->cust_main->invoicing_list)[0]',
+ 'Email ( grep { $_ !~ /^(POST|FAX)$/ } $svc_x->cust_svc->cust_pkg->cust_main->invoicing_list)[0]',
'test 1',
'reseller $svc_x->cust_svc->cust_pkg->part_pkg->pkg =~ /reseller/i',
),
diff --git a/FS/FS/part_export/infostreet.pm b/FS/FS/part_export/infostreet.pm
index 309e7ce6f..ef16c7c54 100644
--- a/FS/FS/part_export/infostreet.pm
+++ b/FS/FS/part_export/infostreet.pm
@@ -67,7 +67,7 @@ sub _export_insert {
$_ => $cust_main->getfield( $infostreet2cust_main{$_} );
} keys %infostreet2cust_main );
- my @emails = grep { $_ ne 'POST' } $cust_main->invoicing_list;
+ my @emails = grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list;
$contact_info{'email'} = $emails[0] if @emails;
#this one is kinda noment-specific
diff --git a/FS/FS/part_export/shellcommands.pm b/FS/FS/part_export/shellcommands.pm
index 4f201cf9c..665ec473f 100644
--- a/FS/FS/part_export/shellcommands.pm
+++ b/FS/FS/part_export/shellcommands.pm
@@ -216,7 +216,7 @@ sub _export_command {
my $cust_pkg = $svc_acct->cust_svc->cust_pkg;
if ( $cust_pkg ) {
- $email = ( grep { $_ ne 'POST' } $cust_pkg->cust_main->invoicing_list )[0];
+ $email = ( grep { $_ !~ /^(POST|FAX)$/ } $cust_pkg->cust_main->invoicing_list )[0];
} else {
$email = '';
}
diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm
index 35596e34b..109ea1d45 100644
--- a/FS/FS/svc_acct.pm
+++ b/FS/FS/svc_acct.pm
@@ -296,7 +296,7 @@ sub insert {
#welcome email
my $to = '';
if ( $welcome_template && $cust_pkg ) {
- my $to = join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list );
+ my $to = join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list );
if ( $to ) {
my $wqueue = new FS::queue {
'svcnum' => $self->svcnum,
diff --git a/htetc/handler.pl b/htetc/handler.pl
index c144eca1a..b44e3f2d4 100644
--- a/htetc/handler.pl
+++ b/htetc/handler.pl
@@ -118,7 +118,7 @@ sub handler
small_custview myexit http_header);
use FS::UI::Web;
use FS::Msgcat qw(gettext geterror);
- use FS::Misc qw( send_email );
+ use FS::Misc qw( send_email send_fax );
use FS::Report::Table::Monthly;
use FS::TicketSystem;
diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html
index eaebcde2b..10c51e77d 100644
--- a/httemplate/docs/install.html
+++ b/httemplate/docs/install.html
@@ -68,6 +68,7 @@ Before installing, you need:
<li><a href="http://search.cpan.org/dist/Frontier-RPC">Frontier::RPC (Frontier::RPC2)</a>
<li><a href="http://search.cpan.org/search?mode=module&query=MIME::Entity">MIME::Entity (MIME-tools)</a>
<!-- <li><a href="http://search.cpan.org/dist/Crypt-YAPassGen">Crypt::YAPassGen</a> -->
+ <li><a href="http://search.cpan.org/search?mode=module&query=MIME::Entity">Fax::Hylafax::Client</a> <i>(Required if using FAX invoice destinations</i>
<li><a href="http://search.cpan.org/dist/ApacheDBI">Apache::DBI</a> <i>(optional but recommended for better webinterface performance)</i>
</ul>
</ul>
diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi
index 3910b4b84..61468f382 100755
--- a/httemplate/edit/cust_main.cgi
+++ b/httemplate/edit/cust_main.cgi
@@ -302,8 +302,11 @@ if ( $payby_default eq 'HIDE' ) {
print qq! CHECKED!
if ( ! @invoicing_list && ! $conf->exists('disablepostalinvoicedefault') )
|| grep { $_ eq 'POST' } @invoicing_list;
- print qq!>Postal mail invoice</TD></TR>!;
- my $invoicing_list = join(', ', grep { $_ ne 'POST' } @invoicing_list );
+ print qq!>Postal mail invoice</TD></TR><TR><TD>!;
+ print qq!<INPUT TYPE="checkbox" NAME="invoicing_list_FAX" VALUE="FAX"!;
+ print qq! CHECKED! if (grep { $_ eq 'FAX' } @invoicing_list);
+ print qq!>FAX invoice</TD></TR>!;
+ my $invoicing_list = join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list );
print qq!<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="$invoicing_list"></TD></TR>!;
print "<TR><TD>Billing type</TD></TR>",
diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi
index a1d36986d..d2773a60e 100755
--- a/httemplate/edit/process/cust_main.cgi
+++ b/httemplate/edit/process/cust_main.cgi
@@ -25,6 +25,7 @@ if ( $payby ) {
my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') );
push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST');
+push @invoicing_list, 'FAX' if $cgi->param('invoicing_list_FAX');
$cgi->param('invoicing_list', join(',', @invoicing_list) );
diff --git a/httemplate/misc/fax-invoice.cgi b/httemplate/misc/fax-invoice.cgi
new file mode 100755
index 000000000..46b2a1721
--- /dev/null
+++ b/httemplate/misc/fax-invoice.cgi
@@ -0,0 +1,25 @@
+<%
+
+my $conf = new FS::Conf;
+my $lpr = $conf->config('lpr');
+
+#untaint invnum
+my($query) = $cgi->keywords;
+$query =~ /^(\d*)$/;
+my $invnum = $1;
+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 ],
+);
+
+die $error if $error;
+
+my $custnum = $cust_bill->getfield('custnum');
+
+print $cgi->redirect("${p}view/cust_main.cgi?$custnum");
+
+%>
diff --git a/httemplate/view/cust_bill.cgi b/httemplate/view/cust_bill.cgi
index ca0612d09..c217cc389 100755
--- a/httemplate/view/cust_bill.cgi
+++ b/httemplate/view/cust_bill.cgi
@@ -7,6 +7,8 @@ $query =~ /^((.+)-)?(\d+)$/;
my $templatename = $2;
my $invnum = $3;
+my $conf = new FS::Conf;
+
my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
die "Invoice #$invnum not found!" unless $cust_bill;
my $custnum = $cust_bill->getfield('custnum');
@@ -27,9 +29,11 @@ if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) {
qq!Re-email this invoice</A>!;
}
+print qq! | <A HREF="${p}misc/fax-invoice.cgi?$invnum">Refax this invoice</A>!
+ if ($conf->exists('hylafax'));
+
print '<BR><BR>';
-my $conf = new FS::Conf;
if ( $conf->exists('invoice_latex') ) {
my $link = "${p}view/cust_bill-pdf.cgi?";
$link .= "$templatename-" if $templatename;
diff --git a/httemplate/view/cust_main/billing.html b/httemplate/view/cust_main/billing.html
index 18a203bd6..561fff992 100644
--- a/httemplate/view/cust_main/billing.html
+++ b/httemplate/view/cust_main/billing.html
@@ -17,9 +17,15 @@ Billing information
</TD>
</TR>
<TR>
+ <TD ALIGN="right">FAX&nbsp;invoices</TD>
+ <TD BGCOLOR="#ffffff">
+ <%= ( grep { $_ eq 'FAX' } @invoicing_list ) ? 'yes' : 'no' %>
+ </TD>
+</TR>
+<TR>
<TD ALIGN="right">Email&nbsp;invoices</TD>
<TD BGCOLOR="#ffffff">
- <%= join(', ', grep { $_ ne 'POST' } @invoicing_list ) || 'no' %>
+ <%= join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) || 'no' %>
</TD>
</TR>
<TR>
diff --git a/httemplate/view/cust_main/tickets.html b/httemplate/view/cust_main/tickets.html
index d6ddfa64c..ea70d701d 100644
--- a/httemplate/view/cust_main/tickets.html
+++ b/httemplate/view/cust_main/tickets.html
@@ -30,7 +30,7 @@
Highest priority tickets
(<A HREF="<%= FS::TicketSystem->href_customer_tickets($cust_main->custnum) %>">View all tickets for this customer</A>)
-(<A HREF="<%= FS::TicketSystem->href_new_ticket($cust_main->custnum, join(', ', grep { $_ ne 'POST' } $cust_main->invoicing_list ) ) %>">New ticket for this customer</A>)
+(<A HREF="<%= FS::TicketSystem->href_new_ticket($cust_main->custnum, join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list ) ) %>">New ticket for this customer</A>)
<%= table() %>
<TR>
<TH>#</TH>