Revision 1298:4f746d8966dd .svn/pristine/48

View differences:

.svn/pristine/48/4829d2fe162c5f9c318c8ff9b05ff5fc25513144.svn-base
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module WelcomeHelper
21
end
.svn/pristine/48/482dc54fc612e4f812361911050f6c949928488f.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  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
class CustomFieldValue
19
  attr_accessor :custom_field, :customized, :value
20

  
21
  def custom_field_id
22
    custom_field.id
23
  end
24

  
25
  def true?
26
    self.value == '1'
27
  end
28

  
29
  def editable?
30
    custom_field.editable?
31
  end
32

  
33
  def visible?
34
    custom_field.visible?
35
  end
36

  
37
  def required?
38
    custom_field.is_required?
39
  end
40

  
41
  def to_s
42
    value.to_s
43
  end
44

  
45
  def validate_value
46
    custom_field.validate_field_value(value).each do |message|
47
      customized.errors.add(:base, custom_field.name + ' ' + message)
48
    end
49
  end
50
end
.svn/pristine/48/4852f1cf9dc40b28e85de8175f26734a857d7d04.svn-base
1
class SharedEngineController < ApplicationController
2
  def an_action
3
    render_class_and_action 'from alpha_engine'
4
  end
5
end
.svn/pristine/48/4881b5ad6e4efa4165188246776dbe492c56e6df.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  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
class Principal < ActiveRecord::Base
19
  self.table_name = "#{table_name_prefix}users#{table_name_suffix}"
20

  
21
  # Account statuses
22
  STATUS_ANONYMOUS  = 0
23
  STATUS_ACTIVE     = 1
24
  STATUS_REGISTERED = 2
25
  STATUS_LOCKED     = 3
26

  
27
  has_many :members, :foreign_key => 'user_id', :dependent => :destroy
28
  has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", :order => "#{Project.table_name}.name"
29
  has_many :projects, :through => :memberships
30
  has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
31

  
32
  # Groups and active users
33
  scope :active, lambda { where(:status => STATUS_ACTIVE) }
34

  
35
  scope :like, lambda {|q|
36
    q = q.to_s
37
    if q.blank?
38
      where({})
39
    else
40
      pattern = "%#{q}%"
41
      sql = %w(login firstname lastname mail).map {|column| "LOWER(#{table_name}.#{column}) LIKE LOWER(:p)"}.join(" OR ")
42
      params = {:p => pattern}
43
      if q =~ /^(.+)\s+(.+)$/
44
        a, b = "#{$1}%", "#{$2}%"
45
        sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:a) AND LOWER(#{table_name}.lastname) LIKE LOWER(:b))"
46
        sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:b) AND LOWER(#{table_name}.lastname) LIKE LOWER(:a))"
47
        params.merge!(:a => a, :b => b)
48
      end
49
      where(sql, params)
50
    end
51
  }
52

  
53
  # Principals that are members of a collection of projects
54
  scope :member_of, lambda {|projects|
55
    projects = [projects] unless projects.is_a?(Array)
56
    if projects.empty?
57
      where("1=0")
58
    else
59
      ids = projects.map(&:id)
60
      active.uniq.joins(:members).where("#{Member.table_name}.project_id IN (?)", ids)
61
    end
62
  }
63
  # Principals that are not members of projects
64
  scope :not_member_of, lambda {|projects|
65
    projects = [projects] unless projects.is_a?(Array)
66
    if projects.empty?
67
      where("1=0")
68
    else
69
      ids = projects.map(&:id)
70
      where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids)
71
    end
72
  }
73
  scope :sorted, lambda { order(*Principal.fields_for_order_statement)}
74

  
75
  before_create :set_default_empty_values
76

  
77
  def name(formatter = nil)
78
    to_s
79
  end
80

  
81
  def <=>(principal)
82
    if principal.nil?
83
      -1
84
    elsif self.class.name == principal.class.name
85
      self.to_s.downcase <=> principal.to_s.downcase
86
    else
87
      # groups after users
88
      principal.class.name <=> self.class.name
89
    end
90
  end
91

  
92
  # Returns an array of fields names than can be used to make an order statement for principals.
93
  # Users are sorted before Groups.
94
  # Examples:
95
  def self.fields_for_order_statement(table=nil)
