view lib/Benzin/Bugzilla/Bug.pm @ 10:14a966369278

working version of exporting bugs from bugzilla in tj3 format (without bookings)
author cin
date Mon, 07 Sep 2015 01:37:11 +0300
parents cc7244ab1b9f
children 4eb9fdf4efa9
line wrap: on
line source

package Benzin::Bugzilla::Bug;
use strict;
use POSIX;
use Scalar::Util qw(looks_like_number);
use DateTime;

my @fields;

BEGIN {
	@fields = qw(
	  id
	  summary
	  creation_time
	  last_change_time
	  creator
	  assigned_to
	  qa_contact
	  cc

	  is_open
	  status
	  resolution

	  priority
	  severity
	  url

	  blocks
	  depends_on

	  component
	  product
	  classification
	  version

	  actual_time
	  estimated_time
	  remaining_time
	  deadline

	  comments
	  history
	);
}

use constant { BUG_FIELDS => \@fields };

use IMPL::declare {
	base    => [ 'IMPL::Object::Fields' => undef ]
};
use fields @fields;

sub CTOR {
	my SELF $this = shift;
	my $data = shift;
	$this->{$_} = $data->{$_}
	  foreach grep exists $data->{$_}, @{ SELF->BUG_FIELDS };
}

# returns {
#	reports => [
#		{ who => email:string, start => work-start-date-time:DateTime, end => report-date-time:DateTime, work_time => hours:double }
#	],
#   actual => hours
#	remaining => hours
# }
sub GetTimeReports {
	my SELF $this = shift;
	my $resolution = shift || 0.25;

	my @bookings;
	my $actual = 0;

	for my $history ( @{ $this->{history} || [] } ) {
		my $who = $history->{who};
		my $when    = $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,
						  {
							end       => $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 )
	};
}

sub coarsen {
	my ( $value, $resolution ) = @_;
	return $resolution ? ceil( $value / $resolution ) * $resolution : $value;
}

1;