Project

General

Profile

Feature #25035 » 0001-Add-current-date-option-for-date-format-custom-field.patch

Go MAEDA, 2026-03-21 10:54

View differences:

app/models/custom_field.rb
89 89
    'position',
90 90
    'searchable',
91 91
    'default_value',
92
    'default_value_mode',
92 93
    'editable',
93 94
    'visible',
94 95
    'multiple',
......
129 130
    @format ||= Redmine::FieldFormat.find(field_format)
130 131
  end
131 132

  
133
  def default_value
134
    if field_format == 'date' && default_value_mode == 'current_date'
135
      User.current.today.to_s
136
    else
137
      self[:default_value]
138
    end
139
  end
140

  
132 141
  def field_format=(arg)
133 142
    # cannot change format of a saved custom field
134 143
    if new_record?
......
158 167
      end
159 168
    end
160 169

  
161
    if default_value.present? && errors[:regexp].blank?
162
      validate_field_value(default_value).each do |message|
170
    if self[:default_value].present? && errors[:regexp].blank? &&
171
         !(field_format == 'date' && default_value_mode == 'current_date')
172
      validate_field_value(self[:default_value]).each do |message|
163 173
        errors.add :default_value, message
164 174
      end
165 175
    end
app/views/custom_fields/formats/_date.html.erb
1
<p><%= f.date_field(:default_value, :value => @custom_field.default_value, :size => 10) %></p>
2
<%= calendar_for('custom_field_default_value') %>
1
<% default_value_mode = @custom_field.default_value_mode.presence || 'fixed_date' %>
2
<p>
3
  <%= f.label :default_value, l(:field_default_value) %>
4
  <label class="inline">
5
    <%= f.radio_button :default_value_mode, 'fixed_date',
6
                       :checked => default_value_mode == 'fixed_date',
7
                       :data => {:enables => '#custom_field_default_value'} %>
8
    <%= l(:label_date) %>
9
  </label>
10
  <%= f.date_field(:default_value,
11
                   :value => @custom_field[:default_value],
12
                   :size => 10,
13
                   :disabled => default_value_mode == 'current_date') %>
14
  <%= calendar_for('custom_field_default_value') %>
15
</p>
16
<p class="indent">
17
  <label class="inline">
18
    <%= f.radio_button :default_value_mode, 'current_date',
19
                       :checked => default_value_mode == 'current_date',
20
                       :data => {:disables => '#custom_field_default_value'} %>
21
    <%= l(:label_today).titleize %>
22
  </label>
23
</p>
3 24
<p><%= f.text_field :url_pattern, :size => 50, :label => :label_link_values_to %></p>
app/views/custom_fields/index.api.rsb
13 13
      api.is_filter         field.is_filter?
14 14
      api.searchable        field.searchable
15 15
      api.multiple          field.multiple?
16
      api.default_value     field.default_value
16
      api.default_value     field[:default_value]
17
      api.default_value_mode(field.default_value_mode.presence || 'fixed_date') if field.field_format == 'date'
17 18
      api.visible           field.visible?
18 19
      api.editable          field.editable?
19 20

  
lib/redmine/field_format.rb
555 555
    class DateFormat < Unbounded
556 556
      add 'date'
557 557
      self.form_partial = 'custom_fields/formats/date'
558
      field_attributes :default_value_mode
558 559

  
559 560
      def cast_single_value(custom_field, value, customized=nil)
560 561
        value.to_date rescue nil
......
583 584
        {:type => :date}
584 585
      end
585 586

  
587
      def before_custom_field_save(custom_field)
588
        super
589

  
590
        custom_field.default_value_mode =
591
          custom_field.default_value_mode == 'current_date' ? 'current_date' : 'fixed_date'
592
        custom_field.default_value = nil if custom_field.default_value_mode == 'current_date'
593
      end
594

  
586 595
      def group_statement(custom_field)
587 596
        order_statement(custom_field)
588 597
      end
test/functional/custom_fields_controller_test.rb
230 230
    end
231 231
  end
232 232

  
233
  def test_default_value_should_offer_fixed_date_and_current_date_for_date_custom_field
234
    get(
235
      :new,
236
      :params => {
237
        :type => 'IssueCustomField',
238
        :custom_field => {
239
          :field_format => 'date'
240
        }
241
      }
242
    )
