version 1.1, 2011/12/22 04:52:42 |
version 1.7, 2012/11/28 02:24:04 |
|
|
use strict; |
use strict; |
use warnings; |
use warnings; |
|
|
use Carp; |
use 5.010; |
|
|
use DateTime; |
use DateTime; |
|
use Carp; |
|
|
use 5.010; |
use YAML::XS qw/ LoadFile DumpFile /; |
|
$YAML::XS::QuoteNumericStrings = 0; |
|
use RTI::Util qw/ ymd_to_DateTime /; |
|
|
use YAML::Any qw/ LoadFile DumpFile /; |
|
|
|
my $file = ''; |
my $file = ''; |
|
|
sub new { |
sub new { |
|
|
$self->{lastinvoice} ||= 0; |
$self->{lastinvoice} ||= 0; |
while ( my ( $id, $invoice ) = each %{ $self->{invoice} } ) { |
while ( my ( $id, $invoice ) = each %{ $self->{invoice} } ) { |
$self->{lastinvoice} = $id if $self->{lastinvoice} < $id; |
$self->{lastinvoice} = $id if $self->{lastinvoice} < $id; |
|
|
$invoice->{id} = $id; |
$invoice->{id} = $id; |
|
$invoice->{$_} = ymd_to_DateTime( $invoice->{$_} ) |
|
for qw/ invdate start end /; |
} |
} |
|
foreach my $custid (keys %{ $self->{payment} || {} }) { |
|
foreach my $payment (@{ $self->{payment}->{$custid} || [] }) { |
|
$payment->{date} = ymd_to_DateTime( $payment->{date} ) |
|
if $payment->{date}; |
|
} |
|
} |
} |
} |
|
|
bless $self, $class; |
bless $self, $class; |
|
|
if exists $self->{invoice}->{$id}; |
if exists $self->{invoice}->{$id}; |
|
|
$invoice->{id} ||= $id; |
$invoice->{id} ||= $id; |
$invoice->{invdate} ||= DateTime->now( time_zone => 'local' )->ymd, |
$invoice->{invdate} ||= DateTime->now( time_zone => 'local' ), |
|
|
$self->{lastinvoice} = $id if $self->{lastinvoice} < $id; |
$self->{lastinvoice} = $id if $self->{lastinvoice} < $id; |
|
|
my %li; |
$self->{invoice}->{$id} = $invoice; |
foreach my $k ( |
|
qw/ |
|
id custid |
|
file transactions |
|
invdate start end |
|
total past_due total_due |
|
/ |
|
) |
|
{ |
|
my $v = $invoice->{$k}; |
|
|
|
if ( defined $v && length $v ) { |
|
if ( ref $v eq 'DateTime' ) { |
|
$li{$k} = $v->ymd; |
|
} |
|
else { |
|
$li{$k} = $v; |
|
} |
|
} |
|
} |
|
|
|
$self->{invoice}->{ $self->{lastinvoice} } = \%li; |
|
delete $self->{_tables}; |
delete $self->{_tables}; |
|
|
return $self->{lastinvoice}; |
return $self->{lastinvoice}; |
} |
} |
|
|
sub get_invoice{ |
sub get_invoice { |
my ( $self, $id ) = @_; |
my ( $self, $id ) = @_; |
return $self->{invoice}->{$id}; |
return $self->{invoice}->{$id}; |
} |
} |
|
|
|
|
sub txn_is_invoiced { |
sub txn_is_invoiced { |
my ( $self, $txn ) = @_; |
my ( $self, $txn ) = @_; |
|
|
if ( !$self->{_table}->{txn} ) { |
if ( !$self->{_table}->{txn} ) { |
my $invoices = $self->{invoice}; |
my $invoices = $self->{invoice}; |
foreach my $id ( sort { $a <=> $b } keys %{$invoices} ) { |
foreach my $id ( sort { $a <=> $b } keys %{$invoices} ) { |
|
|
} |
} |
|
|
sub unpaid_invoices { |
sub unpaid_invoices { |
my ($self, $custid) = @_; |
my ( $self, $custid ) = @_; |
|
|
$self->_match_payments; |
$self->_match_payments; |
return $self->{_table}->{unpaid}->{$custid}; |
return defined $custid |
|
? $self->{_table}->{unpaid}->{$custid} |
|
: $self->{_table}->{unpaid}; |
} |
} |
|
|
|
sub credits { |
|
my ( $self, $custid ) = @_; |
|
|
|
$self->_match_payments; |
|
return defined $custid |
|
? $self->{_table}->{credit}->{$custid} |
|
: $self->{_table}->{credit}; |
|
} |
|
|
sub save { |
sub save { |
my ($self) = @_; |
my ($self) = @_; |
|
|
delete $self->{_table}; |
delete $self->{_table}; |
delete $self->{lastinvoice}; |
delete $self->{lastinvoice}; |
foreach my $invoice ( values %{ $self->{invoice} } ) { |
foreach my $invoice ( values %{ $self->{invoice} } ) { |
delete $invoice->{id}; |
delete $invoice->{$_} for qw/ |
|
id |
|
from |
|
to |
|
info |
|
logo |
|
projects |
|
expenses |
|
discount |
|
hours |
|
organization |
|
/; |
|
|
|
foreach my $k ( keys %{$invoice} ) { |
|
my $v = $invoice->{$k}; |
|
|
|
if ( defined $v && length $v ) { |
|
if ( ref $v eq 'DateTime' ) { |
|
$invoice->{$k} = $v->ymd; |
|
} |
|
} |
|
else { |
|
delete $invoice->{$k}; |
|
} |
|
} |
} |
} |
|
foreach my $custid (keys %{ $self->{payment} || {} }) { |
|
foreach my $payment (@{ $self->{payment}->{$custid} || [] }) { |
|
$payment->{date} = $payment->{date}->ymd |
|
if ref $payment->{date} eq 'DateTime'; |
|
} |
|
} |
DumpFile( $file, {%$self} ) or die "Unable to save state: $!"; |
DumpFile( $file, {%$self} ) or die "Unable to save state: $!"; |
} |
} |
|
|
|
|
return if $self->{_table}{credit} && $self->{_table}{unpaid}; |
return if $self->{_table}{credit} && $self->{_table}{unpaid}; |
|
|
my $invoices = $self->{invoice}; |
my $invoices = $self->{invoice}; |
my %owes = map { $_ => $invoices->{$_}->{total} } keys %{ $invoices }; |
my %owes = map { $_ => $invoices->{$_}->{total} } keys %{$invoices}; |
|
|
my %credit; |
my %credit; |
|
|
|
|
} |
} |
|
|
foreach my $id ( sort { $b <=> $a } keys %owes ) { |
foreach my $id ( sort { $b <=> $a } keys %owes ) { |
my $i = $invoices->{$id}; |
my $i = $invoices->{$id}; |
my $custid = $i->{custid} or next; |
my $custid = $i->{custid} or next; |
|
|
my $owes = sprintf "%0.2f", $owes{$id} || 0; |
my $owes = sprintf "%0.2f", $owes{$id} || 0; |
|
|
if ($paid) { |
if ($paid) { |
$credit{$custid} = $paid; |
$credit{$custid} = $paid; |
} |
} |
elsif (exists $credit{$custid}) { |
elsif ( exists $credit{$custid} ) { |
delete $credit{$custid}; |
delete $credit{$custid}; |
} |
} |
} |
} |