suusan2号の戯れ

SIerでインフラSE⇛WEB系でエンジニアのおっさん

redmineで進捗率をステータスに連動させた場合でも、親チケットのステータスは小チケットの進捗率に連動させる方法

いま自分のグループのredmineの管理者をやっているのですが、進捗率ってみんな変えてくれないですよね。入れてくれても人によって進捗率の考え方がバラバラだったり。そこでチケットのステータスに応じて(対応中とかフィードバックとか)進捗率を自動で変えられるプラグインとかないかなーと思っていたのですが、実はプラグインではなくデフォルトの機能で実現できます(自分は1時間くらいプラグインがないかググっていました…)。以下は少し古い記事ですが、redmine2.5でも同様の設定が可能です。
小技(0.9): チケットのステータスで進捗率を更新する | Redmine.JP Blog

チケットの進捗率をステータスに連動させた場合の弊害

ただし進捗率をステータス連動にさせた場合は、通常小チケット全体の進捗率に連動して自動で計算される親チケットの進捗率も、親チケット自体のステータスに連動して設定されてしまいます。以下の小チケットを4つ持つチケットで考えてみましょう。

チケット
 >小チケット1:進捗率100%
 >小チケット2:進捗率100%
 >小チケット3:進捗率100%
 >小チケット4:進捗率0%

この場合の親チケットの進捗率は以下の様になります。

チケットの進捗率がステータス連動でない ⇛ 75%
チケットの進捗率がステータス連動 ⇛
 小チケットの進捗率に関わらず、親チケットのステータスによって決まる。

自分のとこのredmineもそうなのですが、小チケットを多用してプロジェクトの管理をしている場合、親チケットの進捗率は小チケットの進捗率と連動してた方が見栄えが良いですよね。親チケットのトラッカーを分ける(このトラッカーにはステータスに応じた進捗率を設定しない)ことで、親チケットの進捗率だけ小チケット連動にすることもできますが、自分はもっとシンプルに実現したかったのでredmineのソースを弄ってみることにしました。

2014年10月19日 ソースが会社のサーバの中なので、続きは別途書きます。
2014年11月1日 追記(大分遅くなってしまった…)

細かく書こうと思ったけどだるいのでdiffを貼り付けます。
変更したのは${redmine_home}/app/model/issue.rbの中身変更。
進捗率(=done_ratio)に関する部分の処理条件に、「小チケットを持たないこと」を追加しました。
(children?で小チケットを持つか否か判別できる。
http://www.rubydoc.info/github/edavis10/redmine/Issue
)

今のところ特に不具合などは出てないですが、変更するなら自己責任で。
本当はこういうのもプラグインで実現するべきなんだろうか?
というかプラグインでこういう中身の処理までいじれるのかしら?

@@ -547,7 +552,7 @@
   private :workflow_rule_by_attribute
 
   def done_ratio
-    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
+    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio && !self.children?
       status.default_done_ratio
     else
       read_attribute(:done_ratio)
@@ -629,7 +634,7 @@
   # Set the done_ratio using the status if that setting is set.  This will keep the done_ratios
   # even if the user turns off the setting later
   def update_done_ratio_from_issue_status
-    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
+    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio && !self.children?
       self.done_ratio = status.default_done_ratio
     end
   end
@@ -1352,7 +1357,7 @@
       end
 
       # done ratio = weighted average ratio of leaves
-      unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio
+      unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio && !p.children?
         leaves_count = p.leaves.count
         if leaves_count > 0
           average = p.leaves.where("estimated_hours > 0").average(:estimated_hours).to_f