[freeside-commits] freeside/FS/FS Conf.pm, 1.365, 1.366 Mason.pm, 1.39, 1.40 Schema.pm, 1.219, 1.220 cust_bill.pm, 1.283, 1.284 bill_batch.pm, NONE, 1.1 cust_bill_batch.pm, NONE, 1.1 cust_bill_batch_option.pm, NONE, 1.1

Mark Wells mark at wavetail.420.am
Tue Jun 8 15:25:02 PDT 2010


Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail.420.am:/tmp/cvs-serv29944/FS/FS

Modified Files:
	Conf.pm Mason.pm Schema.pm cust_bill.pm 
Added Files:
	bill_batch.pm cust_bill_batch.pm cust_bill_batch_option.pm 
Log Message:
RT#947: batch download of invoice PDFs

Index: Conf.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Conf.pm,v
retrieving revision 1.365
retrieving revision 1.366
diff -u -w -d -r1.365 -r1.366
--- Conf.pm	7 Jun 2010 02:39:17 -0000	1.365
+++ Conf.pm	8 Jun 2010 22:24:59 -0000	1.366
@@ -1036,6 +1036,12 @@
     'type'        => 'textarea'
   },
 
+  {
+    'key'         => 'invoice_print_pdf',
+    'section'     => 'invoicing',
+    'description' => 'Store postal invoices for download in PDF format rather than printing them directly.',
+    'type'        => 'checkbox',
+  },
 
   { 
     'key'         => 'invoice_default_terms',

Index: Mason.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Mason.pm,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -w -d -r1.39 -r1.40
--- Mason.pm	6 Jun 2010 06:21:47 -0000	1.39
+++ Mason.pm	8 Jun 2010 22:24:59 -0000	1.40
@@ -240,6 +240,8 @@
   use FS::cgp_rule;
   use FS::cgp_rule_condition;
   use FS::cgp_rule_action;
+  use FS::bill_batch;
+  use FS::cust_bill_batch;
   # Sammath Naur
 
   if ( $FS::Mason::addl_handler_use ) {

--- NEW FILE: cust_bill_batch.pm ---
package FS::cust_bill_batch;

use strict;
use vars qw( @ISA $me $DEBUG );
use FS::Record qw( qsearch qsearchs dbh );

@ISA = qw( FS::option_Common );
$me = '[ FS::cust_bill_batch ]';
$DEBUG=0;

sub table { 'cust_bill_batch' }

=head1 NAME

FS::cust_bill_batch - Object methods for cust_bill_batch records

=head1 DESCRIPTION

An FS::cust_bill_batch object represents the inclusion of an invoice in a 
processing batch.  FS::cust_bill_batch inherits from FS::option_Common.  The 
following fields are currently supported:

=over 4

=item billbatchnum - primary key

=item invnum - invoice number (see C<FS::cust_bill>)

=item batchnum - batchn number (see C<FS::bill_batch>)

=back

=head1 METHODS

=over 4

=item bill_batch

Returns the C<FS::bill_batch> object.

=cut

sub bill_batch { 
  my $self = shift;
  FS::bill_batch->by_key($self->batchnum);
}

=item cust_bill

Returns the C<FS::cust_bill> object.

=cut

sub cust_bill {
  my $self = shift;
  FS::cust_bill->by_key($self->invnum);
}

=back

=head1 BUGS

=head1 SEE ALSO

L<FS::Record>, schema.html from the base documentation.

=cut

1;


--- NEW FILE: cust_bill_batch_option.pm ---
package FS::cust_bill_batch_option;

use strict;
use vars qw( @ISA );
use FS::Record qw( qsearch qsearchs );

@ISA = qw(FS::Record);

=head1 NAME

FS::cust_bill_batch_option - Object methods for cust_bill_batch_option records

=head1 SYNOPSIS

  use FS::cust_bill_batch_option;

  $record = new FS::cust_bill_batch_option \%hash;
  $record = new FS::cust_bill_batch_option { 'column' => 'value' };

  $error = $record->insert;

  $error = $new_record->replace($old_record);

  $error = $record->delete;

  $error = $record->check;

=head1 DESCRIPTION

An FS::cust_bill_batch_option object represents an option key and value for
an invoice batch entry.  FS::cust_bill_batch_option inherits from
FS::Record.  The following fields are currently supported:

=over 4

=item optionnum - primary key

=item billbatchnum - 

=item optionname - 

=item optionvalue - 


=back

=head1 METHODS

=over 4

=item new HASHREF

Creates a new option.  To add the option to the database, see L<"insert">.

Note that this stores the hash reference, not a distinct copy of the hash it
points to.  You can ask the object for a copy with the I<hash> method.

=cut

# the new method can be inherited from FS::Record, if a table method is defined

sub table { 'cust_bill_batch_option'; }

=item insert

Adds this record to the database.  If there is an error, returns the error,
otherwise returns false.

=cut

# the insert method can be inherited from FS::Record

=item delete

Delete this record from the database.

=cut

# the delete method can be inherited from FS::Record

=item replace OLD_RECORD

Replaces the OLD_RECORD with this one in the database.  If there is an error,
returns the error, otherwise returns false.

=cut

# the replace method can be inherited from FS::Record

=item check

Checks all fields to make sure this is a valid option.  If there is
an error, returns the error, otherwise returns false.  Called by the insert
and replace methods.

=cut

# the check method should currently be supplied - FS::Record contains some
# data checking routines

sub check {
  my $self = shift;

  my $error = 
    $self->ut_numbern('optionnum')
    || $self->ut_foreign_key('billbatchnum', 'cust_bill_batch', 'billbatchnum')
    || $self->ut_text('optionname')
    || $self->ut_textn('optionvalue')
  ;
  return $error if $error;

  $self->SUPER::check;
}

=back

=head1 BUGS

=head1 SEE ALSO

L<FS::Record>, schema.html from the base documentation.

=cut

1;


Index: cust_bill.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill.pm,v
retrieving revision 1.283
retrieving revision 1.284
diff -u -w -d -r1.283 -r1.284
--- cust_bill.pm	21 May 2010 21:18:29 -0000	1.283
+++ cust_bill.pm	8 Jun 2010 22:24:59 -0000	1.284
@@ -34,6 +34,8 @@
 use FS::cust_bill_pay_batch;
 use FS::part_bill_event;
 use FS::payby;
+use FS::bill_batch;
+use FS::cust_bill_batch;
 
 @ISA = qw( FS::cust_main_Mixin FS::Record );
 
@@ -1300,8 +1302,14 @@
     'notice_name' => $notice_name,
   );
 
+  if($conf->exists('invoice_print_pdf')) {
+    # Add the invoice to the current batch.
+    $self->batch_invoice(\%opt);
+  }
+  else {
   do_print $self->lpr_data(\%opt);
 }
+}
 
 =item fax_invoice HASHREF | [ TEMPLATE ] 
 
