Project

General

Profile

Feature #15180 » 0001-Add-a-start-date-to-versions.patch

Patch against trunk @ r21131 - Mischa The Evil, 2021-08-13 23:04

View differences:

app/models/version.rb
130 130
  validates_uniqueness_of :name, :scope => [:project_id], :case_sensitive => true
131 131
  validates_length_of :name, :maximum => 60
132 132
  validates_length_of :description, :wiki_page_title, :maximum => 255
133
  validates :effective_date, :date => true
133
  validates :start_date, :effective_date, :date => true
134 134
  validates_inclusion_of :status, :in => VERSION_STATUSES
135 135
  validates_inclusion_of :sharing, :in => VERSION_SHARINGS
136 136

  
......
154 154

  
155 155
  safe_attributes 'name',
156 156
                  'description',
157
                  'start_date',
157 158
                  'effective_date',
158 159
                  'due_date',
159 160
                  'wiki_page_title',
......
218 219
    base_reload(*args)
219 220
  end
220 221

  
222
  # Returns the start_date of a given version from the database
223
  def self.persistent_start_date(version)
224
    Version.visible.where(id: version.id).pluck(:start_date)
225
  end
226

  
221 227
  def start_date
222
    @start_date ||= fixed_issues.minimum('start_date')
228
    @start_date = (read_attribute('start_date') || fixed_issues.minimum('start_date'))
223 229
  end
224 230

  
225 231
  def due_date
app/views/projects/settings/_versions.html.erb
24 24
  <thead><tr>
25 25
    <th><%= l(:label_version) %></th>
26 26
    <th><%= l(:field_default_version) %></th>
27
    <th><%= l(:field_start_date) %></th>
27 28
    <th><%= l(:field_effective_date) %></th>
28 29
    <th><%= l(:field_description) %></th>
29 30
    <th><%= l(:field_status) %></th>
......
36 37
    <tr class="version <%=h version.status %> <%= 'shared' if version.project != @project %>">
37 38
    <td class="name <%= 'icon icon-shared' if version.project != @project %>"><%= link_to_version version %></td>
38 39
    <td class="tick"><%= checked_image(version.id == @project.default_version_id) %></td>
39
    <td class="date"><%= format_date(version.effective_date) %></td>
40
    <td class="start_date"><%= format_date(version.start_date) %></td>
41
    <td class="due_date"><%= format_date(version.effective_date) %></td>
40 42
    <td class="description"><%= version.description %></td>
41 43
    <td class="status"><%= l("version_status_#{version.status}") %></td>
42 44
    <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
app/views/versions/_form.html.erb
8 8
  <p><%= f.select :status, Version::VERSION_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %></p>
9 9
<% end %>
10 10
<p><%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %></p>
11
<p>
12
  <%= f.date_field :start_date, :size => 10,
13
                                :value => Version.persistent_start_date(@version) %>
14
  <%= calendar_for('version_start_date') %>
15
</p>
11 16
<p><%= f.date_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
12 17
<p><%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %></p>
13 18
<% if @version.new_record? %>
app/views/versions/_overview.html.erb
1 1
<div class="version-overview">
2
<% if version.completed? %>
3
  <p><%= format_date(version.effective_date) %></p>
4
<% elsif version.effective_date %>
5
  <p><strong><%= due_date_distance_in_words(version.effective_date) %></strong> (<%= format_date(version.effective_date) %>)</p>
2
<p>
3
<%= "#{l(:field_start_date)}: #{format_date(version.start_date)}" if version.start_date %>
4
<% if version.start_date && version.due_date %>
5
&#8211;
6 6
<% end %>
7
<%= "#{l(:field_due_date)}: #{format_date(version.due_date)}" if version.due_date %>
8
<% if version.effective_date && !version.completed? %>
9
<strong><%= "(#{due_date_distance_in_words(version.effective_date)})" %></strong>
10
<% end %>
11
</p>
7 12

  
8 13
<p><%=h version.description %></p>
9 14
<% if version.custom_field_values.any? %>
app/views/versions/index.api.rsb
7 7
      api.name            version.name
