class JiraIssue
Constants
- AFFECTED_USER_GROUP_FIELD
- API_OVER_SLA_FIELD_NO
- API_OVER_SLA_FIELD_YES
- API_OVER_TRIAGE_SLA_FIELD_NO
- API_OVER_TRIAGE_SLA_FIELD_YES
- FIVE_P_DATE
The
FIVE_P_DATE
variable exists for tickets created before 2015-03-06 15:55:16 -0500. Not used for any tickets after that. Tickets created after above date use differnt SLA measurements.- OVER_SLA_FIELD
- OVER_SLA_FIELD_NO
- OVER_SLA_FIELD_YES
- OVER_TRIAGE_SLA_FIELD
- OVER_TRIAGE_SLA_FIELD_NO
- OVER_TRIAGE_SLA_FIELD_YES
- SLA_CLOSED_AT_FIELD
- SLA_DUE_TIME_FIELD
- SLA_DUE_WARNING_FIELD
- SLA_DUE_WARNING_FIELD_SET
- SLA_TRIAGED_AT_FIELD
- STORY_POINTS_FIELD
- TOTAL_TIME_OVER_SLA_FIELD
- TRIAGER_FIELD
Attributes
affected_user_group[RW]
assigned_team[RW]
cant_reproduce[RW]
changelog[RW]
completed[RW]
created_at[RW]
deploy[RW]
description[RW]
in_progress[RW]
key[RW]
labels[RW]
merged[RW]
merged_st[RW]
not_accepted[RW]
on_production[RW]
orig[RW]
over_sla[RW]
over_triage_sla[RW]
pr_review[RW]
priority_name[RW]
project[RW]
raw_sprints[RW]
requester_denied[RW]
requester_review[RW]
resolved[RW]
reverify[RW]
sla_closed_at[RW]
sla_due_time[RW]
sla_due_warning[RW]
sla_triaged_at[RW]
status[RW]
story_points[RW]
summary[RW]
total_time_over_sla[RW]
triaged[RW]
triager[RW]
type[RW]
url[RW]
verified[RW]
Public Class Methods
custom_time_fields()
click to toggle source
# File lib/jira_issue.rb, line 94 def self.custom_time_fields Hash[[ [10812, "Support xt Can't Reproduce"], [10808, 'Support xt In Progress'], [10809, 'Support xt Not Accepted'], [10817, 'Support xt Requester Denied'], [10814, 'Support xt Requester Review'], [13101, 'Support xt Merged'], [13102, 'Support xt On Production'], [10816, 'Support xt Resolved'], [10815, 'Support xt Reverify'], [10813, 'Support xt Review'], [10810, 'Support xt Triaged'], [10811, 'Support xt Verified'] ].map{|k,v| ["customfield_#{k}", v]}] end
find(query, offset = 0)
click to toggle source
# File lib/jira_issue.rb, line 80 def self.find(query, offset = 0) ask = 100 result = Jiralicious.search(query, start_at: offset, max_results: ask) issues = result.issues_raw issues.map! { |i| new(i) } if issues.count == ask && result.num_results > offset + ask issues += find(query, offset + ask) end issues rescue Jiralicious::JqlError => e $stderr.puts "Error: #{e}" [] end
new(issue)
click to toggle source
# File lib/jira_issue.rb, line 40 def initialize(issue) issue.extend(DotNotation) self.key = issue.dot 'key' self.created_at = Time.parse(issue.dot('fields.created')) self.type = issue.dot 'fields.issuetype.name' self.priority_name = issue.dot 'fields.priority.name' self.status = issue.dot('fields.status.name').downcase self.project = issue.dot 'fields.project.key' self.description = issue.dot 'fields.description' self.summary = issue.dot 'fields.summary' self.labels = issue.dot 'fields.labels' self.assigned_team = issue.dot 'fields.customfield_12601.value' self.story_points = issue.dot "fields.#{STORY_POINTS_FIELD}" self.orig = issue self.url = "https://optoro.atlassian.net/browse/#{key}" self.raw_sprints = issue.dot 'fields.customfield_10007' self.sla_triaged_at = Time.parse(issue.dot("fields.#{SLA_TRIAGED_AT_FIELD}")) if issue.dot("fields.#{SLA_TRIAGED_AT_FIELD}").present? self.over_triage_sla = issue.dot "fields.#{OVER_TRIAGE_SLA_FIELD}" self.triager = issue.dot "fields.#{TRIAGER_FIELD}.name" self.sla_due_time = Time.parse(issue.dot("fields.#{SLA_DUE_TIME_FIELD}")) if issue.dot("fields.#{SLA_DUE_TIME_FIELD}").present? self.sla_due_warning = issue.dot "fields.#{SLA_DUE_WARNING_FIELD}" self.sla_closed_at = Time.parse(issue.dot("fields.#{SLA_CLOSED_AT_FIELD}")) if issue.dot("fields.#{SLA_CLOSED_AT_FIELD}").present? self.over_sla = issue.dot "fields.#{OVER_SLA_FIELD}" self.total_time_over_sla = issue.dot "fields.#{TOTAL_TIME_OVER_SLA_FIELD}" self.affected_user_group = issue.dot "fields.#{AFFECTED_USER_GROUP_FIELD}" inv = self.class.custom_time_fields.invert inv.each do |name, key| x = name.gsub(/'/,'').gsub(/ +/, '_').downcase.gsub(/support_xt_/,'') v = issue.dot "fields.#{key}" v = Time.parse(v) if v x = "pr_review" if x == "review" # rename send("#{x}=", v) end end
Public Instance Methods
affected_user_groups()
click to toggle source
# File lib/jira_issue.rb, line 159 def affected_user_groups affected_user_group.map {|user_group| user_group["value"]} unless affected_user_group.nil? end
affects_client_corporate_users?()
click to toggle source
# File lib/jira_issue.rb, line 173 def affects_client_corporate_users? return false if affected_user_groups.nil? affected_user_groups.include?("Client Corporate Users") end
affects_customers?()
click to toggle source
# File lib/jira_issue.rb, line 168 def affects_customers? return false if affected_user_groups.nil? affected_user_groups.include?("Customers") end
affects_internal_optoro_users?()
click to toggle source
# File lib/jira_issue.rb, line 178 def affects_internal_optoro_users? return false if affected_user_groups.nil? affected_user_groups.include?("Internal Optoro Users") end
affects_warehouse_users?()
click to toggle source
# File lib/jira_issue.rb, line 163 def affects_warehouse_users? return false if affected_user_groups.nil? affected_user_groups.include?("WH Users") end
bug?()
click to toggle source
# File lib/jira_issue.rb, line 143 def bug? type == "Bug / Outage" end
changelog_simple()
click to toggle source
# File lib/jira_issue.rb, line 228 def changelog_simple changelog.map { |c| c["items"].map { |i| i.slice("field", "fromString","toString") .merge({ "created" => c["created"], "author_out" => c["author"]["name"] || "" }) } }.flatten end
closed?()
click to toggle source
# File lib/jira_issue.rb, line 117 def closed? [ "requester review", "merged", "merged_st", "on production", "resolved", "not accepted", "can't reproduce", "deploy", "completed" ].include? status end
closed_at()
click to toggle source
# File lib/jira_issue.rb, line 130 def closed_at [ requester_review, merged, merged_st, on_production, resolved, not_accepted, cant_reproduce, deploy, completed ].compact.min end
feature?()
click to toggle source
# File lib/jira_issue.rb, line 151 def feature? type == "Feature Enhancement" end
jiralicious_issue()
click to toggle source
# File lib/jira_issue.rb, line 76 def jiralicious_issue Jiralicious::Issue.find(key) end
open?()
click to toggle source
# File lib/jira_issue.rb, line 111 def open? !closed? # ["unverified", "triaged", "verified", # "in progress", "pr_review", "pr review"].include? status end
operational?()
click to toggle source
# File lib/jira_issue.rb, line 147 def operational? type == "Operational Request" end
priority()
click to toggle source
# File lib/jira_issue.rb, line 183 def priority case priority_name when /P1/ :p1 when /P2/ :p2 when /P3/ :p3 when /P4/ :p4 else :p5 end end
research?()
click to toggle source
# File lib/jira_issue.rb, line 155 def research? type == "Research" end
sprints()
click to toggle source
# File lib/jira_issue.rb, line 214 def sprints if raw_sprints raw_sprints.map {|s| Hash[s.match(/\[(.*)\]/)[1].split(',').map{|f|f.split('=')}]} else [] end end
status_ages()
click to toggle source
# File lib/jira_issue.rb, line 270 def status_ages ages = {} status_changes.each{|c| ages[c[:status]] = ages.fetch(c[:status], 0) + c[:age_hours].to_r.round(2).to_f} ages end
status_changes()
click to toggle source
# File lib/jira_issue.rb, line 240 def status_changes status_changes = changelog_simple.select{|c| c["field"] == "status"} start = created_at author = orig["fields"]["reporter"].andand["name"] || "" status_changes.each { |c| c["age_hours"] = (Time.parse(c["created"]).to_i - start.to_i)/60.0/60 c["started"] = start start = Time.parse(c["created"]) cur_author = author author = c["author_out"] c["author_in"] = cur_author } statuses = status_changes.map { |s| { status: s["fromString"], start: s["started"], end: Time.parse(s["created"]), author_in: s["author_in"], author_out: s["author_out"], age_hours: s["age_hours"] } } statuses << { status: status, start: start, author_in: author } end
status_duration_during(status, start_date, end_date)
click to toggle source
# File lib/jira_issue.rb, line 276 def status_duration_during(status, start_date, end_date) ages = {} status_changes.each{|c| ages[c["fromString"]] = ages.fetch(c["fromString"],0) + c["age_hours"]} status_changes.each{|c| ages[c[:status]] = ages.fetch(c[:status], 0) + c[:age_hours].to_r.round(2).to_f} last_status = status_changes.last if last_status ages[last_status["toString"]] = ages.fetch(last_status["toString"], 0) + ((Time.now.to_f - Time.parse(last_status["created"]).to_f)/60.0/60) end ages end
time_to_qa()
click to toggle source
# File lib/jira_issue.rb, line 198 def time_to_qa if triaged && (verified || cant_reproduce || in_progress) if verified verified - triaged elsif cant_reproduce cant_reproduce - triaged else in_progress - triaged end elsif triaged Time.now - triaged else nil end end