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