+
+my $link = '';
+if ( ( $curuser->access_right('View invoices') #XXX for now
+ || $curuser->access_right('View customer payments')
+ )
+ && ! $opt{'disable_link'}
+ )
+{
+
+ my $key;
+ my $q = '';
+ if ( $table eq 'cust_pay_void' ) {
+ $key = 'paynum';
+ $q .= 'void=1;';
+ } elsif ( $table eq /^cust_(\w+)$/ ) {
+ $key = $1.'num';
+ }
+
+ if ( $key ) {
+ $q .= "$key=";
+ $link = [ "${p}view/$table.html?$q", $key ]
+ }
+}
+
+my $cust_link = sub {
+ my $cust_thing = shift;
+ $cust_thing->cust_main_custnum
+ ? [ "${p}view/cust_main.cgi?", 'custnum' ]
+ : '';
+};
+
+# only valid for $table == 'cust_pay' atm
+my $tax_names = '';
+if ( $cgi->param('tax_names') ) {
+ if ( dbh->{Driver}->{Name} eq 'Pg' ) {
+
+ $tax_names = "
+ array_to_string(
+ array(
+ SELECT itemdesc
+ FROM cust_bill_pay
+ LEFT JOIN cust_bill_pay_pkg USING ( billpaynum )
+ LEFT JOIN cust_bill_pkg USING ( billpkgnum )
+ WHERE cust_bill_pkg.pkgnum = 0
+ AND cust_bill_pay.paynum = cust_pay.paynum
+ ), '|'
+ ) AS tax_names"
+ ;
+
+ } elsif ( dbh->{Driver}->{Name} =~ /^mysql/i ) {
+
+ $tax_names = "GROUP_CONCAT(itemdesc SEPARATOR '|') AS tax_names";
+
+ } else {
+
+ warn "warning: unknown database type ". dbh->{Driver}->{Name}.
+ "omitting tax name information from report.";
+
+ }
+}
+
+my @header = ();
+my @fields = ();
+my $align = '';
+my @links = ();
+if ( $opt{'pre_header'} ) {
+ push @header, @{ $opt{'pre_header'} };
+ $align .= 'c' x scalar(@{ $opt{'pre_header'} });
+ push @links, map '', @{ $opt{'pre_header'} };
+ push @fields, @{ $opt{'pre_fields'} };
+}
+
+push @header, "\u$name_singular",
+ 'Amount',
+ 'Date',
+;
+$align .= 'rrr';
+push @links, '', '', '';
+push @fields, 'payby_payinfo_pretty',
+ sub { sprintf('$%.2f', shift->$amount_field() ) },
+ sub { time2str('%b %d %Y', shift->_date ) },
+;
+
+unless ( $opt{'disable_by'} ) {
+ push @header, 'By';
+ $align .= 'c';
+ push @links, '';
+ push @fields, sub { my $o = shift->otaker;
+ $o = 'auto billing' if $o eq 'fs_daily';
+ $o = 'customer self-service' if $o eq 'fs_selfservice';
+ $o;
+ };
+}
+
+if ( $tax_names ) {
+ push @header, ('Tax names', 'Tax province');
+ $align .= 'cc';
+ push @links, ('','');
+ push @fields, sub { join (' + ', map { /^(.*?)(, \w\w)?$/; $1 }
+ split('\|', shift->tax_names)
+ );
+ };
+ push @fields, sub { join (' + ', map { if (/^(?:.*)(?:, )(\w\w)$/){ $1 }
+ else { () }
+ }
+ split('\|', shift->tax_names)
+ );
+ };
+}
+
+push @header, FS::UI::Web::cust_header();
+$align .= FS::UI::Web::cust_aligns();
+push @links, map { $_ ne 'Cust. Status' ? $cust_link : '' }
+ FS::UI::Web::cust_header();
+my @color = ( ( map '', @fields ), FS::UI::Web::cust_colors() );
+my @style = ( ( map '', @fields ), FS::UI::Web::cust_styles() );
+push @fields, \&FS::UI::Web::cust_fields;
+
+push @header, @{ $opt{'addl_header'} }
+ if $opt{'addl_header'};
+push @fields, @{ $opt{'addl_fields'} }
+ if $opt{'addl_fields'};
+