96
    table ||= table_name
97
    columns = ['type DESC'] + (User.name_formatter[:order] - ['id']) + ['lastname', 'id']
98
    columns.uniq.map {|field| "#{table}.#{field}"}
99
  end
100

  
101
  protected
102

  
103
  # Make sure we don't try to insert NULL values (see #4632)
104
  def set_default_empty_values
105
    self.login ||= ''
106
    self.hashed_password ||= ''
107
    self.firstname ||= ''
108
    self.lastname ||= ''
109
    self.mail ||= ''
110
    true
111
  end
112
end
.svn/pristine/48/48978cef54e6b0d716c9ba5b5c6c5a3e24326336.svn-base
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module TimelogHelper
21
  include ApplicationHelper
22

  
23
  def render_timelog_breadcrumb
24
    links = []
25
    links << link_to(l(:label_project_all), {:project_id => nil, :issue_id => nil})
26
    links << link_to(h(@project), {:project_id => @project, :issue_id => nil}) if @project
27
    if @issue
28
      if @issue.visible?
29
        links << link_to_issue(@issue, :subject => false)
30
      else
31
        links << "##{@issue.id}"
32
      end
33
    end
34
    breadcrumb links
35
  end
36

  
37
  # Returns a collection of activities for a select field.  time_entry
38
  # is optional and will be used to check if the selected TimeEntryActivity
39
  # is active.
40
  def activity_collection_for_select_options(time_entry=nil, project=nil)
41
    project ||= @project
42
    if project.nil?
43
      activities = TimeEntryActivity.shared.active
44
    else
45
      activities = project.activities
46
    end
47

  
48
    collection = []
49
    if time_entry && time_entry.activity && !time_entry.activity.active?
50
      collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ]
51
    else
52
      collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
53
    end
54
    activities.each { |a| collection << [a.name, a.id] }
55
    collection
56
  end
57

  
58
  def select_hours(data, criteria, value)
59
    if value.to_s.empty?
60
      data.select {|row| row[criteria].blank? }
61
    else
62
      data.select {|row| row[criteria].to_s == value.to_s}
63
    end
64
  end
65

  
66
  def sum_hours(data)
67
    sum = 0
68
    data.each do |row|
69
      sum += row['hours'].to_f
70
    end
71
    sum
72
  end
73

  
74
  def options_for_period_select(value)
75
    options_for_select([[l(:label_all_time), 'all'],
76
                        [l(:label_today), 'today'],
77
                        [l(:label_yesterday), 'yesterday'],
78
                        [l(:label_this_week), 'current_week'],
79
                        [l(:label_last_week), 'last_week'],
80
                        [l(:label_last_n_weeks, 2), 'last_2_weeks'],
81
                        [l(:label_last_n_days, 7), '7_days'],
82
                        [l(:label_this_month), 'current_month'],
83
                        [l(:label_last_month), 'last_month'],
84
                        [l(:label_last_n_days, 30), '30_days'],
85
                        [l(:label_this_year), 'current_year']],
86
                        value)
87
  end
88

  
89
  def format_criteria_value(criteria_options, value)
90
    if value.blank?
91
      "[#{l(:label_none)}]"
92
    elsif k = criteria_options[:klass]
93
      obj = k.find_by_id(value.to_i)
94
      if obj.is_a?(Issue)
95
        obj.visible? ? "#{obj.tracker} ##{obj.id}: #{obj.subject}" : "##{obj.id}"
96
      else
97
        obj
98
      end
99
    else
100
      format_value(value, criteria_options[:format])
101
    end
102
  end
103

  
104
  def report_to_csv(report)
105
    decimal_separator = l(:general_csv_decimal_separator)
106
    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
107
      # Column headers
108
      headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
109
      headers += report.periods
110
      headers << l(:label_total_time)
111
      csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
112
                                    c.to_s,
113
                                    l(:general_csv_encoding) ) }
114
      # Content
115
      report_criteria_to_csv(csv, report.available_criteria, report.columns, report.criteria, report.periods, report.hours)
116
      # Total row
117
      str_total = Redmine::CodesetUtil.from_utf8(l(:label_total_time), l(:general_csv_encoding))
118
      row = [ str_total ] + [''] * (report.criteria.size - 1)
119
      total = 0