@@ -1346,6 +1354,23 @@
 
 }
 
+=item batch_invoice [ HASHREF ]
+
+Place this invoice into the open batch (see C<FS::bill_batch>).  If there 
+isn't an open batch, one will be created.
+
+=cut
+
+sub batch_invoice {
+  my ($self, $opt) = @_;
+  my $batch = FS::bill_batch->get_open_batch;
+  my $cust_bill_batch = FS::cust_bill_batch->new({
+      batchnum => $batch->batchnum,
+      invnum   => $self->invnum,
+  });
+  return $cust_bill_batch->insert($opt);
+}
+
 =item ftp_invoice [ TEMPLATENAME ] 
 
 Sends this invoice data via FTP.

Index: Schema.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Schema.pm,v
retrieving revision 1.219
retrieving revision 1.220
diff -u -w -d -r1.219 -r1.220
--- Schema.pm	7 Jun 2010 00:10:11 -0000	1.219
+++ Schema.pm	8 Jun 2010 22:24:59 -0000	1.220
@@ -2848,6 +2848,41 @@
       'index'       => [['listnum'],['svcnum'],['contactemailnum'],['email']],
     },
 
+    'bill_batch' => {
+      'columns' => [
+        'batchnum',         'serial',     '', '', '', '',
+        'status',             'char', 'NULL','1', '', '',
+        'pdf',                'blob', 'NULL', '', '', '',
+      ],
+      'primary_key' => 'batchnum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    'cust_bill_batch' => {
+      'columns' => [
+        'billbatchnum',     'serial',     '', '', '', '',
+        'batchnum',            'int',     '', '', '', '',
+        'invnum',              'int',     '', '', '', '',
+      ],
+      'primary_key' => 'billbatchnum',
+      'unique'      => [],
+      'index'       => [ [ 'batchnum' ], [ 'invnum' ] ],
+    },
+
+    'cust_bill_batch_option' => {
+      'columns' => [
+        'optionnum', 'serial', '', '', '', '', 
+        'billbatchnum', 'int', '', '', '', '', 
+        'optionname', 'varchar', '', $char_d, '', '', 
+        'optionvalue', 'text', 'NULL', '', '', '', 
+      ],
+      'primary_key' => 'optionnum',
+      'unique'      => [],
+      'index'       => [ [ 'billbatchnum' ], [ 'optionname' ] ],
+    },
+
+
 
     # name type nullability length default local
 

