| version 1.46, 2012/01/27 04:13:45 |
version 1.47, 2012/01/31 04:36:28 |
|
|
| #!/usr/bin/perl |
#!/usr/bin/perl |
| # $AFresh1: rt_invoices.pl,v 1.45 2011/12/31 02:14:32 andrew Exp $ |
# $AFresh1: rt_invoices.pl,v 1.46 2012/01/27 04:13:45 andrew Exp $ |
| ######################################################################## |
######################################################################## |
| # Copyright (c) 2011 Andrew Fresh <andrew@afresh1.com> |
# Copyright (c) 2011 Andrew Fresh <andrew@afresh1.com> |
| # |
# |
|
|
| use File::Path; |
use File::Path; |
| use DateTime; |
use DateTime; |
| |
|
| |
use List::Util qw/ sum /; |
| |
|
| use lib './lib'; # XXX This is fragile, there are better ways |
use lib './lib'; # XXX This is fragile, there are better ways |
| use RTI::Config; |
use RTI::Config; |
| use RTI::State; |
use RTI::State; |
|
|
| |
|
| if ( my $unpaid_invoices = $state->unpaid_invoices() ) { |
if ( my $unpaid_invoices = $state->unpaid_invoices() ) { |
| foreach my $custid ( keys %{$unpaid_invoices} ) { |
foreach my $custid ( keys %{$unpaid_invoices} ) { |
| my %project = ( title => 'Unpaid Invoices', fees => [], ); |
my %project |
| |
= ( title => 'Unpaid Invoices', fees => [], no_total => 1 ); |
| my $past_due = 0; |
my $past_due = 0; |
| my $unpaid = 0; |
my $unpaid = 0; |
| |
|
|
|
| |
|
| my $content |
my $content |
| = sprintf( "Invoice %06d from %s", $id, $invdate->ymd ); |
= sprintf( "Invoice %06d from %s", $id, $invdate->ymd ); |
| if ( $cust->{duedate} |
if ( $cust->{duedate} && $invdate < $cust->{duedate}) { |
| && DateTime->compare( $invdate, $cust->{duedate} ) > 0 ) |
|
| { |
|
| $content = "PAST DUE: $content"; |
$content = "PAST DUE: $content"; |
| $past_due += $unpaid_invoices->{$custid}->{$id}; |
$past_due += $unpaid_invoices->{$custid}->{$id}; |
| } |
} |
|
|
| } |
} |
| |
|
| if ($past_due) { |
if ($past_due) { |
| $cust->{invoice} ||= make_invoice(); |
$cust->{invoice} ||= make_invoice($cust); |
| |
|
| $cust->{invoice}->{past_due} = $past_due; |
$cust->{invoice}->{past_due} = $past_due; |
| $cust->{invoice}->{unpaid} = $unpaid; |
$cust->{invoice}->{unpaid} = $unpaid; |
| $cust->{invoice}->{total_due} |
|
| = $cust->{invoice}->{total} + $past_due + $unpaid; |
|
| |
|
| unshift @{ $cust->{invoice}->{projects} }, \%project; |
unshift @{ $cust->{invoice}->{projects} }, \%project; |
| } |
} |
|
|
| $subtotal += round( $expense->{amount} ); |
$subtotal += round( $expense->{amount} ); |
| } |
} |
| $project->{total} = $subtotal; |
$project->{total} = $subtotal; |
| |
|
| |
next if $project->{no_total}; |
| $invoice->{total} += $subtotal; |
$invoice->{total} += $subtotal; |
| } |
} |
| @{ $invoice->{transactions} } = sort { $a <=> $b } keys %transactions; |
@{ $invoice->{transactions} } = sort { $a <=> $b } keys %transactions; |
|
|
| $invoice->{total} -= round( $invoice->{discount}{amount} ); |
$invoice->{total} -= round( $invoice->{discount}{amount} ); |
| } |
} |
| |
|
| |
if ($invoice->{past_due}) { |
| |
$invoice->{total_due} |
| |
= sum( @{ $invoice }{ qw/ total past_due unpaid / } ); |
| |
} |
| |
|
| next unless $invoice->{total} > 0 || $invoice->{total_due}; |
next unless $invoice->{total} > 0 || $invoice->{total_due}; |
| |
|
| $invoice->{info} = $config->get('info'); |
$invoice->{info} = $config->get('info'); |
|
|
| sub make_invoice { |
sub make_invoice { |
| my ($cust) = @_; |
my ($cust) = @_; |
| |
|
| my %invoice |
my %invoice = ( |
| = ( end => $cust->{billend}->clone->subtract( seconds => 1 ) ); |
end => $cust->{billend}->clone->subtract( seconds => 1 ), |
| |
total => 0, |
| |
); |
| $invoice{start} = $cust->{startinvoicedate}->clone |
$invoice{start} = $cust->{startinvoicedate}->clone |
| if $cust->{startinvoicedate}; |
if $cust->{startinvoicedate}; |
| |
|