@@ -0,0 +1,9 | |||||
|
1 | class AllowNullVersionEffectiveDate < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | change_column :versions, :effective_date, :date, :default => nil | |||
|
4 | end | |||
|
5 | ||||
|
6 | def self.down | |||
|
7 | raise IrreversibleMigration | |||
|
8 | end | |||
|
9 | end |
@@ -426,35 +426,25 class ProjectsController < ApplicationController | |||||
426 | Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? |
|
426 | Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |
427 | redirect_to :controller => 'projects', :action => 'list_files', :id => @project |
|
427 | redirect_to :controller => 'projects', :action => 'list_files', :id => @project | |
428 | end |
|
428 | end | |
429 | @versions = @project.versions |
|
429 | @versions = @project.versions.sort | |
430 | end |
|
430 | end | |
431 |
|
431 | |||
432 | def list_files |
|
432 | def list_files | |
433 | @versions = @project.versions |
|
433 | @versions = @project.versions.sort | |
434 | end |
|
434 | end | |
435 |
|
435 | |||
436 | # Show changelog for @project |
|
436 | # Show changelog for @project | |
437 | def changelog |
|
437 | def changelog | |
438 | @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position') |
|
438 | @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position') | |
439 | retrieve_selected_tracker_ids(@trackers) |
|
439 | retrieve_selected_tracker_ids(@trackers) | |
440 |
|
440 | @versions = @project.versions.sort | ||
441 | @fixed_issues = @project.issues.find(:all, |
|
|||
442 | :include => [ :fixed_version, :status, :tracker ], |
|
|||
443 | :conditions => [ "#{IssueStatus.table_name}.is_closed=? and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}) and #{Issue.table_name}.fixed_version_id is not null", true], |
|
|||
444 | :order => "#{Version.table_name}.effective_date DESC, #{Issue.table_name}.id DESC" |
|
|||
445 | ) unless @selected_tracker_ids.empty? |
|
|||
446 | @fixed_issues ||= [] |
|
|||
447 | end |
|
441 | end | |
448 |
|
442 | |||
449 | def roadmap |
|
443 | def roadmap | |
450 | @trackers = Tracker.find(:all, :conditions => ["is_in_roadmap=?", true], :order => 'position') |
|
444 | @trackers = Tracker.find(:all, :conditions => ["is_in_roadmap=?", true], :order => 'position') | |
451 |
retrieve_selected_tracker_ids(@trackers) |
|
445 | retrieve_selected_tracker_ids(@trackers) | |
452 | conditions = ("1" == params[:completed] ? nil : [ "#{Version.table_name}.effective_date > ?", Date.today]) |
|
446 | conditions = ("1" == params[:completed] ? nil : [ "#{Version.table_name}.effective_date > ? OR #{Version.table_name}.effective_date IS NULL", Date.today]) | |
453 |
|
447 | @versions = @project.versions.find(:all, :conditions => conditions).sort | ||
454 | @versions = @project.versions.find(:all, |
|
|||
455 | :conditions => conditions, |
|
|||
456 | :order => "#{Version.table_name}.effective_date ASC" |
|
|||
457 | ) |
|
|||
458 | end |
|
448 | end | |
459 |
|
449 | |||
460 | def activity |
|
450 | def activity |
@@ -94,7 +94,7 class Query < ActiveRecord::Base | |||||
94 | @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } |
|
94 | @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } | |
95 | @available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } |
|
95 | @available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } | |
96 | @available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } } |
|
96 | @available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } } | |
97 | @available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.collect{|s| [s.name, s.id.to_s] } } |
|
97 | @available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } } | |
98 | unless @project.children.empty? |
|
98 | unless @project.children.empty? | |
99 | @available_filters["subproject_id"] = { :type => :list_one_or_more, :order => 13, :values => @project.children.collect{|s| [s.name, s.id.to_s] } } |
|
99 | @available_filters["subproject_id"] = { :type => :list_one_or_more, :order => 13, :values => @project.children.collect{|s| [s.name, s.id.to_s] } } | |
100 | end |
|
100 | end |
@@ -23,7 +23,7 class Version < ActiveRecord::Base | |||||
23 |
|
23 | |||
24 | validates_presence_of :name |
|
24 | validates_presence_of :name | |
25 | validates_uniqueness_of :name, :scope => [:project_id] |
|
25 | validates_uniqueness_of :name, :scope => [:project_id] | |
26 | validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date |
|
26 | validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date, :allow_nil => true | |
27 |
|
27 | |||
28 | def start_date |
|
28 | def start_date | |
29 | effective_date |
|
29 | effective_date | |
@@ -37,6 +37,16 class Version < ActiveRecord::Base | |||||
37 | effective_date && effective_date <= Date.today |
|
37 | effective_date && effective_date <= Date.today | |
38 | end |
|
38 | end | |
39 |
|
39 | |||
|
40 | # Versions are sorted by effective_date | |||
|
41 | # Those with no effective_date are at the end, sorted by name | |||
|
42 | def <=>(version) | |||
|
43 | if self.effective_date | |||
|
44 | version.effective_date ? (self.effective_date <=> version.effective_date) : -1 | |||
|
45 | else | |||
|
46 | version.effective_date ? 1 : (self.name <=> version.name) | |||
|
47 | end | |||
|
48 | end | |||
|
49 | ||||
40 | private |
|
50 | private | |
41 | def check_integrity |
|
51 | def check_integrity | |
42 | raise "Can't delete version" if self.fixed_issues.find(:first) |
|
52 | raise "Can't delete version" if self.fixed_issues.find(:first) |
@@ -11,17 +11,26 | |||||
11 | <% end %> |
|
11 | <% end %> | |
12 | </div> |
|
12 | </div> | |
13 |
|
13 | |||
14 |
<% if @ |
|
14 | <% if @versions.empty? %><p><i><%= l(:label_no_data) %></i></p><% end %> | |
15 |
|
15 | |||
16 | <% ver_id = nil |
|
16 | <% @versions.each do |version| %> | |
17 | @fixed_issues.each do |issue| %> |
|
17 | <a name="<%= version.name %>"><h3 class="icon22 icon22-package"><%= version.name %></h3></a> | |
18 | <% unless ver_id == issue.fixed_version_id %> |
|
18 | <% if version.completed? %> | |
19 | <% if ver_id %></ul><% end %> |
|
19 | <p><%= format_date(version.effective_date) %></p> | |
20 | <h3 class="icon22 icon22-package"><%= issue.fixed_version.name %></h3> |
|
20 | <% elsif version.effective_date %> | |
21 | <p><%= format_date(issue.fixed_version.effective_date) %><br /> |
|
21 | <p><strong><%=l(:label_roadmap_due_in)%> <%= distance_of_time_in_words Time.now, version.effective_date %> (<%= format_date(version.effective_date) %>)</strong></p> | |
22 | <%=h issue.fixed_version.description %></p> |
|
22 | <% end %> | |
|
23 | <p><%=h version.description %></p> | |||
|
24 | <% issues = version.fixed_issues.find(:all, | |||
|
25 | :include => [:status, :tracker], | |||
|
26 | :conditions => ["#{IssueStatus.table_name}.is_closed=? AND #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')})", true], | |||
|
27 | :order => "#{Tracker.table_name}.position") | |||
|
28 | %> | |||
|
29 | <% if !issues.empty? %> | |||
23 | <ul> |
|
30 | <ul> | |
24 | <% ver_id = issue.fixed_version_id |
|
31 | <% issues.each do |issue| %> | |
25 | end %> |
|
32 | <li><%= link_to_issue(issue) %>: <%=h issue.subject %></li> | |
26 | <li><%= link_to_issue issue %>: <%=h issue.subject %></li> |
|
33 | <% end %> | |
|
34 | </ul> | |||
|
35 | <% end %> | |||
27 | <% end %> |
|
36 | <% end %> |
@@ -18,7 +18,7 | |||||
18 | <a name="<%= version.name %>"><h3 class="icon22 icon22-package"><%= version.name %></h3></a> |
|
18 | <a name="<%= version.name %>"><h3 class="icon22 icon22-package"><%= version.name %></h3></a> | |
19 | <% if version.completed? %> |
|
19 | <% if version.completed? %> | |
20 | <p><%= format_date(version.effective_date) %></p> |
|
20 | <p><%= format_date(version.effective_date) %></p> | |
21 | <% else %> |
|
21 | <% elsif version.effective_date %> | |
22 | <p><strong><%=l(:label_roadmap_due_in)%> <%= distance_of_time_in_words Time.now, version.effective_date %> (<%= format_date(version.effective_date) %>)</strong></p> |
|
22 | <p><strong><%=l(:label_roadmap_due_in)%> <%= distance_of_time_in_words Time.now, version.effective_date %> (<%= format_date(version.effective_date) %>)</strong></p> | |
23 | <% end %> |
|
23 | <% end %> | |
24 | <p><%=h version.description %></p> |
|
24 | <p><%=h version.description %></p> |
@@ -27,7 +27,7 | |||||
27 | <table class="list"> |
|
27 | <table class="list"> | |
28 | <thead><th><%= l(:label_version) %></th><th><%= l(:field_effective_date) %></th><th><%= l(:field_description) %></th><th style="width:15%"></th><th style="width:15%"></th></thead> |
|
28 | <thead><th><%= l(:label_version) %></th><th><%= l(:field_effective_date) %></th><th><%= l(:field_description) %></th><th style="width:15%"></th><th style="width:15%"></th></thead> | |
29 | <tbody> |
|
29 | <tbody> | |
30 | <% for version in @project.versions %> |
|
30 | <% for version in @project.versions.sort %> | |
31 | <tr class="<%= cycle 'odd', 'even' %>"> |
|
31 | <tr class="<%= cycle 'odd', 'even' %>"> | |
32 | <td><%=h version.name %></td> |
|
32 | <td><%=h version.name %></td> | |
33 | <td align="center"><%= format_date(version.effective_date) %></td> |
|
33 | <td align="center"><%= format_date(version.effective_date) %></td> |
@@ -4,7 +4,7 | |||||
4 | <!--[form:version]--> |
|
4 | <!--[form:version]--> | |
5 | <p><%= f.text_field :name, :size => 20, :required => true %></p> |
|
5 | <p><%= f.text_field :name, :size => 20, :required => true %></p> | |
6 | <p><%= f.text_field :description, :size => 60 %></p> |
|
6 | <p><%= f.text_field :description, :size => 60 %></p> | |
7 |
<p><%= f.text_field :effective_date, :size => 10 |
|
7 | <p><%= f.text_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p> | |
8 | <!--[eoform:version]--> |
|
8 | <!--[eoform:version]--> | |
9 | </div> |
|
9 | </div> | |
10 |
|
10 |
@@ -15,3 +15,12 versions_002: | |||||
15 | id: 2 |
|
15 | id: 2 | |
16 | description: Stable release |
|
16 | description: Stable release | |
17 | effective_date: 2006-07-19 |
|
17 | effective_date: 2006-07-19 | |
|
18 | versions_003: | |||
|
19 | created_on: 2006-07-19 21:00:33 +02:00 | |||
|
20 | name: "2.0" | |||
|
21 | project_id: 1 | |||
|
22 | updated_on: 2006-07-19 21:00:33 +02:00 | |||
|
23 | id: 3 | |||
|
24 | description: Future version | |||
|
25 | effective_date: | |||
|
26 | No newline at end of file |
@@ -109,7 +109,7 class ProjectsControllerTest < Test::Unit::TestCase | |||||
109 | get :changelog, :id => 1 |
|
109 | get :changelog, :id => 1 | |
110 | assert_response :success |
|
110 | assert_response :success | |
111 | assert_template 'changelog' |
|
111 | assert_template 'changelog' | |
112 |
assert_not_nil assigns(: |
|
112 | assert_not_nil assigns(:versions) | |
113 | end |
|
113 | end | |
114 |
|
114 | |||
115 | def test_roadmap |
|
115 | def test_roadmap |
General Comments 0
You need to be logged in to leave comments.
Login now