243
    assert_response :success
244
    assert_select 'input[type=radio][name=?][value=?]', 'custom_field[default_value_mode]', 'fixed_date'
245
    assert_select 'input[type=radio][name=?][value=?]', 'custom_field[default_value_mode]', 'current_date'
246
    assert_select 'input[type=date][name=?]', 'custom_field[default_value]'
247
  end
248

  
233 249
  def test_default_value_should_not_be_present_for_user_custom_field
234 250
    get(
235 251
      :new,
test/integration/api_test/custom_fields_test.rb
56 56
      assert_select "value:contains(?) + label:contains(?)", bar.id.to_s, 'Bar'
57 57
    end
58 58
  end
59

  
59 60
end
test/integration/api_test/issues_test.rb
681 681
    assert_equal "", issue.custom_field_value(field)
682 682
  end
683 683

  
684
  test "POST /issues.json with omitted date custom field should set current date default" do
685
    User.current = User.find_by_login('jsmith')
686
    field =
687
      IssueCustomField.generate!(
688
        :field_format => 'date',
689
        :default_value_mode => 'current_date',
690
        :trackers => Tracker.all,
691
        :is_for_all => true
692
      )
693
    issue = new_record(Issue) do
694
      post(
695
        '/issues.json',
696
        :params => {
697
          :issue => {
698
            :project_id => 1,
699
            :tracker_id => 1,
700
            :subject => 'API date default',
701
            :custom_field_values => {}
702
          }
703
        },
704
        :headers => credentials('jsmith'))
705
    end
706

  
707
    assert_equal User.current.today.to_s, issue.custom_field_value(field)
708
  end
709

  
710
  test "POST /issues.json with date custom field set to blank should not set current date default" do
711
    field =
712
      IssueCustomField.generate!(
713
        :field_format => 'date',
714
        :default_value_mode => 'current_date',
715
        :trackers => Tracker.all,
716
        :is_for_all => true
717
      )
718
    issue = new_record(Issue) do
719
      post(
720
        '/issues.json',
721
        :params => {
722
          :issue => {
723
            :project_id => 1,
724
            :tracker_id => 1,
725
            :subject => 'API blank date default',
726
            :custom_field_values => {field.id.to_s => ''}
727
          }
728
        },
729
        :headers => credentials('jsmith'))
730
    end
731

  
732
    assert_equal "", issue.custom_field_value(field)
733
  end
734

  
684 735
  test "POST /issues.json with failure should return errors" do
685 736
    assert_no_difference('Issue.count') do
686 737
      post(
test/unit/custom_field_test.rb
72 72
    assert field.valid?
73 73
  end
74 74

  
75
  def test_date_default_value_should_not_be_validated_when_current_date_mode_is_selected
76
    field =
77
      IssueCustomField.new(
78
        :name => 'Date',
79
        :field_format => 'date',
80
        :default_value_mode => 'current_date',
81
        :default_value => 'invalid'
82
      )
83

  
84
    assert field.valid?
85
  end
86

  
87
  def test_date_default_value_should_be_validated_when_fixed_date_mode_is_selected
88
    field = IssueCustomField.new(:name => 'Date', :field_format => 'date', :default_value_mode => 'fixed_date')
89

  
90
    field.default_value = 'invalid'
91
    assert field.invalid?
92

  
93
    field.default_value = '2026-03-21'
94
    assert field.valid?
95
  end
96

  
75 97
  def test_field_format_should_be_validated
76 98
    field = CustomField.new(:name => 'Test', :field_format => 'foo')
77 99
    assert field.invalid?
test/unit/custom_value_test.rb
45 45
    assert_nil v.value
46 46
  end
47 47

  
48
  def test_new_without_value_should_set_current_date_default_for_date_custom_field
49
    user = User.generate!
50
    User.current = user
51
    field = IssueCustomField.generate!(:field_format => 'date', :default_value_mode => 'current_date')
52

  
53
    v = CustomValue.new(:custom_field => field)
54
    assert_equal user.today.to_s, v.value
55
  end
56

  
48 57
  def test_sti_polymorphic_association
49 58
    # Rails uses top level sti class for polymorphic association. See #3978.
50 59
    assert !User.find(4).custom_values.empty?
(4-4/4)