Mercurial > pub > buggler
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 8:ff9c0c788382 | 9:cc7244ab1b9f |
|---|---|
| 1 package Benzin::Bugzilla::Bug; | 1 package Benzin::Bugzilla::Bug; |
| 2 use strict; | 2 use strict; |
| 3 use POSIX; | |
| 4 use Scalar::Util qw(looks_like_number); | |
| 5 use DateTime; | |
| 3 | 6 |
| 4 my @bugFields; | 7 my @fields; |
| 5 | 8 |
| 6 BEGIN { | 9 BEGIN { |
| 7 @bugFields = qw( | 10 @fields = qw( |
| 8 id | 11 id |
| 9 summary | 12 summary |
| 10 creation_time | 13 creation_time |
| 11 last_change_time | 14 last_change_time |
| 12 creator | 15 creator |
| 13 assigned_to | 16 assigned_to |
| 14 qa_contact | 17 qa_contact |
| 15 cc | 18 cc |
| 16 | 19 |
| 20 is_open | |
| 17 status | 21 status |
| 18 resolution | 22 resolution |
| 19 | 23 |
| 20 priority | 24 priority |
| 21 severity | 25 severity |
| 22 url | 26 url |
| 23 | 27 |
| 24 blocks | 28 blocks |
| 25 depends_on | 29 depends_on |
| 26 | |
| 27 | 30 |
| 28 component | 31 component |
| 29 product | 32 product |
| 30 classification | 33 classification |
| 31 version | 34 version |
| 32 | 35 |
| 33 actual_time | 36 actual_time |
| 34 estimated_time | 37 estimated_time |
| 35 remaining_time | 38 remaining_time |
| 36 deadline | 39 deadline |
| 37 | 40 |
| 38 comments | 41 comments |
| 42 history | |
| 39 ); | 43 ); |
| 40 } | 44 } |
| 41 | 45 |
| 42 use constant { | 46 use constant { BUG_FIELDS => \@fields }; |
| 43 BUG_FIELDS => \@bugFields | |
| 44 }; | |
| 45 | 47 |
| 46 use IMPL::declare { | 48 use IMPL::declare { |
| 49 require => { | |
| 50 Strptime => 'DateTime::Format::Strptime' | |
| 51 }, | |
| 47 base => [ | 52 base => [ |
| 48 'IMPL::Object::Fields' => undef | 53 'IMPL::Object::Fields' => undef |
| 49 ] | 54 ] |
| 50 }; | 55 }; |
| 51 | 56 |
| 52 use fields @bugFields; | 57 use fields @fields; |
| 58 | |
| 59 my $dtparser = Strptime->new( | |
| 60 pattern => '%Y%m%dT%H:%M:%S', | |
| 61 time_zone => 'UTC', | |
| 62 on_error => 'croak' | |
| 63 ); | |
| 53 | 64 |
| 54 sub CTOR { | 65 sub CTOR { |
| 55 my SELF $this = shift; | 66 my SELF $this = shift; |
| 56 my $data = shift; | 67 my $data = shift; |
| 57 | 68 $this->{$_} = $data->{$_} |
| 58 $this->{$_} = $data->{$_} foreach grep exists $data->{$_}, SELF->BUG_FIELDS; | 69 foreach grep exists $data->{$_}, @{ SELF->BUG_FIELDS }; |
| 59 } | 70 } |
| 60 | 71 |
| 61 sub GetEffort { | 72 # returns { |
| 73 # reports => [ | |
| 74 # { who => email:string, when => report-date-time:DateTime, work_time => hours:double } | |
| 75 # ], | |
| 76 # actual => hours | |
| 77 # remaining => hours | |
| 78 # } | |
| 79 sub GetTimeReports { | |
| 62 my SELF $this = shift; | 80 my SELF $this = shift; |
| 81 my $resolution = shift || 0.25; | |
| 63 | 82 |
| 64 return $this->{actual_time} + $this->{remaining_time}; | 83 warn "Processing: $this->{id}"; |
| 84 | |
| 85 my @bookings; | |
| 86 my $actual = 0; | |
| 87 | |
| 88 for my $history ( @{ $this->{history} || [] } ) { | |
| 89 my $who = $history->{who}; | |
| 90 warn $history->{when}; | |
| 91 my $when = $dtparser->parse_datetime( $history->{when} ); | |
| 92 my $changes = $history->{changes}; | |
| 93 | |
| 94 for my $change ( @{ $changes || [] } ) { | |
| 95 if ( $change->{field_name} eq 'work_time' ) { | |
| 96 my $prev = $change->{removed} || 0; | |
| 97 my $value = $change->{added} || 0; | |
| 98 if ( looks_like_number($prev) and looks_like_number($value) ) { | |
| 99 my $dt = coarsen( $value - $prev, $resolution ); | |
| 100 | |
| 101 if ($dt) { | |
| 102 push @bookings, | |
| 103 { | |
| 104 who => $who, | |
| 105 when => $when->iso8601(), | |
| 106 work_time => $dt, | |
| 107 start => $when->clone()->subtract( hours => $dt )->iso8601() | |
| 108 }; | |
| 109 $actual += $dt; | |
| 110 } | |
| 111 } | |
| 112 } | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 return { | |
| 117 reports => \@bookings, | |
| 118 actual => $actual, | |
| 119 remaining => coarsen( $this->{remaining_time}, $resolution ) | |
| 120 }; | |
| 121 } | |
| 122 | |
| 123 sub coarsen { | |
| 124 my ( $value, $resolution ) = @_; | |
| 125 return $resolution ? ceil( $value / $resolution ) * $resolution : $value; | |
| 65 } | 126 } |
| 66 | 127 |
| 67 1; | 128 1; |
