##// END OF EJS Templates
Estimated time recognizes improved time formats (#1092)....
Jean-Philippe Lang -
r1346:a6311a960370
parent child
Show More
@@ -0,0 +1,1
1 Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
@@ -0,0 +1,5
1 require File.dirname(__FILE__) + '/string/conversions'
2
3 class String #:nodoc:
4 include Redmine::CoreExtensions::String::Conversions
5 end
@@ -0,0 +1,40
1 # redMine - project management software
2 # Copyright (C) 2008 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module Redmine #:nodoc:
19 module CoreExtensions #:nodoc:
20 module String #:nodoc:
21 # Custom string conversions
22 module Conversions
23 # Parses hours format and returns a float
24 def to_hours
25 s = self.dup
26 s.strip!
27 unless s =~ %r{^[\d\.,]+$}
28 # 2:30 => 2.5
29 s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
30 # 2h30, 2h, 30m => 2.5, 2, 0.5
31 s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
32 end
33 # 2,5 => 2.5
34 s.gsub!(',', '.')
35 s.to_f
36 end
37 end
38 end
39 end
40 end
@@ -94,6 +94,10 class Issue < ActiveRecord::Base
94 write_attribute(:priority_id, pid)
94 write_attribute(:priority_id, pid)
95 end
95 end
96
96
97 def estimated_hours=(h)
98 write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
99 end
100
97 def validate
101 def validate
98 if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
102 if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
99 errors.add :due_date, :activerecord_error_not_a_date
103 errors.add :due_date, :activerecord_error_not_a_date
@@ -40,19 +40,7 class TimeEntry < ActiveRecord::Base
40 end
40 end
41
41
42 def hours=(h)
42 def hours=(h)
43 s = h.dup
43 write_attribute :hours, (h.is_a?(String) ? h.to_hours : h)
44 if s.is_a?(String)
45 s.strip!
46 unless s =~ %r{^[\d\.,]+$}
47 # 2:30 => 2.5
48 s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
49 # 2h30, 2h, 30m
50 s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
51 end
52 # 2,5 => 2.5
53 s.gsub!(',', '.')
54 end
55 write_attribute :hours, s
56 end
44 end
57
45
58 # tyear, tmonth, tweek assigned where setting spent_on attributes
46 # tyear, tmonth, tweek assigned where setting spent_on attributes
@@ -1,6 +1,7
1 require 'redmine/access_control'
1 require 'redmine/access_control'
2 require 'redmine/menu_manager'
2 require 'redmine/menu_manager'
3 require 'redmine/mime_type'
3 require 'redmine/mime_type'
4 require 'redmine/core_ext'
4 require 'redmine/themes'
5 require 'redmine/themes'
5 require 'redmine/plugin'
6 require 'redmine/plugin'
6
7
@@ -20,6 +20,13 require File.dirname(__FILE__) + '/../test_helper'
20 class IssueTest < Test::Unit::TestCase
20 class IssueTest < Test::Unit::TestCase
21 fixtures :projects, :users, :members, :trackers, :projects_trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :time_entries
21 fixtures :projects, :users, :members, :trackers, :projects_trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :time_entries
22
22
23 def test_create
24 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
25 assert issue.save
26 issue.reload
27 assert_equal 1.5, issue.estimated_hours
28 end
29
23 def test_category_based_assignment
30 def test_category_based_assignment
24 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
31 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
25 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
32 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
General Comments 0
You need to be logged in to leave comments. Login now