summaryrefslogtreecommitdiffstats
path: root/redmine/app/models
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2006-06-28 18:11:03 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2006-06-28 18:11:03 +0000
commit6b7650e2f03156ea1e3985b30c1995e44c317e3d (patch)
treee56734d45ecc3725b77f3da1ede21294e49ec894 /redmine/app/models
parent73e0b8f8b3c9350018a7d8fda143dd9b8aa6f091 (diff)
downloadredmine-6b7650e2f03156ea1e3985b30c1995e44c317e3d.tar.gz
redmine-6b7650e2f03156ea1e3985b30c1995e44c317e3d.zip
Initial commit
git-svn-id: http://redmine.rubyforge.org/svn/trunk@4 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'redmine/app/models')
-rw-r--r--redmine/app/models/attachment.rb81
-rw-r--r--redmine/app/models/custom_field.rb38
-rw-r--r--redmine/app/models/custom_value.rb41
-rw-r--r--redmine/app/models/document.rb24
-rw-r--r--redmine/app/models/enumeration.rb45
-rw-r--r--redmine/app/models/issue.rb55
-rw-r--r--redmine/app/models/issue_category.rb28
-rw-r--r--redmine/app/models/issue_history.rb23
-rw-r--r--redmine/app/models/issue_status.rb47
-rw-r--r--redmine/app/models/mailer.rb36
-rw-r--r--redmine/app/models/member.rb29
-rw-r--r--redmine/app/models/news.rb28
-rw-r--r--redmine/app/models/permission.rb63
-rw-r--r--redmine/app/models/project.rb44
-rw-r--r--redmine/app/models/role.rb31
-rw-r--r--redmine/app/models/tracker.rb31
-rw-r--r--redmine/app/models/user.rb89
-rw-r--r--redmine/app/models/version.rb30
-rw-r--r--redmine/app/models/workflow.rb25
19 files changed, 788 insertions, 0 deletions
diff --git a/redmine/app/models/attachment.rb b/redmine/app/models/attachment.rb
new file mode 100644
index 000000000..bc1ff5d87
--- /dev/null
+++ b/redmine/app/models/attachment.rb
@@ -0,0 +1,81 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require "digest/md5"
+
+class Attachment < ActiveRecord::Base
+ belongs_to :container, :polymorphic => true
+ belongs_to :author, :class_name => "User", :foreign_key => "author_id"
+
+ validates_presence_of :filename
+
+ def file=(incomming_file)
+ unless incomming_file.nil?
+ @temp_file = incomming_file
+ if @temp_file.size > 0
+ self.filename = sanitize_filename(@temp_file.original_filename)
+ self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
+ self.content_type = @temp_file.content_type
+ self.size = @temp_file.size
+ end
+ end
+ end
+
+ # Copy temp file to its final location
+ def before_save
+ if @temp_file && (@temp_file.size > 0)
+ logger.debug("saving '#{self.diskfile}'")
+ File.open(diskfile, "wb") do |f|
+ f.write(@temp_file.read)
+ end
+ self.digest = Digest::MD5.hexdigest(File.read(diskfile))
+ end
+ end
+
+ # Deletes file on the disk
+ def after_destroy
+ if self.filename?
+ File.delete(diskfile) if File.exist?(diskfile)
+ end
+ end
+
+ # Returns file's location on disk
+ def diskfile
+ "#{RDM_STORAGE_PATH}/#{self.disk_filename}"
+ end
+
+ def increment_download
+ increment!(:downloads)
+ end
+
+ # returns last created projects
+ def self.most_downloaded
+ find(:all, :limit => 5, :order => "downloads DESC")
+ end
+
+private
+ def sanitize_filename(value)
+ # get only the filename, not the whole path
+ just_filename = value.gsub(/^.*(\\|\/)/, '')
+ # NOTE: File.basename doesn't work right with Windows paths on Unix
+ # INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
+
+ # Finally, replace all non alphanumeric, underscore or periods with underscore
+ @filename = just_filename.gsub(/[^\w\.\-]/,'_')
+ end
+
+end
diff --git a/redmine/app/models/custom_field.rb b/redmine/app/models/custom_field.rb
new file mode 100644
index 000000000..9e817d1ef
--- /dev/null
+++ b/redmine/app/models/custom_field.rb
@@ -0,0 +1,38 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class CustomField < ActiveRecord::Base
+
+ has_and_belongs_to_many :projects
+ has_many :custom_values, :dependent => true
+ has_many :issues, :through => :issue_custom_values
+
+ validates_presence_of :name, :typ
+ validates_uniqueness_of :name
+
+ TYPES = [
+ [ "Integer", 0 ],
+ [ "String", 1 ],
+ [ "Date", 2 ],
+ [ "Boolean", 3 ],
+ [ "List", 4 ]
+ ].freeze
+
+ def self.for_all
+ find(:all, :conditions => ["is_for_all=?", true])
+ end
+end
diff --git a/redmine/app/models/custom_value.rb b/redmine/app/models/custom_value.rb
new file mode 100644
index 000000000..faaa8ff82
--- /dev/null
+++ b/redmine/app/models/custom_value.rb
@@ -0,0 +1,41 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class CustomValue < ActiveRecord::Base
+ belongs_to :issue
+ belongs_to :custom_field
+
+protected
+ def validate
+ errors.add(custom_field.name, "can't be blank") if custom_field.is_required? and value.empty?
+ errors.add(custom_field.name, "is not valid") unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
+
+ case custom_field.typ
+ when 0
+ errors.add(custom_field.name, "must be an integer") unless value =~ /^[0-9]*$/
+ when 1
+ errors.add(custom_field.name, "is too short") if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
+ errors.add(custom_field.name, "is too long") if custom_field.max_length > 0 and value.length > custom_field.max_length
+ when 2
+ errors.add(custom_field.name, "must be a valid date") unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
+ when 3
+
+ when 4
+ errors.add(custom_field.name, "is not a valid value") unless custom_field.possible_values.split('|').include? value or value.empty?
+ end
+ end
+end
diff --git a/redmine/app/models/document.rb b/redmine/app/models/document.rb
new file mode 100644
index 000000000..40c3a1656
--- /dev/null
+++ b/redmine/app/models/document.rb
@@ -0,0 +1,24 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Document < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
+ has_many :attachments, :as => :container, :dependent => true
+
+ validates_presence_of :title
+end
diff --git a/redmine/app/models/enumeration.rb b/redmine/app/models/enumeration.rb
new file mode 100644
index 000000000..d93db4445
--- /dev/null
+++ b/redmine/app/models/enumeration.rb
@@ -0,0 +1,45 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Enumeration < ActiveRecord::Base
+ before_destroy :check_integrity
+
+ validates_presence_of :opt, :name
+
+ OPTIONS = [
+ ["Issue priorities", "IPRI"],
+ ["Document categories", "DCAT"]
+ ].freeze
+
+ def self.get_values(option)
+ find(:all, :conditions => ['opt=?', option])
+ end
+
+ def name
+ _ self.attributes['name']
+ end
+
+private
+ def check_integrity
+ case self.opt
+ when "IPRI"
+ raise "Can't delete enumeration" if Issue.find(:first, :conditions => ["priority_id=?", self.id])
+ when "DCAT"
+ raise "Can't delete enumeration" if Document.find(:first, :conditions => ["category_id=?", self.id])
+ end
+ end
+end
diff --git a/redmine/app/models/issue.rb b/redmine/app/models/issue.rb
new file mode 100644
index 000000000..4a21ac03b
--- /dev/null
+++ b/redmine/app/models/issue.rb
@@ -0,0 +1,55 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Issue < ActiveRecord::Base
+
+ belongs_to :project
+ belongs_to :tracker
+ belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
+ belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+ belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
+ belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
+ belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
+ belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
+
+ has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
+ has_many :attachments, :as => :container, :dependent => true
+
+ has_many :custom_values, :dependent => true
+ has_many :custom_fields, :through => :custom_values
+
+ validates_presence_of :subject, :descr, :priority, :tracker, :author
+
+ # set default status for new issues
+ def before_create
+ self.status = IssueStatus.default
+ build_history
+ end
+
+ def long_id
+ "%05d" % self.id
+ end
+
+private
+ # Creates an history for the issue
+ def build_history
+ @history = self.histories.build
+ @history.status = self.status
+ @history.author = self.author
+ end
+
+end
diff --git a/redmine/app/models/issue_category.rb b/redmine/app/models/issue_category.rb
new file mode 100644
index 000000000..b7d4e2623
--- /dev/null
+++ b/redmine/app/models/issue_category.rb
@@ -0,0 +1,28 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class IssueCategory < ActiveRecord::Base
+ before_destroy :check_integrity
+ belongs_to :project
+
+ validates_presence_of :name
+
+private
+ def check_integrity
+ raise "Can't delete category" if Issue.find(:first, :conditions => ["category_id=?", self.id])
+ end
+end
diff --git a/redmine/app/models/issue_history.rb b/redmine/app/models/issue_history.rb
new file mode 100644
index 000000000..f410a39c1
--- /dev/null
+++ b/redmine/app/models/issue_history.rb
@@ -0,0 +1,23 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class IssueHistory < ActiveRecord::Base
+ belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
+ belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+
+ validates_presence_of :status
+end
diff --git a/redmine/app/models/issue_status.rb b/redmine/app/models/issue_status.rb
new file mode 100644
index 000000000..ff34cb666
--- /dev/null
+++ b/redmine/app/models/issue_status.rb
@@ -0,0 +1,47 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class IssueStatus < ActiveRecord::Base
+ before_destroy :check_integrity
+ has_many :workflows, :foreign_key => "old_status_id"
+
+ validates_presence_of :name
+ validates_uniqueness_of :name
+
+ # Returns the default status for new issues
+ def self.default
+ find(:first, :conditions =>["is_default=?", true])
+ end
+
+ # Returns an array of all statuses the given role can switch to
+ def new_statuses_allowed_to(role, tracker)
+ statuses = []
+ for workflow in self.workflows.find(:all, :include => :new_status)
+ statuses << workflow.new_status if workflow.role_id == role.id and workflow.tracker_id == tracker.id
+ end unless role.nil?
+ statuses
+ end
+
+ def name
+ _ self.attributes['name']
+ end
+
+private
+ def check_integrity
+ raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id]) or IssueHistory.find(:first, :conditions => ["status_id=?", self.id])
+ end
+end
diff --git a/redmine/app/models/mailer.rb b/redmine/app/models/mailer.rb
new file mode 100644
index 000000000..b04ec7ebc
--- /dev/null
+++ b/redmine/app/models/mailer.rb
@@ -0,0 +1,36 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Mailer < ActionMailer::Base
+
+ def issue_change_status(issue)
+ # Sends to all project members
+ @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
+ @from = 'redmine@somenet.foo'
+ @subject = "Issue ##{issue.id} has been updated"
+ @body['issue'] = issue
+ end
+
+ def issue_add(issue)
+ # Sends to all project members
+ @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
+ @from = 'redmine@somenet.foo'
+ @subject = "Issue ##{issue.id} has been reported"
+ @body['issue'] = issue
+ end
+
+end
diff --git a/redmine/app/models/member.rb b/redmine/app/models/member.rb
new file mode 100644
index 000000000..d37936561
--- /dev/null
+++ b/redmine/app/models/member.rb
@@ -0,0 +1,29 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Member < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :role
+ belongs_to :project
+
+ validates_presence_of :role, :user, :project
+ validates_uniqueness_of :user_id, :scope => :project_id
+
+ def name
+ self.user.display_name
+ end
+end
diff --git a/redmine/app/models/news.rb b/redmine/app/models/news.rb
new file mode 100644
index 000000000..0642a4bf5
--- /dev/null
+++ b/redmine/app/models/news.rb
@@ -0,0 +1,28 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class News < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+
+ validates_presence_of :title, :shortdescr, :descr
+
+ # returns last created news
+ def self.latest
+ find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
+ end
+end
diff --git a/redmine/app/models/permission.rb b/redmine/app/models/permission.rb
new file mode 100644
index 000000000..f66214119
--- /dev/null
+++ b/redmine/app/models/permission.rb
@@ -0,0 +1,63 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Permission < ActiveRecord::Base
+ has_and_belongs_to_many :roles
+
+ validates_presence_of :controller, :action, :descr
+
+ GROUPS = {
+ 100 => "Project",
+ 200 => "Membres",
+ 300 => "Versions",
+ 400 => "Issue categories",
+ 1000 => "Issues",
+ 1100 => "News",
+ 1200 => "Documents",
+ 1300 => "Files",
+ }.freeze
+
+ @@cached_perms_for_public = nil
+ @@cached_perms_for_roles = nil
+
+ def name
+ self.controller + "/" + self.action
+ end
+
+ def group_id
+ (self.sort / 100)*100
+ end
+
+ def self.allowed_to_public(action)
+ @@cached_perms_for_public ||= find(:all, :conditions => ["public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
+ @@cached_perms_for_public.include? action
+ end
+
+ def self.allowed_to_role(action, role)
+ @@cached_perms_for_roles ||=
+ begin
+ perms = {}
+ find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
+ perms
+ end
+ @@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role
+ end
+
+ def self.allowed_to_role_expired
+ @@cached_perms_for_roles = nil
+ end
+end
diff --git a/redmine/app/models/project.rb b/redmine/app/models/project.rb
new file mode 100644
index 000000000..7c50ee8cb
--- /dev/null
+++ b/redmine/app/models/project.rb
@@ -0,0 +1,44 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Project < ActiveRecord::Base
+ has_many :versions, :dependent => true, :order => "versions.date DESC"
+ has_many :members, :dependent => true
+ has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
+ has_many :documents, :dependent => true
+ has_many :news, :dependent => true, :order => "news.created_on DESC", :include => :author
+ has_many :issue_categories, :dependent => true
+ has_and_belongs_to_many :custom_fields
+
+ validates_presence_of :name, :descr
+
+ # returns 5 last created projects
+ def self.latest
+ find(:all, :limit => 5, :order => "created_on DESC")
+ end
+
+ # Returns current version of the project
+ def current_version
+ versions.find(:first, :conditions => [ "date <= ?", Date.today ], :order => "date DESC, id DESC")
+ end
+
+ # Returns an array of all custom fields enabled for project issues
+ # (explictly associated custom fields and custom fields enabled for all projects)
+ def custom_fields_for_issues
+ (CustomField.for_all + custom_fields).uniq
+ end
+end
diff --git a/redmine/app/models/role.rb b/redmine/app/models/role.rb
new file mode 100644
index 000000000..ce880b5cc
--- /dev/null
+++ b/redmine/app/models/role.rb
@@ -0,0 +1,31 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Role < ActiveRecord::Base
+ before_destroy :check_integrity
+ has_and_belongs_to_many :permissions
+ has_many :workflows, :dependent => true
+ has_many :members
+
+ validates_presence_of :name
+ validates_uniqueness_of :name
+
+private
+ def check_integrity
+ raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id])
+ end
+end
diff --git a/redmine/app/models/tracker.rb b/redmine/app/models/tracker.rb
new file mode 100644
index 000000000..6b123d79c
--- /dev/null
+++ b/redmine/app/models/tracker.rb
@@ -0,0 +1,31 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Tracker < ActiveRecord::Base
+ before_destroy :check_integrity
+ has_many :issues
+ has_many :workflows, :dependent => true
+
+ def name
+ _ self.attributes['name']
+ end
+
+private
+ def check_integrity
+ raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
+ end
+end
diff --git a/redmine/app/models/user.rb b/redmine/app/models/user.rb
new file mode 100644
index 000000000..1bc1b5802
--- /dev/null
+++ b/redmine/app/models/user.rb
@@ -0,0 +1,89 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require "digest/sha1"
+
+class User < ActiveRecord::Base
+ has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
+
+ attr_accessor :password
+ attr_accessor :last_before_login_on
+ # Prevents unauthorized assignments
+ attr_protected :admin
+
+ validates_presence_of :login, :firstname, :lastname, :mail
+ validates_uniqueness_of :login, :mail
+
+ # Login must contain lettres, numbers, underscores only
+ validates_format_of :login, :with => /^[a-z0-9_]+$/i
+ validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
+
+ def before_create
+ self.hashed_password = User.hash_password(self.password)
+ end
+
+ def after_create
+ @password = nil
+ end
+
+ # Returns the user that matches user's login and password
+ def try_to_login
+ @user = User.login(self.login, self.password)
+ unless @user.nil?
+ @user.last_before_login_on = @user.last_login_on
+ @user.update_attribute(:last_login_on, DateTime.now)
+ end
+ @user
+ end
+
+ # Return user's full name for display
+ def display_name
+ firstname + " " + lastname #+ (self.admin ? " (Admin)" : "" )
+ end
+
+ # Returns the user that matches the given login and password
+ def self.login(login, password)
+ hashed_password = hash_password(password || "")
+ find(:first,
+ :conditions => ["login = ? and hashed_password = ? and locked = ?", login, hashed_password, false])
+ end
+
+ def check_password?(clear_password)
+ User.hash_password(clear_password) == self.hashed_password
+ end
+
+ def change_password(current_password, new_password)
+ self.hashed_password = User.hash_password(new_password)
+ save
+ end
+
+ def role_for_project(project_id)
+ @role_for_projects ||=
+ begin
+ roles = {}
+ self.memberships.each { |m| roles.store m.project_id, m.role_id }
+ roles
+ end
+ @role_for_projects[project_id]
+ end
+
+private
+ # Return password digest
+ def self.hash_password(clear_password)
+ Digest::SHA1.hexdigest(clear_password)
+ end
+end
diff --git a/redmine/app/models/version.rb b/redmine/app/models/version.rb
new file mode 100644
index 000000000..02dee15c8
--- /dev/null
+++ b/redmine/app/models/version.rb
@@ -0,0 +1,30 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Version < ActiveRecord::Base
+ before_destroy :check_integrity
+ belongs_to :project
+ has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
+ has_many :attachments, :as => :container, :dependent => true
+
+ validates_presence_of :name, :descr
+
+private
+ def check_integrity
+ raise "Can't delete version" if self.fixed_issues.find(:first)
+ end
+end
diff --git a/redmine/app/models/workflow.rb b/redmine/app/models/workflow.rb
new file mode 100644
index 000000000..212e33350
--- /dev/null
+++ b/redmine/app/models/workflow.rb
@@ -0,0 +1,25 @@
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Workflow < ActiveRecord::Base
+
+ belongs_to :role
+ belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
+ belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
+
+ validates_presence_of :role, :old_status, :new_status
+end