=================================================================== RCS file: /cvs/RT/Invoicing/rt_invoices.pl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- RT/Invoicing/rt_invoices.pl 2011/03/21 01:05:38 1.2 +++ RT/Invoicing/rt_invoices.pl 2011/03/21 04:19:25 1.3 @@ -12,46 +12,53 @@ use DateTime; -my %included_hours; - my $config = RTI::Config->new(); #print Dump $config; exit; -# my $state = RTI::State->new($cust); -# $invoice{state} = $state; -my $lastinvdate; # = $state->{lastinvoicedte}; XXX Needs to be a DateTime - -#$lastinvdate = DateTime->now->subtract( months => 2 ); my $invoiceid = 1; # $state->{lastinvoice} + 1; my $startdate; my @invoices; foreach my $cust ( @{ $config->get('customers') } ) { + + # my $state = RTI::State->new($cust); + # $invoice{state} = $state; + my $lastinvdate; # = $state->{lastinvoicedte}; XXX Needs to be a DateTime + #$lastinvdate = DateTime->now->subtract( months => 2 ) + # ->set( hour => 0, minute => 0, second => 0 ); + my %invoice = ( from => $config->get('from'), + info => $config->get('info'), to => $cust->{address}, rates => $cust->{rates}, match => $cust->{match}, ); if ( $cust->{base_rate} ) { - my $date = DateTime->now; - my $day = $cust->{day} || 1; + my $day = $cust->{day} || 1; my $freq = $cust->{frequency} || 1; - my $diff; + my $day_method; my $per; given ( $cust->{per} ) { - when ('week') { $per = 'weeks'; $diff = $date->dow - $day; } - when ('month') { $per = 'months'; $diff = $date->day - $day; } + when ('week') { $per = 'weeks'; $day_method = 'dow' } + when ('month') { $per = 'months'; $day_method = 'day' } default { die "Unknown per [$cust->{per}]\n" } } - # $day is start day, end should be one day further back - $diff = abs($diff) + 1; - $date->subtract( days => $diff ); + my $lastbill + = DateTime->now->set( hour => 0, minute => 0, second => 0 ); + while ( $lastbill->$day_method != $day ) { + $lastbill->subtract( days => 1 ); + } + my $date + = $lastinvdate + ? $lastinvdate->clone->add( days => 1 ) + : $lastbill->clone->subtract( $per => $freq ); + my $title = $freq == 1 ? ucfirst( $cust->{per} . 'ly' ) @@ -60,46 +67,49 @@ my %project = ( title => $title, fees => [], ); - # XXX need to add them until we get to where we billed already - # if we don't know the last invoice date, assume the day before - $lastinvdate ||= $date->clone->subtract( days => 1 ); - while ( $date > $lastinvdate ) { - $invoice{enddate} = $date->clone; + while ( $date < $lastbill ) { + my $start = $date->clone; + + $date->add( $per => $freq ); + $date = $lastbill->clone if $date > $lastbill; + if ( my $diff = $date->$day_method - $day ) { + $date->subtract( days => $diff ); + } + + my $end = $date->clone; + + $end->subtract( seconds => 1 ); + + $startdate = $start->clone if $startdate > $start; + $invoice{start} ||= $start->clone; + $invoice{end} = $end->clone; my %hours = ( - end => $date->clone, + start => $start->clone, + end => $end->clone, hours => { %{ $cust->{hours} } }, ); - my $contents = ' to ' . $date->ymd; - $date->subtract( $per => $freq )->add( days => 1 ); - $contents = $date->ymd . $contents; - - $invoice{startdate} ||= $date->clone; - $hours{start} = $date->clone; - $startdate = $date->clone; - - unshift @{ $invoice{hours} }, \%hours; - unshift @{ $project{fees} }, + push @{ $invoice{hours} }, \%hours; + push @{ $project{fees} }, { count => 1, rate => $cust->{base_rate}, - contents => $contents, + contents => $start->ymd . ' to ' . $end->ymd, }; - # Next time, one day less - $date->subtract( days => 1 ); } - if (@{ $project{fees} }) { + if ( @{ $project{fees} } ) { push @{ $invoice{projects} }, \%project; } } else { - $invoice{enddate} = DateTime->now->ymd; + $invoice{end} = DateTime->now; push @{ $invoice{hours} }, { end => DateTime->now, hours => $cust->{hours} }; } + next unless $invoice{end}; push @invoices, \%invoice; } @@ -161,11 +171,13 @@ id => $ticket->id, queue => $ticket->queue, owner => $ticket->owner, - title => $ticket->id . ': ' . $ticket->subject, - detail => 'Requestors: ' - . join( ', ', $ticket->requestors ) + title => $ticket->subject, + detail => 'Ticket: ' + . $ticket->id . ' Queue: ' - . $ticket->queue, + . $ticket->queue + . ' Requestors: ' + . join( ', ', $ticket->requestors ), fees => [], expenses => [], ); @@ -210,6 +222,33 @@ while ( my $txn = $txn_i->() ) { next unless $txn->time_taken; + my ( $date, $time ) = split ' ', $txn->created; + my ( $year, $month, $day ) = split '-', $date; + my ( $hour, $minute, $second ) = split ':', $time; + + my $txn_date = DateTime->new( + year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $minute, + second => $second, + ); + + next if $invoice->{start} && $invoice->{start} > $txn_date; + next if $invoice->{end} < $txn_date; + + my $hours = {}; + if ( $invoice->{hours} ) { + foreach my $h ( @{ $invoice->{hours} } ) { + next if $h->{start} && $h->{start} > $txn_date; + next if $h->{end} < $txn_date; + + $hours = $h->{hours}; + last; + } + } + my $work_time = sprintf "%.03f", $txn->time_taken / 60; my $work_type = $txn->cf('WorkType'); my $work_rate @@ -217,8 +256,8 @@ || $invoice->{rates}{default} || 0; - my $ih_type - = exists $included_hours{$work_type} + my $h_type + = exists $hours->{$work_type} ? $work_type : 'default'; @@ -236,17 +275,16 @@ push @{ $project{fees} }, \%fee; - next - unless $included_hours{$ih_type} && $included_hours{$ih_type} > 0; + next unless $hours->{$h_type} && $hours->{$h_type} > 0; my $discount_time = 0; - if ( $included_hours{$ih_type} > $work_time ) { - $included_hours{$ih_type} -= $work_time; + if ( $hours->{$h_type} > $work_time ) { + $hours->{$h_type} -= $work_time; $discount_time = $work_time; } else { - $discount_time = $included_hours{$ih_type}; - $included_hours{$ih_type} = 0; + $discount_time = $hours->{$h_type}; + $hours->{$h_type} = 0; } if ($discount_time) { @@ -297,6 +335,12 @@ if ( $invoice->{past_due} ) { $invoice->{total_due} = $invoice->{total} + $invoice->{past_due}; + } + + foreach my $key (qw/ start end /) { + if ( exists $invoice->{$key} ) { + $invoice->{$key} = $invoice->{$key}->strftime('%B %d, %Y'); + } } $invoice->{id} = $invoiceid;