diff options
| -rw-r--r-- | FS/FS/cust_bill.pm | 312 | ||||
| -rw-r--r-- | FS/FS/part_event/Action/cust_bill_send_reminder.pm | 31 | ||||
| -rw-r--r-- | conf/invoice_html | 2 | ||||
| -rw-r--r-- | conf/invoice_latex | 2 | ||||
| -rw-r--r-- | conf/invoice_template | 2 | ||||
| -rwxr-xr-x | httemplate/misc/email-statement.cgi | 19 | ||||
| -rw-r--r-- | httemplate/misc/send-invoice.cgi | 30 | ||||
| -rwxr-xr-x | httemplate/misc/send-statement.cgi | 28 | ||||
| -rw-r--r-- | httemplate/search/cust_event.html | 23 | ||||
| -rwxr-xr-x | httemplate/view/cust_bill-pdf.cgi | 22 | ||||
| -rwxr-xr-x | httemplate/view/cust_bill-ps.cgi | 21 | ||||
| -rwxr-xr-x | httemplate/view/cust_bill.cgi | 37 | ||||
| -rwxr-xr-x | httemplate/view/cust_statement.html | 9 | 
13 files changed, 399 insertions, 139 deletions
| diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 57066b474..e7c0be892 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -770,6 +770,10 @@ text attachment arrayref, optional  email subject, optional +=item notice_name + +notice name instead of "Invoice", optional +  =back  Returns an argument list to be passed to L<FS::Misc::send_email>. @@ -790,13 +794,19 @@ sub generate_email {      'subject'   => (($args{'subject'}) ? $args{'subject'} : 'Invoice'),    ); -  my %cdrs = ( 'unsquelch_cdr' => $conf->exists('voip-cdr_email') ); +  my %opt = ( +    'unsquelch_cdr' => $conf->exists('voip-cdr_email'), +    'template'      => $args{'template'}, +    'notice_name'   => ( $args{'notice_name'} || 'Invoice' ), +  ); + +  my $cust_main = $self->cust_main;    if (ref($args{'to'}) eq 'ARRAY') {      $return{'to'} = $args{'to'};    } else {      $return{'to'} = [ grep { $_ !~ /^(POST|FAX)$/ } -                           $self->cust_main->invoicing_list +                           $cust_main->invoicing_list                      ];    } @@ -830,7 +840,7 @@ sub generate_email {        if ( ref($args{'print_text'}) eq 'ARRAY' ) {          $data = $args{'print_text'};        } else { -        $data = [ $self->print_text('', $args{'template'}, %cdrs) ]; +        $data = [ $self->print_text(\%opt) ];        }      } @@ -848,7 +858,7 @@ sub generate_email {      my $content_id = join('.', rand()*(2**32), $$, time). "\@$from";      my $logo; -    my $agentnum = $self->cust_main->agentnum; +    my $agentnum = $cust_main->agentnum;      if ( defined($args{'template'}) && length($args{'template'})           && $conf->exists( 'logo_'. $args{'template'}. '.png', $agentnum )         ) @@ -877,11 +887,7 @@ sub generate_email {                           '    </title>',                           '  </head>',                           '  <body bgcolor="#e8e8e8">', -                         $self->print_html({ time          => '', -                                             template      => $args{'template'}, -                                             cid           => $content_id, -                                             %cdrs, -                                          }), +                         $self->print_html({ 'cid'=>$content_id, %opt }),                           '  </body>',                           '</html>',                         ], @@ -890,7 +896,7 @@ sub generate_email {      );      my @otherparts = (); -    if ( $self->cust_main->email_csv_cdr ) { +    if ( $cust_main->email_csv_cdr ) {        push @otherparts, build MIME::Entity          'Type'        => 'text/csv', @@ -929,7 +935,7 @@ sub generate_email {        $related->add_part($image); -      my $pdf = build MIME::Entity $self->mimebuild_pdf('', $args{'template'}, %cdrs); +      my $pdf = build MIME::Entity $self->mimebuild_pdf(\%opt);        $return{'mimeparts'} = [ $related, $pdf, @otherparts ]; @@ -957,7 +963,7 @@ sub generate_email {        #mime parts arguments a la MIME::Entity->build().        $return{'mimeparts'} = [ -        { $self->mimebuild_pdf('', $args{'template'}, %cdrs) } +        { $self->mimebuild_pdf(\%opt) }        ];      } @@ -977,7 +983,7 @@ sub generate_email {        if ( ref($args{'print_text'}) eq 'ARRAY' ) {          $return{'body'} = $args{'print_text'};        } else { -        $return{'body'} = [ $self->print_text('', $args{'template'}, %cdrs) ]; +        $return{'body'} = [ $self->print_text(\%opt) ];        }      } @@ -1006,22 +1012,27 @@ sub mimebuild_pdf {    );  } -=item send [ TEMPLATENAME [ , AGENTNUM [ , INVOICE_FROM ] ] ] +=item send HASHREF | [ TEMPLATE [ , AGENTNUM [ , INVOICE_FROM [ , AMOUNT ] ] ] ]  Sends this invoice to the destinations configured for this customer: sends  email, prints and/or faxes.  See L<FS::cust_main_invoice>. -TEMPLATENAME, if specified, is the name of a suffix for alternate invoices. +Options can be passed as a hashref (recommended) or as a list of up to  +four values for templatename, agentnum, invoice_from and amount. -AGENTNUM, if specified, means that this invoice will only be sent for customers +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<agentnum>, if specified, means that this invoice will only be sent for customers  of the specified agent or agent(s).  AGENTNUM can be a scalar agentnum (for a  single agent) or an arrayref of agentnums. -INVOICE_FROM, if specified, overrides the default email invoice From: address. +I<invoice_from>, if specified, overrides the default email invoice From: address. -AMOUNT, if specified, only sends the invoice if the total amount owed on this +I<amount>, if specified, only sends the invoice if the total amount owed on this  invoice and all older invoices is greater than the specified amount. +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) +  =cut  sub queueable_send { @@ -1041,48 +1052,73 @@ sub queueable_send {  sub send {    my $self = shift; -  my $template = scalar(@_) ? shift : ''; -  if ( scalar(@_) && $_[0]  ) { -    my $agentnums = ref($_[0]) ? shift : [ shift ]; -    return 'N/A' unless grep { $_ == $self->cust_main->agentnum } @$agentnums; -  } -  my $invoice_from = -    scalar(@_) -      ? shift -      : ( $self->_agent_invoice_from ||    #XXX should go away -          $conf->config('invoice_from', $self->cust_main->agentnum ) -        ); +  my( $template, $invoice_from, $notice_name ); +  my $agentnums = ''; +  my $balance_over = 0; + +  if ( ref($_[0]) ) { +    my $opt = shift; +    $template = $opt->{'template'} || ''; +    if ( $agentnums = $opt->{'agentnum'} ) { +      $agentnums = [ $agentnums ] unless ref($agentnums); +    } +    $invoice_from = $opt->{'invoice_from'}; +    $balance_over = $opt->{'balance_over'} if $opt->{'balance_over'}; +    $notice_name = $opt=>{'notice_name'}; +  } else { +    $template = scalar(@_) ? shift : ''; +    if ( scalar(@_) && $_[0]  ) { +      $agentnums = ref($_[0]) ? shift : [ shift ]; +    } +    $invoice_from = shift if scalar(@_); +    $balance_over = shift if scalar(@_) && $_[0] !~ /^\s*$/; +  } -  my $balance_over = ( scalar(@_) && $_[0] !~ /^\s*$/ ) ? shift : 0; +  return 'N/A' unless ! $agentnums +                   or grep { $_ == $self->cust_main->agentnum } @$agentnums;    return ''      unless $self->cust_main->total_owed_date($self->_date) > $balance_over; +  $invoice_from ||= $self->_agent_invoice_from ||    #XXX should go away +                    $conf->config('invoice_from', $self->cust_main->agentnum ); + +  my %opt = ( +    'template'     => $template, +    'invoice_from' => $invoice_from, +    'notice_name'  => ( $notice_name || 'Invoice' ), +  ); +    my @invoicing_list = $self->cust_main->invoicing_list; -  #$self->email_invoice($template, $invoice_from) -  $self->email($template, $invoice_from) +  #$self->email_invoice(\%opt) +  $self->email(\%opt)      if grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list or !@invoicing_list; -  #$self->print_invoice($template) -  $self->print($template) +  #$self->print_invoice(\%opt) +  $self->print(\%opt)      if grep { $_ eq 'POST' } @invoicing_list; #postal -  $self->fax_invoice($template) +  $self->fax_invoice(\%opt)      if grep { $_ eq 'FAX' } @invoicing_list; #fax    '';  } -=item email [ TEMPLATENAME  [ , INVOICE_FROM ] ]  +=item email HASHREF | [ TEMPLATE [ , INVOICE_FROM ] ]   Emails this invoice. -TEMPLATENAME, if specified, is the name of a suffix for alternate invoices. +Options can be passed as a hashref (recommended) or as a list of up to  +two values for templatename and invoice_from. + +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<invoice_from>, if specified, overrides the default email invoice From: address. -INVOICE_FROM, if specified, overrides the default email invoice From: address. +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required)  =cut @@ -1104,14 +1140,21 @@ sub queueable_email {  #sub email_invoice {  sub email {    my $self = shift; -  my $template = scalar(@_) ? shift : ''; -  my $invoice_from = -    scalar(@_) -      ? shift -      : ( $self->_agent_invoice_from ||    #XXX should go away -          $conf->config('invoice_from', $self->cust_main->agentnum ) -        ); +  my( $template, $invoice_from, $notice_name ); +  if ( ref($_[0]) ) { +    my $opt = shift; +    $template = $opt->{'template'} || ''; +    $invoice_from = $opt->{'invoice_from'}; +    $notice_name = $opt->{'notice_name'} || 'Invoice'; +  } else { +    $template = scalar(@_) ? shift : ''; +    $invoice_from = shift if scalar(@_); +    $notice_name = 'Invoice'; +  } + +  $invoice_from ||= $self->_agent_invoice_from ||    #XXX should go away +                    $conf->config('invoice_from', $self->cust_main->agentnum );    my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ }                               $self->cust_main->invoicing_list; @@ -1123,10 +1166,11 @@ sub email {    my $error = send_email(      $self->generate_email( -      'from'       => $invoice_from, -      'to'         => [ grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ], -      'subject'    => $subject, -      'template'   => $template, +      'from'        => $invoice_from, +      'to'          => [ grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ], +      'subject'     => $subject, +      'template'    => $template, +      'notice_name' => $notice_name,      )    );    die "can't email invoice: $error\n" if $error; @@ -1152,48 +1196,98 @@ sub email_subject {    eval qq("$subject");  } -=item lpr_data [ TEMPLATENAME ] +=item lpr_data HASHREF | [ TEMPLATE ]  Returns the postscript or plaintext for this invoice as an arrayref. -TEMPLATENAME, if specified, is the name of a suffix for alternate invoices. +Options can be passed as a hashref (recommended) or as a single optional value +for template. + +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required)  =cut  sub lpr_data { -  my( $self, $template) = @_; -  $conf->exists('invoice_latex') -    ? [ $self->print_ps('', $template) ] -    : [ $self->print_text('', $template) ]; +  my $self = shift; +  my( $template, $notice_name ); +  if ( ref($_[0]) ) { +    my $opt = shift; +    $template = $opt->{'template'} || ''; +    $notice_name = $opt->{'notice_name'} || 'Invoice'; +  } else { +    $template = scalar(@_) ? shift : ''; +    $notice_name = 'Invoice'; +  } + +  my %opt = ( +    'template'    => $template, +    'notice_name' => $notice_name, +  ); + +  my $method = $conf->exists('invoice_latex') ? 'print_ps' : 'print_text'; +  [ $self->$method( \%opt ) ];  } -=item print [ TEMPLATENAME ] +=item print HASHREF | [ TEMPLATE ]  Prints this invoice. -TEMPLATENAME, if specified, is the name of a suffix for alternate invoices. +Options can be passed as a hashref (recommended) or as a single optional +value for template. + +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required)  =cut  #sub print_invoice {  sub print {    my $self = shift; -  my $template = scalar(@_) ? shift : ''; +  my( $template, $notice_name ); +  if ( ref($_[0]) ) { +    my $opt = shift; +    $template = $opt->{'template'} || ''; +    $notice_name = $opt->{'notice_name'} || 'Invoice'; +  } else { +    $template = scalar(@_) ? shift : ''; +    $notice_name = 'Invoice'; +  } -  do_print $self->lpr_data($template); +  my %opt = ( +    'template'    => $template, +    'notice_name' => $notice_name, +  ); + +  do_print $self->lpr_data(\%opt);  } -=item fax_invoice [ TEMPLATENAME ]  +=item fax_invoice HASHREF | [ TEMPLATE ]   Faxes this invoice. -TEMPLATENAME, if specified, is the name of a suffix for alternate invoices. +Options can be passed as a hashref (recommended) or as a single optional +value for template. + +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required)  =cut  sub fax_invoice {    my $self = shift; -  my $template = scalar(@_) ? shift : ''; +  my( $template, $notice_name ); +  if ( ref($_[0]) ) { +    my $opt = shift; +    $template = $opt->{'template'} || ''; +    $notice_name = $opt->{'notice_name'} || 'Invoice'; +  } else { +    $template = scalar(@_) ? shift : ''; +    $notice_name = 'Invoice'; +  }    die 'FAX invoice destination not (yet?) supported with plain text invoices.'      unless $conf->exists('invoice_latex'); @@ -1201,7 +1295,12 @@ sub fax_invoice {    my $dialstring = $self->cust_main->getfield('fax');    #Check $dialstring? -  my $error = send_fax( 'docdata'    => $self->lpr_data($template), +  my %opt = ( +    'template'    => $template, +    'notice_name' => $notice_name, +  ); + +  my $error = send_fax( 'docdata'    => $self->lpr_data(\%opt),                          'dialstring' => $dialstring,                        );    die $error if $error; @@ -1805,29 +1904,45 @@ sub _agent_invoice_from {    $self->cust_main->agent_invoice_from;  } -=item print_text [ TIME [ , TEMPLATE ] ] +=item print_text HASHREF | [ TIME [ , TEMPLATE [ , OPTION => VALUE ... ] ] ]  Returns an text invoice, as a list of lines. -TIME an optional value used to control the printing of overdue messages.  The +Options can be passed as a hashref (recommended) or as a list of time, template +and then any key/value pairs for any other options. + +I<time>, if specified, is used to control the printing of overdue messages.  The  default is now.  It isn't the date of the invoice; that's the `_date' field.  It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see  L<Time::Local> and L<Date::Parse> for conversion functions. +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) +  =cut  sub print_text { -  my( $self, $today, $template, %opt ) = @_; +  my $self = shift; +  my( $today, $template, %opt ); +  if ( ref($_[0]) ) { +    %opt = %{ shift() }; +    $today = delete($opt{'time'}) || ''; +    $template = delete($opt{template}) || ''; +  } else { +    ( $today, $template, %opt ) = @_; +  }    my %params = ( 'format' => 'template' );    $params{'time'} = $today if $today;    $params{'template'} = $template if $template; -  $params{'unsquelch_cdr'} = $opt{'unsquelch_cdr'} if $opt{'unsquelch_cdr'}; +  $params{$_} = $opt{$_}  +    foreach grep $opt{$_}, qw( unsquealch_cdr notice_name );    $self->print_generic( %params );  } -=item print_latex [ TIME [ , TEMPLATE ] ] +=item print_latex HASHREF | [ TIME [ , TEMPLATE [ , OPTION => VALUE ... ] ] ]  Internal method - returns a filename of a filled-in LaTeX template for this  invoice (Note: add ".tex" to get the actual filename), and a filename of @@ -1835,20 +1950,36 @@ an associated logo (with the .eps extension included).  See print_ps and print_pdf for methods that return PostScript and PDF output. -TIME an optional value used to control the printing of overdue messages.  The +Options can be passed as a hashref (recommended) or as a list of time, template +and then any key/value pairs for any other options. + +I<time>, if specified, is used to control the printing of overdue messages.  The  default is now.  It isn't the date of the invoice; that's the `_date' field.  It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see  L<Time::Local> and L<Date::Parse> for conversion functions. +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) +  =cut  sub print_latex { -  my( $self, $today, $template, %opt ) = @_; +  my $self = shift; +  my( $today, $template, %opt ); +  if ( ref($_[0]) ) { +    %opt = %{ shift() }; +    $today = delete($opt{'time'}) || ''; +    $template = delete($opt{template}) || ''; +  } else { +    ( $today, $template, %opt ) = @_; +  }    my %params = ( 'format' => 'latex' );    $params{'time'} = $today if $today;    $params{'template'} = $template if $template; -  $params{'unsquelch_cdr'} = $opt{'unsquelch_cdr'} if $opt{'unsquelch_cdr'}; +  $params{$_} = $opt{$_}  +    foreach grep $opt{$_}, qw( unsquealch_cdr notice_name );    $template ||= $self->_agent_template; @@ -1886,7 +2017,7 @@ sub print_latex {  } -=item print_generic OPTIONS_HASH +=item print_generic OPTION => VALUE ...  Internal method - returns a filled-in template for this invoice as a scalar. @@ -1908,10 +2039,12 @@ cid -  unsquelch_cdr - overrides any per customer cdr squelching when true +notice_name - overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) +  =cut  #what's with all the sprintf('%10.2f')'s in here?  will it cause any -# (alignment?) problems to change them all to '%.2f' ? +# (alignment in text invoice?) problems to change them all to '%.2f' ?  sub print_generic {    my( $self, %params ) = @_; @@ -2148,6 +2281,7 @@ sub print_generic {      'duedate'         => $self->due_date2str('%m/%d/%Y'), #date_format?      'ship_enable'     => $conf->exists('invoice-ship_address'),      'unitprices'      => $conf->exists('invoice-unitprice'), +    'notice_name'     => ($params{'notice_name'} || 'Invoice'),#escape_function?    );    $invoice_data{finance_section} = ''; @@ -2705,15 +2839,20 @@ sub print_generic {    }  } -=item print_ps [ TIME [ , TEMPLATE ] ] +=item print_ps HASHREF | [ TIME [ , TEMPLATE ] ]  Returns an postscript invoice, as a scalar. -TIME an optional value used to control the printing of overdue messages.  The +Options can be passed as a hashref (recommended) or as a list of time, template +and then any key/value pairs for any other options. + +I<time> an optional value used to control the printing of overdue messages.  The  default is now.  It isn't the date of the invoice; that's the `_date' field.  It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see  L<Time::Local> and L<Date::Parse> for conversion functions. +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) +  =cut  sub print_ps { @@ -2726,15 +2865,22 @@ sub print_ps {    $ps;  } -=item print_pdf [ TIME [ , TEMPLATE ] ] +=item print_pdf HASHREF | [ TIME [ , TEMPLATE ] ]  Returns an PDF invoice, as a scalar. -TIME an optional value used to control the printing of overdue messages.  The +Options can be passed as a hashref (recommended) or as a list of time, template +and then any key/value pairs for any other options. + +I<time> an optional value used to control the printing of overdue messages.  The  default is now.  It isn't the date of the invoice; that's the `_date' field.  It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see  L<Time::Local> and L<Date::Parse> for conversion functions. +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) +  =cut  sub print_pdf { @@ -2747,16 +2893,20 @@ sub print_pdf {    $pdf;  } -=item print_html [ TIME [ , TEMPLATE [ , CID ] ] ] +=item print_html HASHREF | [ TIME [ , TEMPLATE [ , CID ] ] ]  Returns an HTML invoice, as a scalar. -TIME an optional value used to control the printing of overdue messages.  The +I<time> an optional value used to control the printing of overdue messages.  The  default is now.  It isn't the date of the invoice; that's the `_date' field.  It is specified as a UNIX timestamp; see L<perlfunc/"time">.  Also see  L<Time::Local> and L<Date::Parse> for conversion functions. -CID is a MIME Content-ID used to create a "cid:" URL for the logo image, used +I<template>, if specified, is the name of a suffix for alternate invoices. + +I<notice_name>, if specified, overrides "Invoice" as the name of the sent document (templates from 10/2009 or newer required) + +I<cid> is a MIME Content-ID used to create a "cid:" URL for the logo image, used  when emailing the invoice as part of a multipart/related MIME email.  =cut @@ -2764,7 +2914,7 @@ when emailing the invoice as part of a multipart/related MIME email.  sub print_html {    my $self = shift;    my %params; -  if ( ref $_[0]  ) { +  if ( ref($_[0]) ) {      %params = %{ shift() };     }else{      $params{'time'} = shift; diff --git a/FS/FS/part_event/Action/cust_bill_send_reminder.pm b/FS/FS/part_event/Action/cust_bill_send_reminder.pm new file mode 100644 index 000000000..2ba8136dd --- /dev/null +++ b/FS/FS/part_event/Action/cust_bill_send_reminder.pm @@ -0,0 +1,31 @@ +package FS::part_event::Action::cust_bill_send_reminder; + +use strict; +use base qw( FS::part_event::Action ); + +sub description { 'Send invoice (email/print/fax) reminder'; } + +sub eventtable_hashref { +  { 'cust_bill' => 1 }; +} + +sub option_fields { +  ( +    'notice_name'  => 'Reminder name', +    #'notes' => { 'label' => 'Reminder notes' },  +    #include standard notes?  no/prepend/append +  ); +} + +sub default_weight { 50; } + +sub do_action { +  my( $self, $cust_bill ) = @_; + +  #my $cust_main = $self->cust_main($cust_bill); +  #my $cust_main = $cust_bill->cust_main; + +  $cust_bill->send({ 'notice_name' => $self->option('notice_name') }); +} + +1; diff --git a/conf/invoice_html b/conf/invoice_html index 026bc8b6b..7ee0fdc19 100644 --- a/conf/invoice_html +++ b/conf/invoice_html @@ -42,7 +42,7 @@            <tr>              <th> </th>              <th colspan=3 align="center"> -              <FONT SIZE="+3">I</FONT><FONT SIZE="+2">NVOICE</FONT> +              <FONT SIZE="+3"><%= $notice_name ? substr($notice_name, 0, 1) : 'I' %></FONT><FONT SIZE="+2"><%= $notice_name ? uc(substr($notice_name, 1)) : 'NVOICE' %></FONT>              </th>              <th> </th>            </tr> diff --git a/conf/invoice_latex b/conf/invoice_latex index cf684ef75..42a9f93cf 100644 --- a/conf/invoice_latex +++ b/conf/invoice_latex @@ -127,7 +127,7 @@      Invoice date & Invoice \#& Customer\#\\
      \vspace{0.2cm}
      \textbf{[@-- $date --@]} & \textbf{[@-- $invnum --@]} & \textbf{[@-- $custnum --@]} \\\hline
 -    \rule{0pt}{5ex} &~~ \huge{\textsc{Invoice}} & \\
 +    \rule{0pt}{5ex} &~~ \huge{\textsc{[@-- $notice_name || 'Invoice' --@]}} & \\
      \vspace{-0.2cm}
       & & \\\hline
      \end{tabular}
 diff --git a/conf/invoice_template b/conf/invoice_template index b33c4dda1..ebf8ef7d0 100644 --- a/conf/invoice_template +++ b/conf/invoice_template @@ -1,5 +1,5 @@ -                                 Invoice +                                 { $notice_name || 'Invoice'; }                                   { substr("Page $page of $total_pages          ", 0, 19); } { use Date::Format; time2str("%x", $date); }  Invoice #{ $invnum; } diff --git a/httemplate/misc/email-statement.cgi b/httemplate/misc/email-statement.cgi deleted file mode 100755 index 67f654d64..000000000 --- a/httemplate/misc/email-statement.cgi +++ /dev/null @@ -1,19 +0,0 @@ -<% $cgi->redirect("${p}view/cust_main.cgi?$custnum") %> -<%init> - -die "access denied" -  unless $FS::CurrentUser::CurrentUser->access_right('Resend invoices'); - -#untaint statementnum -my($query) = $cgi->keywords; -$query =~ /^((.+)-)?(\d+)$/; -my $template = $2 || 'statement'; #XXX configure... via event??  eh.. -my $statementnum = $3; -my $cust_statement = qsearchs('cust_statement',{'statementnum'=>$statementnum}); -die "Can't find statement!\n" unless $cust_statement; - -$cust_statement->email($template);  - -my $custnum = $cust_statement->getfield('custnum'); - -</%init> diff --git a/httemplate/misc/send-invoice.cgi b/httemplate/misc/send-invoice.cgi new file mode 100644 index 000000000..32dfe276d --- /dev/null +++ b/httemplate/misc/send-invoice.cgi @@ -0,0 +1,30 @@ +<% $cgi->redirect("${p}view/cust_main.cgi?$custnum") %> +<%once> + +my %method = ( map { $_=>1 } qw( email print fax_invoice ) ); + +</%once> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Resend invoices'); + +my $invnum      = $cgi->param('invnum'); +my $template    = $cgi->param('template'); +my $notice_name = $cgi->param('notice_name') if $cgi->param('notice_name'); +my $method      = $cgi->param('method'); + +$method .= '_invoice' if $method eq 'fax'; #! + +die "unknown method $method" unless $method{$method}; + +my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum}); +die "Can't find invoice!\n" unless $cust_bill; + +$cust_bill->$method({ 'template'    => $template, +                      'notice_name' => $notice_name, +                   });  + +my $custnum = $cust_bill->getfield('custnum'); + +</%init> diff --git a/httemplate/misc/send-statement.cgi b/httemplate/misc/send-statement.cgi new file mode 100755 index 000000000..e363fbd09 --- /dev/null +++ b/httemplate/misc/send-statement.cgi @@ -0,0 +1,28 @@ +<% $cgi->redirect("${p}view/cust_main.cgi?$custnum") %> +<%once> + +my %method = map { $_=>1 } qw( email print fax_invoice ); + +</%once> +<%init> + +die "access denied" +  unless $FS::CurrentUser::CurrentUser->access_right('Resend invoices'); + +my $statementnum = $cgi->param('statementnum'); +my $template     = $cgi->param('template') || 'statement'; #XXX configure... via event??  eh.. +my $notice_name  = $cgi->param('notice_name') if $cgi->param('notice_name'); +my $method       = $cgi->param('method'); + +$method .= '_invoice' if $method eq 'fax'; #! + +die "unknown method $method" unless $method{$method}; + +my $cust_statement = qsearchs('cust_statement',{'statementnum'=>$statementnum}); +die "Can't find statement!\n" unless $cust_statement; + +$cust_statement->$method({ 'template' => $template });  + +my $custnum = $cust_statement->getfield('custnum'); + +</%init> diff --git a/httemplate/search/cust_event.html b/httemplate/search/cust_event.html index 715d1ca9a..f8cf6b2a6 100644 --- a/httemplate/search/cust_event.html +++ b/httemplate/search/cust_event.html @@ -75,29 +75,34 @@ my $status_sub = sub {    my $part_event = $cust_event->part_event; -  if ( $part_event->eventtable eq 'cust_bill' && $part_event->templatename ) { -    my $alt_templatename = $part_event->templatename; -    my $alt_link = "$alt_templatename-". $cust_event->tablenum; +  if ( $part_event->eventtable eq 'cust_bill' +       && ( $part_event->templatename || $part_event->option('notice_name') ) +     ) +  { +    my $link = 'invnum='. $cust_event->tablenum; +    $link .= ';template='. uri_escape($part_event->templatename) +      if $part_event->templatename; +    $link .= ';notice_name='. uri_escape($part_event->option('notice_name')) +      if $part_event->option('notice_name');      my $conf = new FS::Conf;      my $cust_bill = $cust_event->cust_X;      $status .= qq{ -          ( <A HREF="${p}view/cust_bill.cgi?$alt_link">view</A> -          | <A HREF="${p}view/cust_bill-pdf.cgi?$alt_link.pdf">view -              typeset</A> -          | <A HREF="${p}misc/print-invoice.cgi?$alt_link">re-print</A> +          ( <A HREF="${p}view/cust_bill.cgi?$link">view</A> +          | <A HREF="${p}view/cust_bill-pdf.cgi?$link">view typeset</A> +          | <A HREF="${p}misc/send-invoice.cgi?method=print;$link">re-print</A>      };      if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) {         $status .= qq{ -            | <A HREF="${p}misc/email-invoice.cgi?$alt_link">re-email</A> +            | <A HREF="${p}misc/send-invoice.cgi?method=email;$link">re-email</A>        };      }       if ( $conf->exists('hylafax') && length($cust_bill->cust_main->fax) ) {         $status .= qq{ -            | <A HREF="${p}misc/fax-invoice.cgi?$alt_link">re-fax</A> +            | <A HREF="${p}misc/send-invoice.cgi?method=fax;$link">re-fax</A>        }      }  diff --git a/httemplate/view/cust_bill-pdf.cgi b/httemplate/view/cust_bill-pdf.cgi index f09e1b74d..51e47e00d 100755 --- a/httemplate/view/cust_bill-pdf.cgi +++ b/httemplate/view/cust_bill-pdf.cgi @@ -4,11 +4,23 @@  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('View invoices'); -#untaint invnum +my( $invnum, $template, $notice_name );  my($query) = $cgi->keywords; -$query =~ /^((.+)-)?(\d+)(.pdf)?$/; -my $templatename = $2; -my $invnum = $3; +if ( $query =~ /^((.+)-)?(\d+)(.pdf)?$/ ) { +  $template = $2; +  $invnum = $3; +  $notice_name = 'Invoice'; +} else { +  $invnum = $cgi->param('invnum'); +  $invnum =~ s/\.pdf//i; +  $template = $cgi->param('template'); +  $notice_name = ( $cgi->param('notice_name') || 'Invoice' ); +} + +my %opt = ( +  'template'    => $template, +  'notice_name' => $notice_name, +);  my $cust_bill = qsearchs({    'select'    => 'cust_bill.*', @@ -19,7 +31,7 @@ my $cust_bill = qsearchs({  });  die "Invoice #$invnum not found!" unless $cust_bill; -my $pdf = $cust_bill->print_pdf( '', $templatename); +my $pdf = $cust_bill->print_pdf(\%opt);  http_header('Content-Type' => 'application/pdf' );  http_header('Content-Length' => length($pdf) ); diff --git a/httemplate/view/cust_bill-ps.cgi b/httemplate/view/cust_bill-ps.cgi index 5313dbf02..881491f69 100755 --- a/httemplate/view/cust_bill-ps.cgi +++ b/httemplate/view/cust_bill-ps.cgi @@ -1,14 +1,25 @@ -<% $cust_bill->print_ps( '', $templatename) %> +<% $cust_bill->print_ps(\%opt) %>  <%init>  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('View invoices'); -#untaint invnum +my( $invnum, $template, $notice_name );  my($query) = $cgi->keywords; -$query =~ /^((.+)-)?(\d+)$/; -my $templatename = $2; -my $invnum = $3; +if ( $query =~ /^((.+)-)?(\d+)(.pdf)?$/ ) { +  $template = $2; +  $invnum = $3; +  $notice_name = 'Invoice'; +} else { +  $invnum = $cgi->param('invnum'); +  $template = $cgi->param('template'); +  $notice_name = ( $cgi->param('notice_name') || 'Invoice' ); +} + +my %opt = ( +  'template'    => $template, +  'notice_name' => $notice_name, +);  my $cust_bill = qsearchs({    'select'    => 'cust_bill.*', diff --git a/httemplate/view/cust_bill.cgi b/httemplate/view/cust_bill.cgi index 5540221d9..ce8d96a95 100755 --- a/httemplate/view/cust_bill.cgi +++ b/httemplate/view/cust_bill.cgi @@ -60,14 +60,14 @@  % if ( $curuser->access_right('Resend invoices') ) { -    <A HREF="<% $p %>misc/print-invoice.cgi?<% $link %>">Re-print this invoice</A> +    <A HREF="<% $p %>misc/send-invoice.cgi?method=print;<% $link %>">Re-print this invoice</A>  %   if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) {  -        | <A HREF="<% $p %>misc/email-invoice.cgi?<% $link %>">Re-email this invoice</A> +        | <A HREF="<% $p %>misc/send-invoice.cgi?method=email;<% $link %>">Re-email this invoice</A>  %   }   %   if ( $conf->exists('hylafax') && length($cust_bill->cust_main->fax) ) {  -        | <A HREF="<% $p %>misc/fax-invoice.cgi?<% $link %>">Re-fax this invoice</A> +        | <A HREF="<% $p %>misc/send-invoice.cgi?method=fax;<% $link %>">Re-fax this invoice</A>  %   }       <BR><BR> @@ -76,7 +76,7 @@  % if ( $conf->exists('invoice_latex') ) {  -  <A HREF="<% $p %>view/cust_bill-pdf.cgi?<% $link %>.pdf">View typeset invoice PDF</A> +  <A HREF="<% $p %>view/cust_bill-pdf.cgi?<% $link %>">View typeset invoice PDF</A>    <BR><BR>  % }  @@ -92,11 +92,9 @@  <% $br ? '<BR><BR>' : '' %>  % if ( $conf->exists('invoice_html') ) {  - -  <% join('', $cust_bill->print_html('', $templatename) ) %> +  <% join('', $cust_bill->print_html(\%opt) ) %>  % } else {  - -  <PRE><% join('', $cust_bill->print_text('', $templatename) ) %></PRE> +  <PRE><% join('', $cust_bill->print_text(\%opt) ) %></PRE>  % }   <% include('/elements/footer.html') %> @@ -107,11 +105,22 @@ my $curuser = $FS::CurrentUser::CurrentUser;  die "access denied"    unless $curuser->access_right('View invoices'); -#untaint invnum +my( $invnum, $template, $notice_name );  my($query) = $cgi->keywords; -$query =~ /^((.+)-)?(\d+)$/; -my $templatename = $2; -my $invnum = $3; +if ( $query =~ /^((.+)-)?(\d+)$/ ) { +  $template = $2; +  $invnum = $3; +  $notice_name = 'Invoice'; +} else { +  $invnum = $cgi->param('invnum'); +  $template = $cgi->param('template'); +  $notice_name = $cgi->param('notice_name'); +} + +my %opt = ( +  'template'    => $template, +  'notice_name' => $notice_name, +);  my $conf = new FS::Conf; @@ -135,6 +144,8 @@ my $display_custnum = $cust_bill->cust_main->display_custnum;  #my $printed = $cust_bill->printed; -my $link = $templatename ? "$templatename-$invnum" : $invnum; +my $link = "invnum=$invnum"; +$link .= ';template='. uri_escape($template) if $template; +$link .= ';notice_name='. $notice_name if $notice_name;  </%init> diff --git a/httemplate/view/cust_statement.html b/httemplate/view/cust_statement.html index b078c9d07..74c80d3bc 100755 --- a/httemplate/view/cust_statement.html +++ b/httemplate/view/cust_statement.html @@ -4,16 +4,16 @@  % if ( $FS::CurrentUser::CurrentUser->access_right('Resend invoices') ) { -%#    <A HREF="<% $p %>misc/print-invoice.cgi?<% $link %>">Re-print this statement</A> +%#    <A HREF="<% $p %>misc/send-statement.cgi?method=print;<% $link %>">Re-print this statement</A>  %   if ( grep { $_ ne 'POST' } $cust_statement->cust_main->invoicing_list ) {   %#        | -        <A HREF="<% $p %>misc/email-invoice.cgi?<% $link %>">Re-email this statement</A> +        <A HREF="<% $p %>misc/send-statement.cgi?method=email;<% $link %>">Re-email this statement</A>  %   }   %   if ( 0 ) {  %   #if ( $conf->exists('hylafax') && length($cust_statement->cust_main->fax) ) {  -        | <A HREF="<% $p %>misc/fax-invoice.cgi?<% $link %>">Re-fax this statement</A> +        | <A HREF="<% $p %>misc/send-statement.cgi?method=fax;<% $link %>">Re-fax this statement</A>  %   }       <BR><BR> @@ -73,6 +73,7 @@ die "Statement #$statementnum not found!" unless $cust_statement;  my $custnum = $cust_statement->custnum;  my $display_custnum = $cust_statement->cust_main->display_custnum; -my $link = $templatename ? "$templatename-$statementnum" : $statementnum; +my $link = "statementnum=$statementnum"; +$link .= ';template='. uri_escape($templatename) if $templatename;  </%init> | 
