Redmineプラグイン開発 – 日付指定で時間コストを表示
On 2009/02/14
- NetBeans6.5で作ります。
- ソースはGoogle Codeを参照のこと。
- redmineは「c:\fujihara\Ruby\redmine-0.8.0」にあって、WEBrickを使って動かす。
ValueObject
表示用データを格納するValueObjectをplugin_root/app/libに作成。
Main
# To change this template, choose Tools | Templates # and open the template in the editor. class TimeReportMainVO TRACKER_SUM_STRING = "合計" def initialize @project_name = "" #FIXME @trackers = Hash.new() all_trackers = Tracker.find(:all) all_trackers.each do |tracker| @trackers[tracker.name] = TimeReportDetailVO.new() end @trackers[TRACKER_SUM_STRING] = TimeReportDetailVO.new() end def get_tracker(name) return trackers[name] end def put_tracker(name, value) trackers[name] = value end attr_accessor :project_name, :trackers end
Main has Detailになっている。
Detail
# To change this template, choose Tools | Templates # and open the template in the editor. class TimeReportDetailVO def initialize @estimated_hours = 0.0 @actual_performances = 0.0 @percentages = 0.0 end attr_accessor :estimated_hours, :actual_performances, :percentages end
Controller
ControllerではVOに計算したデータを格納する。
daizu_time_report_controller.rb
require 'logger'
require 'time_report_detail_v_o'
require 'time_report_main_v_o'
class DaizuTimeReportController < ApplicationController
before_filter :init
TRACKER_SUM_STRING = "合計"
def index
if @project_id && @start_date && @due_date
# counting per tracker.
# counting estimated_hours and time_entries and percentages.
@results = []
if @project_id == "all"
@projects.each do |project|
calc_per_project(project)
end
all_sumvo = calc_allsum(@results)
@results.push(all_sumvo)
else
project = Project.find(:first, :conditions => ["id = ?", @project_id])
calc_per_project(project)
end
end
end
def calc_per_project(project)
# per project.
mainvo = TimeReportMainVO.new()
mainvo.project_name = project.name
issues =
Issue.find(:all,
:conditions => ["start_date >= ? and due_date <= ? and project_id = ?",
@start_date, @due_date, project.id])
mainvo = count_per_tracker(issues, mainvo)
mainvo = calc_percentages(mainvo)
@results.push(mainvo)
end
def count_per_tracker(issues, mainvo)
sumvo = mainvo.get_tracker(TRACKER_SUM_STRING)
# counting per project and per tracker.
issues.each do |issue|
tracker_name = @trakcer_names[issue.tracker_id]
detailvo = mainvo.get_tracker(tracker_name)
# counting estimated_hours.
detailvo.estimated_hours += issue.estimated_hours
sumvo.estimated_hours += issue.estimated_hours
# counting time_entries.
time_entry = TimeEntry.find(:all, :conditions => ["issue_id = ?", issue.id])
time_entry.each do |entry|
detailvo.actual_performances += entry.hours
sumvo.actual_performances += entry.hours
end
mainvo.put_tracker(tracker_name, detailvo)
end
mainvo.put_tracker(TRACKER_SUM_STRING, sumvo)
return mainvo
end
def calc_percentages(mainvo)
mainvo.trackers.each do |key, detailvo|
detailvo.percentages =
calc_percentage(detailvo.estimated_hours, detailvo.actual_performances)
mainvo.put_tracker(key, detailvo)
end
return mainvo
end
def calc_percentage(estimated_hours, actual_performances)
if estimated_hours != 0 && actual_performances != 0
percentage =
(actual_performances / estimated_hours) * 100
percentage = percentage * 100
percentage = percentage.round
percentage = percentage / 100
return percentage
else
return 0.0
end
end
def calc_allsum(results)
sumvo = TimeReportMainVO.new()
sumvo.project_name = TRACKER_SUM_STRING
results.each do |result|
result.trackers.each do |tracker_name, detailvo|
detailsumvo = sumvo.get_tracker(tracker_name)
detailsumvo.estimated_hours += detailvo.estimated_hours
detailsumvo.actual_performances += detailvo.actual_performances
sumvo.put_tracker(tracker_name, detailsumvo)
end
end
sumvo.trackers.each do |tracker_name, tracker|
detailsumvo = sumvo.get_tracker(tracker_name)
detailsumvo.percentages =
calc_percentage(detailsumvo.estimated_hours, detailsumvo.actual_performances)
end
return sumvo
end
def init
@log = Logger.new(STDOUT)
@log.level = Logger::DEBUG
@project_id = params[:project_id]
@start_date = params[:start_date]
@due_date = params[:due_date]
@projects = Project.find :all
@trackers = Tracker.find(:all)
@trackers.push(Tracker.new(:name => TRACKER_SUM_STRING))
@trakcer_names = {}
@trackers.each do |tracker|
@trakcer_names[tracker.id] = tracker.name
end
end
end
View
グラフで表示するためにHTML5.JPのライブラリを利用。
plugin_root/app/assets/javascripts/html5jpにライブラリを配置した。
<script src="/javascripts/calendar/calendar.js" type="text/javascript"></script>
<script src="/javascripts/calendar/lang/calendar-ja.js" type="text/javascript"></script>
<script src="/javascripts/calendar/calendar-setup.js" type="text/javascript"></script>
<link href="/stylesheets/calendar.css" media="screen" rel="stylesheet" type="text/css" />
<h2><%= link_to h('大豆トップページ'), :controller => 'daizu_main', :action => 'index' %> > タイムレポート</h2>
<% form_tag({ :controller => 'daizu_time_report', :action => 'index' }, :id => 'query_form') do %>
<p><label for="project_id">プロジェクト</label>
<select name="project_id">
<option value="all">全てのプロジェクト</option>
<% @projects.each do |project| %>
<option value="<%= project.id %>"><%= project.name %></option>
<% end %>
</select>
<p><label for="issue_start_date">開始日</label>
<input id="issue_start_date" name="start_date" size="15" type="text" value="<%= params[:start_date] %>" />
<img alt="Calendar" class="calendar-trigger" id="issue_start_date_trigger" src="/images/calendar.png" />
<script type="text/javascript">
//<![CDATA[
Calendar.setup({inputField : 'issue_start_date', ifFormat : '%Y-%m-%d', button : 'issue_start_date_trigger' });
//]]>
</script></p>
<p><label for="issue_due_date">期限日</label>
<input id="issue_due_date" name="due_date" size="15" type="text" value="<%= params[:due_date] %>" />
<img alt="Calendar" class="calendar-trigger" id="issue_due_date_trigger" src="/images/calendar.png" />
<script type="text/javascript">
//<![CDATA[
Calendar.setup({inputField : 'issue_due_date', ifFormat : '%Y-%m-%d', button : 'issue_due_date_trigger' });
//]]>
</script></p>
<button type="submit">GO</button>
<% end %>
<% if @results %>
<p>[from:<%= params[:start_date] %> to:<%= params[:due_date] %>] のタイムレポート。</p>
<table class="list">
<tr>
<th></th>
<% @trackers.each do |tracker| %>
<th colspan="3" ><%= tracker.name %></th>
<% end %>
</tr>
<tr>
<th></th>
<% @trackers.each do |tracker| %>
<th>予想</th>
<th>実績</th>
<th>進捗</th>
<% end %>
</tr>
<% @results.each do |result| %>
<tr>
<th><%= result.project_name %></th>
<% @trackers.each do |tracker| %>
<td><%= result.get_tracker(tracker.name).estimated_hours %></td>
<td><%= result.get_tracker(tracker.name).actual_performances %></td>
<td>
<table class="progress" style="width: 40px;">
<tr>
<% if result.get_tracker(tracker.name).percentages == 0 %>
<td class="todo" style="width:100%;"></td>
<% elsif result.get_tracker(tracker.name).percentages == 100 %>
<td class="closed" style="width:100%;"></td>
<% elsif result.get_tracker(tracker.name).percentages > 100 %>
<td style="width:100%;background-color:red;"></td>
<% else %>
<td class="closed" style="<%= "width:" + result.get_tracker(tracker.name).percentages.to_s + "%;" %>"></td>
<td class="todo" style="<%= "width:" + (100 - result.get_tracker(tracker.name).percentages).to_s + "%;" %>"></td>
<% end %>
</tr>
</table>
<p class="pourcent"><%= result.get_tracker(tracker.name).percentages.to_s %>%</p>
</td>
<% end %>
</tr>
<% end %>
</table>
<% if params[:project_id] != "all" %>
<% @results.each do |result| %>
<h3><%= result.project_name %>の統計情報</h3>
<!--[if IE]><script src="/plugin_assets/redmine_daizu/javascripts/html5jp/excanvas/excanvas.js" type="text/javascript"></script><![endif]-->
<script src="/plugin_assets/redmine_daizu/javascripts/html5jp/graph/circle.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function() {
var cg = new html5jp.graph.circle("yosou");
if( ! cg ) { return; }
var items = [
<% @trackers.each do |tracker| %>
<% if tracker.name != "合計" %>
<% if result.get_tracker(tracker.name).actual_performances != 0.0 %>
["<%=tracker.name%>", <%= result.get_tracker(tracker.name).actual_performances %>],
<% end %>
<% end %>
<% end %>
];
cg.draw(items);
var cg = new html5jp.graph.circle("jisseki");
if( ! cg ) { return; }
var items = [
<% @trackers.each do |tracker| %>
<% if tracker.name != "合計" %>
<% if result.get_tracker(tracker.name).estimated_hours != 0.0 %>
["<%=tracker.name%>", <%= result.get_tracker(tracker.name).estimated_hours %>],
<% end %>
<% end %>
<% end %>
];
cg.draw(items);
};
</script>
<table>
<tr>
<td>
<h4>予想</h4>
<div>
<canvas width="300" height="200" id="yosou"></canvas>
</div>
</td>
<td>
<h4>実績</h4>
<div>
<canvas width="300" height="200" id="jisseki"></canvas>
</div>
</td>
</tr>
</table>
<% end %>
<% end %>
<% end %>
できあがりのイメージ
おおお!できましたね!!!
僕について
Dai Fujihara
A hero can be anyone.
藤原大はマネージャでありアジャイル実践者だ。そして、プロジェクトリーダー、チェンジ・エージェント、アジャイルコーチ、トレーナーでもある。彼はまたRedmine、Jenkinsといった開発を支援するツール環境の整備や、アジャイル開発を活用した創造的なソフトウェア開発の支援を行っている。さらに、趣味は沖縄離島巡りらしい。
ここ最近の人気
アジャイルコミュニティは超めんどうくさい… 944 view(s)
3年使ったRedmineの使い方について共有したい10の… 579 view(s)
チームとタワーを創造せよ!マシュマロチャレンジでチームビ… 310 view(s)
Javaで入力チェックに使える正規表現まとめ… 199 view(s)
Redmineプラグイン開発 – 史上最高のチームプラグ… 147 view(s)
開発ツールを使うと「思いやり」が減る(後半) #swat… 137 view(s)
開発ツールを使うと「思いやり」が減る(前半) #swat… 134 view(s)
LinkStationのようなNASを買ってもバックアッ… 102 view(s)
Redmineプラグイン開発 – パーキングロットチャー… 95 view(s)
DAOとかDTOとかVOとかEntityとか… 86 view(s)
永久保存の本
Jonathan Rasmusson (著), 西村 直人 (翻訳), 角谷 信太郎 (翻訳)
アジャイルサムライ―それはソフトウェアを顧客に届ける猛々しきプロフェッショナルだ。本書では、圧倒的なアジャイルプロジェクトの姿を見せる。2011年爆発的にヒットしたアジャイル開発に情熱を持つエンジニアに届けたい本。
Mike Cohn (著), マイク コーン (著), 安井 力 (翻訳), 角谷 信太郎 (翻訳)
採用した現在のタイトルは、見積りや計画づくりといったプロセスを、アジャイルに進めなければならないと謳っているのだ。見積りと計画づくりがアジャイルでないのに、プロジェクトがアジャイルであるということはありえない。(イントロダクションより)
Venkat Subramaniam (著), Andy Hunt (著), 木下 史彦 (監訳), 角谷 信太郎 (監訳)
アジャイルな習慣とは一体何なのか?本書ではプラクティスを交えながら、その姿勢を読者に問いかけている。世代や役割をこえて色褪せない「アジャイル」に対する良書。Amazonレビュー
メアリー・ポッペンディーク (著), トム・ポッペンディーク (著), 高嶋 優子 (翻訳), 天野 勝 (翻訳), 平鍋 健児 (翻訳)
「トヨタ生産方式」を源流にする「リーン開発」をソフトウエア開発に取り入れるための具体的方法を紹介した本です。本書は、リーンの7大原則を「価値」「ムダ」「スピード」「人」「知識」「品質」「パートナー」に整理し、ソフト開発現場にどうしたら効果的に適用できるかを、多くの実例を交えながら具体的に説明します。
タグ
Agile ant Apache bash Eclipse GlassFish install Java Javascript kobo Linux log4j Management Maven Open Source PHP Pukiwiki Python Redmine Ruby Ruby on Rails Scrum Spring Struts Struts2 Subversion Test Tomcat Trac VBA Web WebDriver WebLogic Windows WordPress 働く 勉強会 嫁(ベータ) 思い出し笑う 我思う 旅する 映画/ドラマ 英語を話す 読むと聞く 過去を語るアーカイブ

