8 8
      api.description     version.description
9 9
      api.status          version.status
10
      api.start_date      version.start_date
10 11
      api.due_date        version.effective_date
11 12
      api.sharing         version.sharing
12 13
      api.wiki_page_title version.wiki_page_title
app/views/versions/show.api.rsb
5 5
  api.name            @version.name
6 6
  api.description     @version.description
7 7
  api.status          @version.status
8
  api.start_date      @version.start_date
8 9
  api.due_date        @version.effective_date
9 10
  api.sharing         @version.sharing
10 11
  api.wiki_page_title @version.wiki_page_title
db/migrate/20210806100000_add_start_date_to_versions.rb
1
class AddStartDateToVersions < ActiveRecord::Migration[5.2]
2
  def change
3
    add_column :versions, :start_date, :date, :after => :description
4
  end
5
end
test/functional/versions_controller_test.rb
289 289

  
290 290
  def test_post_update
291 291
    @request.session[:user_id] = 2
292

  
293
    today = Date.today
292 294
    put :update, :params => {
293 295
      :id => 2,
294 296
      :version => {
295 297
        :name => 'New version name',
296
        :effective_date => Date.today.strftime("%Y-%m-%d")
298
        :start_date => today.yesterday.strftime("%Y-%m-%d"),
299
        :effective_date => today.strftime("%Y-%m-%d")
297 300
      }
298 301
    }
299 302
    assert_redirected_to :controller => 'projects', :action => 'settings',
300 303
                         :tab => 'versions', :id => 'ecookbook'
301 304
    version = Version.find(2)
302 305
    assert_equal 'New version name', version.name
303
    assert_equal Date.today, version.effective_date
306
    assert_equal today.yesterday, version.start_date
307
    assert_equal today, version.effective_date
304 308
  end
305 309

  
306 310
  def test_post_update_with_validation_failure
test/unit/version_test.rb
53 53
    assert_nil project.reload.default_version
54 54
  end
55 55

  
56
  def test_invalid_start_date_validation
57
    v = Version.new(:project => Project.find(1), :name => '1.1',
58
                    :start_date => '99999-01-01')
59
    assert !v.valid?
60
    v.start_date = '2012-11-33'
61
    assert !v.valid?
62
    v.start_date = '2012-31-11'
63
    assert !v.valid?
64
    v.start_date = '-2012-31-11'
65
    assert !v.valid?
66
    v.start_date = 'ABC'
67
    assert !v.valid?
68
    assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
69
                   v.errors[:start_date]
70
  end
71

  
56 72
  def test_invalid_effective_date_validation
57 73
    v = Version.new(:project => Project.find(1), :name => '1.1',
58 74
                    :effective_date => '99999-01-01')
......
69 85
                   v.errors[:effective_date]
70 86
  end
71 87

  
88
  def test_start_date_with_no_value_saved_should_be_the_date_of_the_earliest_issue
89
      project = Project.find(1)
90
      Issue.generate!(:project => project, :subject => 'not assigned', :start_date => '2021-01-01')
91
      v = Version.create!(:project => project, :name => 'Progress')
92
      add_issue(v, :estimated_hours => 10, :start_date => '2021-03-01')
93
      add_issue(v, :estimated_hours => 10, :start_date => '2021-02-01')
94

  
95
      assert_equal '2021-02-01', v.start_date.to_s
96
  end
97

  
98
  def test_start_date_with_a_value_saved_should_be_the_value
99
      project = Project.find(1)
100
      v = Version.create!(:project => project, :name => 'Progress', :start_date => '2021-01-05')
101
      add_issue(v, :estimated_hours => 10, :start_date => '2020-03-01')
102

  
103
      assert_equal '2021-01-05', v.start_date.to_s
104
  end
105

  
72 106
  def test_progress_should_be_0_with_no_assigned_issues
73 107
    project = Project.find(1)
74 108
    v = Version.create!(:project => project, :name => 'Progress')
(3-3/3)