From 982ded2d929bdcdfa72efa810273f3bc753bf036 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 20 Jul 2011 18:34:19 +0000 Subject: [PATCH] per-agent invoice PDF batches, RT#13727 --- FS/FS/AccessRight.pm | 8 +++-- FS/FS/Conf.pm | 9 +++++- FS/FS/Schema.pm | 9 +++--- FS/FS/bill_batch.pm | 43 +++++++++++++++++--------- FS/FS/cust_bill.pm | 26 ++++++++++++++-- FS/FS/part_event/Action/cust_bill_print.pm | 23 ++++++++++++++ FS/FS/part_event/Action/cust_bill_print_pdf.pm | 26 ++++++++++++++++ httemplate/elements/menu.html | 7 +++-- httemplate/search/bill_batch.cgi | 23 ++++++++++---- 9 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 FS/FS/part_event/Action/cust_bill_print.pm create mode 100644 FS/FS/part_event/Action/cust_bill_print_pdf.pm diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 2f6f53101..458f9694e 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -272,9 +272,11 @@ tie my %rights, 'Tie::IxHash', 'Miscellaneous rights' => [ { rightname=>'Job queue', global=>1 }, { rightname=>'Time queue', global=>1 }, - { rightname=>'Process batches', global=>1 }, - { rightname=>'Reprocess batches', global=>1 }, - { rightname=>'Redownload resolved batches', global=>1 }, + { rightname=>'Process batches', global=>1 }, #Process payment batches + { rightname=>'Reprocess batches', global=>1 }, #Reprocess payment batches + { rightname=>'Redownload resolved batches', global=>1 }, #Redownload resolved payment batches + { rightname=>'Process invoice batches', }, + { rightname=>'Process global invoice batches', global=>1 }, { rightname=>'Import', global=>1 }, #some of these are ag-virt'ed now? give em their own ACLs { rightname=>'Export', global=>1 }, { rightname=> 'Edit rating data', desc=>'Delete CDRs', global=>1 }, diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 774332253..9953ea54b 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1258,7 +1258,14 @@ and customer address. Include units.', { 'key' => 'invoice_print_pdf', 'section' => 'invoicing', - 'description' => 'Store postal invoices for download in PDF format rather than printing them directly.', + 'description' => 'For all invoice print operations, store postal invoices for download in PDF format rather than printing them directly.', + 'type' => 'checkbox', + }, + + { + 'key' => 'invoice_print_pdf-spoolagent', + 'section' => 'invoicing', + 'description' => 'Store postal invoices PDF downloads in per-agent spools.', 'type' => 'checkbox', }, diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 168fae0ff..6fde8b1e5 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3339,13 +3339,14 @@ sub tables_hashref { 'bill_batch' => { 'columns' => [ - 'batchnum', 'serial', '', '', '', '', - 'status', 'char', 'NULL','1', '', '', - 'pdf', 'blob', 'NULL', '', '', '', + 'batchnum', 'serial', '', '', '', '', + 'agentnum', 'int', 'NULL', '', '', '', + 'status', 'char', 'NULL', '1', '', '', + 'pdf', 'blob', 'NULL', '', '', '', ], 'primary_key' => 'batchnum', 'unique' => [], - 'index' => [], + 'index' => [ ['agentnum'] ], }, 'cust_bill_batch' => { diff --git a/FS/FS/bill_batch.pm b/FS/FS/bill_batch.pm index 3afe20915..ec5c19456 100644 --- a/FS/FS/bill_batch.pm +++ b/FS/FS/bill_batch.pm @@ -2,9 +2,11 @@ package FS::bill_batch; use strict; use vars qw( @ISA $me $DEBUG ); +use CAM::PDF; +use FS::Conf; use FS::Record qw( qsearch qsearchs dbh ); +use FS::agent; use FS::cust_bill_batch; -use CAM::PDF; @ISA = qw( FS::Record ); $me = '[ FS::bill_batch ]'; @@ -37,6 +39,8 @@ inherits from FS::Record. The following fields are currently supported: =item batchnum - primary key +=item agentnum - empty for global batches or agent (see L) + =item status - either 'O' (open) or 'R' (resolved/closed). =item pdf - blob field for temporarily storing the invoice as a PDF. @@ -96,26 +100,38 @@ sub close { return $self->replace; } -=back +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('batchnum') + || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum') + || $self->ut_enum('status', [ 'O', 'R' ] ) + ; + return $error if $error; -=head1 CLASS METHODS + $self->SUPER::check; +} -=item get_open_batch +=item agent -Returns the currently open batch. There should only be one at a time. +Returns the agent (see L) for this invoice batch. =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; +sub agent { + my $self = shift; + qsearchs( 'agent', { 'agentnum' => $self->agentnum } ); } +=back + +=head1 SUBROUTINES + +=item process_print_pdf + +=cut + use Storable 'thaw'; use Data::Dumper; use MIME::Base64; @@ -134,7 +150,6 @@ sub process_print_pdf { die $error if $error; } - =back =head1 BUGS diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 6e4eba426..7669479eb 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -1520,14 +1520,36 @@ isn't an open batch, one will be created. sub batch_invoice { my ($self, $opt) = @_; - my $batch = FS::bill_batch->get_open_batch; + my $bill_batch = $self->get_open_bill_batch; my $cust_bill_batch = FS::cust_bill_batch->new({ - batchnum => $batch->batchnum, + batchnum => $bill_batch->batchnum, invnum => $self->invnum, }); return $cust_bill_batch->insert($opt); } +=item get_open_batch + +Returns the currently open batch as an FS::bill_batch object, creating a new +one if necessary. (A per-agent batch if invoice_print_pdf-spoolagent is +enabled) + +=cut + +sub get_open_bill_batch { + my $self = shift; + my $hashref = { status => 'O' }; + $hashref->{'agentnum'} = $conf->exists('invoice_print_pdf-spoolagent') + ? $self->cust_main->agentnum + : ''; + my $batch = qsearchs('bill_batch', $hashref); + return $batch if $batch; + $batch = FS::bill_batch->new($hashref); + my $error = $batch->insert; + die $error if $error; + return $batch; +} + =item ftp_invoice [ TEMPLATENAME ] Sends this invoice data via FTP. diff --git a/FS/FS/part_event/Action/cust_bill_print.pm b/FS/FS/part_event/Action/cust_bill_print.pm new file mode 100644 index 000000000..6b3e6f460 --- /dev/null +++ b/FS/FS/part_event/Action/cust_bill_print.pm @@ -0,0 +1,23 @@ +package FS::part_event::Action::cust_bill_print; + +use strict; +use base qw( FS::part_event::Action ); + +sub description { 'Send invoice (print only)'; } + +sub eventtable_hashref { + { 'cust_bill' => 1 }; +} + +sub default_weight { 51; } + +sub do_action { + my( $self, $cust_bill ) = @_; + + #my $cust_main = $self->cust_main($cust_bill); + my $cust_main = $cust_bill->cust_main; + + $cust_bill->print; +} + +1; diff --git a/FS/FS/part_event/Action/cust_bill_print_pdf.pm b/FS/FS/part_event/Action/cust_bill_print_pdf.pm new file mode 100644 index 000000000..6b37f389f --- /dev/null +++ b/FS/FS/part_event/Action/cust_bill_print_pdf.pm @@ -0,0 +1,26 @@ +package FS::part_event::Action::cust_bill_print_pdf; + +use strict; +use base qw( FS::part_event::Action ); + +sub description { 'Send invoice (spool PDF only)'; } + +sub eventtable_hashref { + { 'cust_bill' => 1 }; +} + +sub default_weight { 51; } + +sub do_action { + my( $self, $cust_bill ) = @_; + + #my $cust_main = $self->cust_main($cust_bill); + #my $cust_main = $cust_bill->cust_main; + + my $opt = { $self->options }; + $opt->{'notice_name'} ||= 'Invoice'; + + $cust_bill->batch_invoice($opt); +} + +1; diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 1064836fb..cd9fe06a1 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -395,8 +395,11 @@ $tools_menu{'Quick payment entry'} = [ $fsurl.'misc/batch-cust_pay.html', 'Ente $tools_menu{'Process payment batches'} = [ $fsurl.'search/pay_batch.cgi?magic=_date;open=1;intransit=1', 'Process credit card and electronic check batches' ] if ( $conf->exists('batch-enable') || $conf->config('batch-enable_payby') ) && $curuser->access_right('Process batches'); -$tools_menu{'Download invoice batches'} = [ $fsurl.'search/bill_batch.cgi' ] - if $conf->exists('invoice_print_pdf'); +$tools_menu{'Download invoice batches'} = [ $fsurl.'search/bill_batch.cgi' ] + if $curuser->access_right('Process invoice batches') + || $curuser->access_right('Process global invoice batches') + || $curuser->access_right('Configuration'); #XXX remove in 2.5 + #now there's a standalone event#if $conf->exists('invoice_print_pdf'); $tools_menu{'Bulk DID Orders'} = [ $fsurl.'browse/did_order.html', 'View/manage bulk DID orders' ] if $curuser->access_right('Import'); $tools_menu{'Job Queue'} = [ $fsurl.'search/queue.html', 'View pending job queue' ] diff --git a/httemplate/search/bill_batch.cgi b/httemplate/search/bill_batch.cgi index 72e5d3a8b..6d7e18fee 100755 --- a/httemplate/search/bill_batch.cgi +++ b/httemplate/search/bill_batch.cgi @@ -3,10 +3,10 @@ 'name_singular' => 'batch', 'query' => { 'table' => 'bill_batch', 'hashref' => $hashref, - 'extra_sql' => $extra_sql. - 'ORDER BY batchnum DESC', + #'extra_sql' => $extra_sql. + 'order_by' => 'ORDER BY batchnum DESC', }, - 'count_query' => "$count_query $extra_sql", + 'count_query' => $count_query, 'header' => [ 'Batch', 'Item Count', 'Status', @@ -42,19 +42,30 @@ sub { shift->status eq 'O' ? "b" : '' }, ], 'really_disable_download' => 1, + 'agent_virt' => 1, + 'agent_null_right' => [ 'Process global invoice batches', 'Configuration' ], + 'agent_pos' => 1, + ) %> <%init> +my $curuser = $FS::CurrentUser::CurrentUser; + die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('View invoices'); + unless $curuser->access_right('Process invoice batches') + || $curuser->access_right('Process global invoice batches') + || $curuser->access_right('Configuration'); #remove in 2.5 my %statusmap = ('O'=>'Open', 'R'=>'Closed'); my $hashref = {}; -my $count_query = 'SELECT COUNT(*) FROM bill_batch'; +my $count_query = "SELECT COUNT(*) FROM bill_batch WHERE". # $extra_sql AND " + $curuser->agentnums_sql( + 'null_right' => ['Process global invoice batches', 'Configuration' ], + ); -my $extra_sql = ''; # may add something here later +#my $extra_sql = ''; # may add something here later my $link = [ "${p}view/bill_batch.cgi?batchnum=", 'batchnum' ]; my $dlink = sub { [ "${p}view/bill_batch.cgi?start_download=1;". -- 2.11.0