[BACK]Return to State.pm CVS log [TXT][DIR] Up to [local] / RT / Invoicing / lib / RTI

Annotation of RT/Invoicing/lib/RTI/State.pm, Revision 1.1

1.1     ! andrew      1: package RTI::State;
        !             2: use strict;
        !             3: use warnings;
        !             4:
        !             5: use Carp;
        !             6:
        !             7: use DateTime;
        !             8:
        !             9: use 5.010;
        !            10:
        !            11: use YAML::Any qw/ LoadFile DumpFile /;
        !            12:
        !            13: my $file = '';
        !            14:
        !            15: sub new {
        !            16:     my $class;
        !            17:     ( $class, $file ) = @_;
        !            18:
        !            19:     my $self = { lastinvoice => 0, };
        !            20:     if ( -e $file ) {
        !            21:         $self = LoadFile($file) or die "Unable to load state: $!";
        !            22:
        !            23:         $self->{lastinvoice} ||= 0;
        !            24:         while ( my ( $id, $invoice ) = each %{ $self->{invoice} } ) {
        !            25:             $self->{lastinvoice} = $id if $self->{lastinvoice} < $id;
        !            26:             $invoice->{id} = $id;
        !            27:         }
        !            28:     }
        !            29:
        !            30:     bless $self, $class;
        !            31:
        !            32:     die "Need to pass filename to new: $!" unless $file;
        !            33:
        !            34:     return $self;
        !            35: }
        !            36:
        !            37: sub next_invoice_id {
        !            38:     my ($self) = @_;
        !            39:     return $self->{lastinvoice} + 1;
        !            40: }
        !            41:
        !            42: sub add_invoice {
        !            43:     my ( $self, $invoice ) = @_;
        !            44:
        !            45:     my $id = $invoice->{id} || $self->next_invoice_id;
        !            46:
        !            47:     croak "Can't add duplicate invoice $id\n"
        !            48:         if exists $self->{invoice}->{$id};
        !            49:
        !            50:     $invoice->{id} ||= $id;
        !            51:     $invoice->{invdate} ||= DateTime->now( time_zone => 'local' )->ymd,
        !            52:
        !            53:         $self->{lastinvoice} = $id if $self->{lastinvoice} < $id;
        !            54:
        !            55:     my %li;
        !            56:     foreach my $k (
        !            57:         qw/
        !            58:         id custid
        !            59:         file transactions
        !            60:         invdate start end
        !            61:         total past_due total_due
        !            62:         /
        !            63:         )
        !            64:     {
        !            65:         my $v = $invoice->{$k};
        !            66:
        !            67:         if ( defined $v && length $v ) {
        !            68:             if ( ref $v eq 'DateTime' ) {
        !            69:                 $li{$k} = $v->ymd;
        !            70:             }
        !            71:             else {
        !            72:                 $li{$k} = $v;
        !            73:             }
        !            74:         }
        !            75:     }
        !            76:
        !            77:     $self->{invoice}->{ $self->{lastinvoice} } = \%li;
        !            78:     delete $self->{_tables};
        !            79:
        !            80:     return $self->{lastinvoice};
        !            81: }
        !            82:
        !            83: sub get_invoice{
        !            84:     my ( $self, $id ) = @_;
        !            85:     return $self->{invoice}->{$id};
        !            86: }
        !            87:
        !            88: sub last_invoice {
        !            89:     my ( $self, $custid ) = @_;
        !            90:
        !            91:     if ( !$self->{_table}->{last_invoice} ) {
        !            92:         my $invoices = $self->{invoice};
        !            93:         foreach my $id ( sort { $a <=> $b } keys %{$invoices} ) {
        !            94:             my $inv = $invoices->{$id};
        !            95:             next unless $inv->{custid};
        !            96:             $self->{_table}->{last_invoice}->{ $inv->{custid} } = $inv;
        !            97:         }
        !            98:     }
        !            99:
        !           100:     return $self->{_table}->{last_invoice}->{$custid};
        !           101: }
        !           102:
        !           103: sub txn_is_invoiced {
        !           104:     my ( $self, $txn ) = @_;
        !           105:
        !           106:     if ( !$self->{_table}->{txn} ) {
        !           107:         my $invoices = $self->{invoice};
        !           108:         foreach my $id ( sort { $a <=> $b } keys %{$invoices} ) {
        !           109:             my $inv = $invoices->{$id};
        !           110:             foreach my $t ( @{ $inv->{transactions} } ) {
        !           111:                 $self->{_table}->{txn}->{$t} = 1;
        !           112:             }
        !           113:         }
        !           114:     }
        !           115:     return $self->{_table}->{txn}->{$txn};
        !           116: }
        !           117:
        !           118: sub unpaid_invoices {
        !           119:     my ($self, $custid) = @_;
        !           120:
        !           121:     $self->_match_payments;
        !           122:     return $self->{_table}->{unpaid}->{$custid};
        !           123: }
        !           124:
        !           125: sub save {
        !           126:     my ($self) = @_;
        !           127:
        !           128:     delete $self->{_table};
        !           129:     delete $self->{lastinvoice};
        !           130:     foreach my $invoice ( values %{ $self->{invoice} } ) {
        !           131:         delete $invoice->{id};
        !           132:     }
        !           133:     DumpFile( $file, {%$self} ) or die "Unable to save state: $!";
        !           134: }
        !           135:
        !           136: sub _match_payments {
        !           137:     my ($self) = @_;
        !           138:
        !           139:     return if $self->{_table}{credit} && $self->{_table}{unpaid};
        !           140:
        !           141:     my $invoices = $self->{invoice};
        !           142:     my %owes = map { $_ => $invoices->{$_}->{total} } keys %{ $invoices };
        !           143:
        !           144:     my %credit;
        !           145:
        !           146:     foreach my $custid ( keys %{ $self->{payment} } ) {
        !           147:         $credit{$custid} = 0;
        !           148:
        !           149:         my $payments = $self->{payment}->{$custid};
        !           150:         foreach my $p ( @{$payments} ) {
        !           151:             my $paid = $p->{paid};
        !           152:             $p->{invoices} ||= [];
        !           153:
        !           154:             foreach my $id ( @{ $p->{invoices} } ) {
        !           155:                 $owes{$id} ||= 0;
        !           156:
        !           157:                 if ( $owes{$id} == $paid ) {
        !           158:                     $owes{$id} = 0;
        !           159:                     $paid = 0;
        !           160:                 }
        !           161:                 elsif ( $owes{$id} > $paid ) {
        !           162:                     $owes{$id} -= $paid;
        !           163:                     $paid = 0;
        !           164:                 }
        !           165:                 elsif ( $owes{$id} < $paid ) {
        !           166:                     $paid -= $owes{$id};
        !           167:                     $owes{$id} = 0;
        !           168:                 }
        !           169:             }
        !           170:
        !           171:             $credit{$custid} += $paid;
        !           172:         }
        !           173:
        !           174:         delete $credit{$custid} unless $credit{$custid};
        !           175:     }
        !           176:
        !           177:     foreach my $id ( sort { $b <=> $a } keys %owes ) {
        !           178:         my $i      = $invoices->{$id};
        !           179:         my $custid = $i->{custid} or next;
        !           180:
        !           181:         my $owes = sprintf "%0.2f", $owes{$id}       || 0;
        !           182:         my $paid = sprintf "%0.2f", $credit{$custid} || 0;
        !           183:
        !           184:         if ( $owes == $paid ) {
        !           185:             $owes = 0;
        !           186:             $paid = 0;
        !           187:         }
        !           188:         elsif ( $owes > $paid ) {
        !           189:             $owes -= $paid;
        !           190:             $paid = 0;
        !           191:         }
        !           192:         elsif ( $owes < $paid ) {
        !           193:             $paid -= $owes;
        !           194:             $owes = 0;
        !           195:         }
        !           196:
        !           197:         $self->{_table}{unpaid}{$custid}{$id} = $owes if $owes;
        !           198:
        !           199:         if ($paid) {
        !           200:             $credit{$custid} = $paid;
        !           201:         }
        !           202:         elsif (exists $credit{$custid}) {
        !           203:             delete $credit{$custid};
        !           204:         }
        !           205:     }
        !           206:
        !           207:     $self->{_table}{credit} = \%credit;
        !           208: }
        !           209:
        !           210: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>