120
      report.periods.each do |period|
121
        sum = sum_hours(select_hours(report.hours, report.columns, period.to_s))
122
        total += sum
123
        row << (sum > 0 ? ("%.2f" % sum).gsub('.',decimal_separator) : '')
124
      end
125
      row << ("%.2f" % total).gsub('.',decimal_separator)
126
      csv << row
127
    end
128
    export
129
  end
130

  
131
  def report_criteria_to_csv(csv, available_criteria, columns, criteria, periods, hours, level=0)
132
    decimal_separator = l(:general_csv_decimal_separator)
133
    hours.collect {|h| h[criteria[level]].to_s}.uniq.each do |value|
134
      hours_for_value = select_hours(hours, criteria[level], value)
135
      next if hours_for_value.empty?
136
      row = [''] * level
137
      row << Redmine::CodesetUtil.from_utf8(
138
                        format_criteria_value(available_criteria[criteria[level]], value).to_s,
139
                        l(:general_csv_encoding) )
140
      row += [''] * (criteria.length - level - 1)
141
      total = 0
142
      periods.each do |period|
143
        sum = sum_hours(select_hours(hours_for_value, columns, period.to_s))
144
        total += sum
145
        row << (sum > 0 ? ("%.2f" % sum).gsub('.',decimal_separator) : '')
146
      end
147
      row << ("%.2f" % total).gsub('.',decimal_separator)
148
      csv << row
149
      if criteria.length > level + 1
150
        report_criteria_to_csv(csv, available_criteria, columns, criteria, periods, hours_for_value, level + 1)
151
      end
152
    end
153
  end
154
end
.svn/pristine/48/48b2840db60b271c593d21c38917c44a5158b68b.svn-base
1
# Rails <2.x doesn't define #except
2
class Hash #:nodoc:
3
  # Returns a new hash without the given keys.
4
  def except(*keys)
5
    clone.except!(*keys)
6
  end unless method_defined?(:except)
7

  
8
  # Replaces the hash without the given keys.
9
  def except!(*keys)
10
    keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
11
    keys.each { |key| delete(key) }
12
    self
13
  end unless method_defined?(:except!)
14
end
15

  
16
# NamedScope is new to Rails 2.1
17
unless defined? ActiveRecord::NamedScope
18
  require 'awesome_nested_set/named_scope'
19
  ActiveRecord::Base.class_eval do
20
    include CollectiveIdea::NamedScope
21
  end
22
end
23

  
24
# Rails 1.2.x doesn't define #quoted_table_name
25
class ActiveRecord::Base  #:nodoc:
26
  def self.quoted_table_name
27
    self.connection.quote_column_name(self.table_name)
28
  end unless methods.include?('quoted_table_name')
29
end
.svn/pristine/48/48b4396c87b793f88c5ab4bc586ea45f81977244.svn-base
1
<%= error_messages_for 'message' %>
2
<% replying ||= false %>
3

  
4
<div class="box">
5
<!--[form:message]-->
6
<p><label for="message_subject"><%= l(:field_subject) %></label><br />
7
<%= f.text_field :subject, :size => 120, :id => "message_subject" %>
8

  
9
<% if !replying && User.current.allowed_to?(:edit_messages, @project) %>
10
    <label><%= f.check_box :sticky %><%= l(:label_board_sticky) %></label>
11
    <label><%= f.check_box :locked %><%= l(:label_board_locked) %></label>
12
<% end %>
13
</p>
14

  
15
<% if !replying && !@message.new_record? && User.current.allowed_to?(:edit_messages, @project) %>
16
  <p><label><%= l(:label_board) %></label><br />
17
  <%= f.select :board_id, @project.boards.collect {|b| [b.name, b.id]} %></p>
18
<% end %>
19

  
20
<p>
21
<%= label_tag "message_content", l(:description_message_content), :class => "hidden-for-sighted" %>
22
<%= f.text_area :content, :cols => 80, :rows => 15, :class => 'wiki-edit', :id => 'message_content' %></p>
23
<%= wikitoolbar_for 'message_content' %>
24
<!--[eoform:message]-->
25

  
26
<p><%= l(:label_attachment_plural) %><br />
27
<%= render :partial => 'attachments/form' %></p>
28
</div>

Also available in: Unified diff