Mercurial > pub > buggler
diff lib/Benzin/Bugzilla/Bug.pm @ 9:cc7244ab1b9f
implemented time reports on bugs
author | cin |
---|---|
date | Sat, 05 Sep 2015 22:01:12 +0300 |
parents | 29309bc8d932 |
children | 14a966369278 |
line wrap: on
line diff
--- a/lib/Benzin/Bugzilla/Bug.pm Fri Sep 04 19:42:15 2015 +0300 +++ b/lib/Benzin/Bugzilla/Bug.pm Sat Sep 05 22:01:12 2015 +0300 @@ -1,10 +1,13 @@ package Benzin::Bugzilla::Bug; use strict; +use POSIX; +use Scalar::Util qw(looks_like_number); +use DateTime; -my @bugFields; +my @fields; BEGIN { - @bugFields = qw( + @fields = qw( id summary creation_time @@ -14,6 +17,7 @@ qa_contact cc + is_open status resolution @@ -23,7 +27,6 @@ blocks depends_on - component product @@ -34,34 +37,92 @@ estimated_time remaining_time deadline - + comments + history ); } -use constant { - BUG_FIELDS => \@bugFields -}; +use constant { BUG_FIELDS => \@fields }; use IMPL::declare { + require => { + Strptime => 'DateTime::Format::Strptime' + }, base => [ - 'IMPL::Object::Fields' => undef + 'IMPL::Object::Fields' => undef ] }; -use fields @bugFields; +use fields @fields; + +my $dtparser = Strptime->new( + pattern => '%Y%m%dT%H:%M:%S', + time_zone => 'UTC', + on_error => 'croak' +); sub CTOR { my SELF $this = shift; - my $data = shift; - - $this->{$_} = $data->{$_} foreach grep exists $data->{$_}, SELF->BUG_FIELDS; + my $data = shift; + $this->{$_} = $data->{$_} + foreach grep exists $data->{$_}, @{ SELF->BUG_FIELDS }; } -sub GetEffort { +# returns { +# reports => [ +# { who => email:string, when => report-date-time:DateTime, work_time => hours:double } +# ], +# actual => hours +# remaining => hours +# } +sub GetTimeReports { my SELF $this = shift; + my $resolution = shift || 0.25; - return $this->{actual_time} + $this->{remaining_time}; + warn "Processing: $this->{id}"; + + my @bookings; + my $actual = 0; + + for my $history ( @{ $this->{history} || [] } ) { + my $who = $history->{who}; + warn $history->{when}; + my $when = $dtparser->parse_datetime( $history->{when} ); + my $changes = $history->{changes}; + + for my $change ( @{ $changes || [] } ) { + if ( $change->{field_name} eq 'work_time' ) { + my $prev = $change->{removed} || 0; + my $value = $change->{added} || 0; + if ( looks_like_number($prev) and looks_like_number($value) ) { + my $dt = coarsen( $value - $prev, $resolution ); + + if ($dt) { + push @bookings, + { + who => $who, + when => $when->iso8601(), + work_time => $dt, + start => $when->clone()->subtract( hours => $dt )->iso8601() + }; + $actual += $dt; + } + } + } + } + } + + return { + reports => \@bookings, + actual => $actual, + remaining => coarsen( $this->{remaining_time}, $resolution ) + }; } -1; +sub coarsen { + my ( $value, $resolution ) = @_; + return $resolution ? ceil( $value / $resolution ) * $resolution : $value; +} + +1; \ No newline at end of file