--- NEW FILE: bill_batch.pm ---
package FS::bill_batch;

use strict;
use vars qw( @ISA $me $DEBUG );
use FS::Record qw( qsearch qsearchs dbh );
use FS::cust_bill_batch;

@ISA = qw( FS::Record );
$me = '[ FS::bill_batch ]';
$DEBUG=0;

sub table { 'bill_batch' }

sub nohistory_fields { 'pdf' }

=head1 NAME

FS::bill_batch - Object methods for bill_batch records

=head1 SYNOPSIS

  use FS::bill_batch;

  $open_batch = FS::bill_batch->get_open_batch;
  
  my $pdf = $open_batch->print_pdf;
  
  $error = $open_batch->close;
  
=head1 DESCRIPTION

An FS::bill_batch object represents a batch of invoices.  FS::bill_batch 
inherits from FS::Record.  The following fields are currently supported:

=over 4

=item batchnum - primary key

=item status - either 'O' (open) or 'R' (resolved/closed).

=item pdf - blob field for temporarily storing the invoice as a PDF.

=back

=head1 METHODS

=over 4

=item print_pdf

Typeset the entire batch as a PDF file.  Returns the PDF as a string.

=cut

sub print_pdf {
  eval 'use CAM::PDF';
  warn "Failed to load CAM::PDF: '$@'\n" if $@;

  my $self = shift;
  my $job = shift;
  $job->update_statustext(0) if $job;
  my @invoices = sort { $a->invnum <=> $b->invnum }
                 qsearch('cust_bill_batch', { batchnum => $self->batchnum });
  return "No invoices in batch ".$self->batchnum.'.' if !@invoices;

  my $pdf_out;
  my $num = 0;
  foreach my $invoice (@invoices) {
    my $part = $invoice->cust_bill->print_pdf({$invoice->options});
    die 'Failed creating PDF from invoice '.$invoice->invnum.'\n' if !$part;

    if($pdf_out) {
      $pdf_out->appendPDF(CAM::PDF->new($part));
    }
    else {
      $pdf_out = CAM::PDF->new($part);
    }
    if($job) {
      # update progressbar
      $num++;
      my $error = $job->update_statustext(int(100 * $num/scalar(@invoices)));
      die $error if $error;
    }
  }

  return $pdf_out->toPDF;
}

=item close

Set the status of the batch to 'R' (resolved).

=cut

sub close {
  my $self = shift;
  $self->status('R');
  return $self->replace;
}

=back

=head1 CLASS METHODS

=item get_open_batch

Returns the currently open batch.  There should only be one at a time.

=cut

sub get_open_batch {
  my $class = shift;
  my $batch = qsearchs('bill_batch', { status => 'O' });
  return $batch if $batch;
  $batch = FS::bill_batch->new({status => 'O'});
  my $error = $batch->insert;
  die $error if $error;
  return $batch;
}

use Storable 'thaw';
use Data::Dumper;
use MIME::Base64;

sub process_print_pdf {
  my $job = shift;
  my $param = thaw(decode_base64(shift));
  warn Dumper($param) if $DEBUG;
  die "no batchnum specified!\n" if ! exists($param->{batchnum});
  my $batch = FS::bill_batch->by_key($param->{batchnum});
  die "batch '$param->{batchnum}' not found!\n" if !$batch;

  my $pdf = $batch->print_pdf($job);
  $batch->pdf($pdf);
  my $error = $batch->replace;
  die $error if $error;
}


=back

=head1 BUGS

=head1 SEE ALSO

L<FS::Record>, schema.html from the base documentation.

=cut

1;




More information about the freeside-commits mailing list