scinote-web/app/models/project.rb

229 lines
6.6 KiB
Ruby
Raw Normal View History

2017-06-23 21:19:08 +08:00
class Project < ApplicationRecord
2016-02-12 23:52:43 +08:00
include ArchivableModel, SearchableModel
enum visibility: { hidden: 0, visible: 1 }
auto_strip_attributes :name, nullify: false
2016-02-12 23:52:43 +08:00
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH },
uniqueness: { scope: :team, case_sensitive: false }
2016-02-12 23:52:43 +08:00
validates :visibility, presence: true
2017-01-24 23:34:21 +08:00
validates :team, presence: true
2016-02-12 23:52:43 +08:00
2017-06-28 21:21:32 +08:00
belongs_to :created_by,
foreign_key: 'created_by_id',
class_name: 'User',
optional: true
belongs_to :last_modified_by,
foreign_key: 'last_modified_by_id',
class_name: 'User',
optional: true
belongs_to :archived_by,
foreign_key: 'archived_by_id',
class_name: 'User',
optional: true
belongs_to :restored_by,
foreign_key: 'restored_by_id',
class_name: 'User',
optional: true
belongs_to :team, inverse_of: :projects, optional: true
2016-02-12 23:52:43 +08:00
has_many :user_projects, inverse_of: :project
has_many :users, through: :user_projects
has_many :experiments, inverse_of: :project
has_many :active_experiments, -> { where(archived: false) },
class_name: 'Experiment'
has_many :project_comments, foreign_key: :associated_id, dependent: :destroy
2016-02-12 23:52:43 +08:00
has_many :activities, inverse_of: :project
has_many :tags, inverse_of: :project
has_many :reports, inverse_of: :project, dependent: :destroy
has_many :report_elements, inverse_of: :project, dependent: :destroy
after_commit do
2018-04-23 18:26:21 +08:00
Views::Datatables::DatatablesReport.refresh_materialized_view
end
def self.visible_from_user_by_name(user, team, name)
if user.is_admin_of_team? team
return where('projects.archived IS FALSE AND projects.name ILIKE ?',
"%#{name}%")
end
2018-05-24 21:28:54 +08:00
joins(:user_projects)
.where('user_projects.user_id = ? OR projects.visibility = 1', user.id)
.where('projects.archived IS FALSE AND projects.name ILIKE ?',
"%#{name}%")
end
def self.search(
user,
include_archived,
query = nil,
page = 1,
2017-05-05 22:41:23 +08:00
current_team = nil,
options = {}
)
2016-07-21 19:11:15 +08:00
2017-01-24 23:34:21 +08:00
if current_team
new_query =
Project
.distinct
.joins(:user_projects)
.where('projects.team_id = ?', current_team.id)
unless user.user_teams.find_by(team: current_team).try(:admin?)
# Admins see all projects in the team
new_query = new_query.where(
'projects.visibility = 1 OR user_projects.user_id = ?',
user.id
)
end
2017-05-05 22:41:23 +08:00
new_query = new_query.where_attributes_like(:name, query, options)
2017-01-20 00:09:25 +08:00
if include_archived
return new_query
else
return new_query.where('projects.archived = ?', false)
end
2016-02-12 23:52:43 +08:00
else
new_query = Project
.distinct
.joins(team: :user_teams)
.where('user_teams.user_id = ?', user.id)
if include_archived
new_query =
new_query
.joins(:user_projects)
.where(
'user_teams.role = 2 OR projects.visibility = 1 OR ' \
'user_projects.user_id = ?',
user.id
)
2017-05-05 22:41:23 +08:00
.where_attributes_like('projects.name', query, options)
else
new_query =
new_query
.joins(:user_projects)
.where(
'user_teams.role = 2 OR projects.visibility = 1 OR ' \
'user_projects.user_id = ?',
user.id
)
2017-05-05 22:41:23 +08:00
.where_attributes_like('projects.name', query, options)
.where('projects.archived = ?', false)
end
2016-02-12 23:52:43 +08:00
end
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
2016-02-12 23:52:43 +08:00
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
2016-02-12 23:52:43 +08:00
end
end
def last_activities(count = Constants::ACTIVITY_AND_NOTIF_SEARCH_LIMIT)
2016-07-21 19:11:15 +08:00
activities.order(created_at: :desc).first(count)
2016-02-12 23:52:43 +08:00
end
# Get project comments order by created_at time. Results are paginated
# using last comment id and per_page parameters.
def last_comments(last_id = 1, per_page = Constants::COMMENTS_SEARCH_LIMIT)
last_id = Constants::INFINITY if last_id <= 1
comments = ProjectComment.joins(:project)
.where(projects: { id: id })
.where('comments.id < ?', last_id)
.order(created_at: :desc)
.limit(per_page)
2016-09-27 15:00:02 +08:00
comments.reverse
2016-02-12 23:52:43 +08:00
end
def unassigned_users
2016-07-21 19:11:15 +08:00
User
2017-01-24 23:34:21 +08:00
.joins('INNER JOIN user_teams ON users.id = user_teams.user_id')
.where('user_teams.team_id = ?', team)
2016-08-18 19:24:44 +08:00
.where.not(confirmed_at: nil)
.where('users.id NOT IN (?)',
UserProject.where(project: self).select(:user_id).distinct)
2016-02-12 23:52:43 +08:00
end
def user_role(user)
unless self.users.include? user
return nil
end
return (self.user_projects.select { |up| up.user == user }).first.role
end
def sorted_active_experiments(sort_by = :new)
sort = case sort_by
when 'old' then { created_at: :asc }
when 'atoz' then { name: :asc }
when 'ztoa' then { name: :desc }
else { created_at: :desc }
end
experiments.is_archived(false).order(sort)
2016-07-29 21:47:41 +08:00
end
2016-08-08 20:19:35 +08:00
def archived_experiments
experiments.is_archived(true)
end
def project_my_modules
2016-07-26 14:44:09 +08:00
MyModule.where('"experiment_id" IN (?)', experiments.select(:id))
2016-02-12 23:52:43 +08:00
end
def space_taken
st = 0
2016-07-22 20:31:09 +08:00
project_my_modules.find_each do |my_module|
2016-02-12 23:52:43 +08:00
st += my_module.space_taken
end
st
end
def assigned_samples
Sample.joins(:my_modules).where(my_modules: {
id: my_modules_ids.split(',')
})
end
def my_modules_ids
ids = active_experiments.map do |exp|
exp.my_modules.pluck(:id) if exp.my_modules
end
ids.delete_if { |i| i.flatten.empty? }
ids.join(', ')
end
2016-08-17 19:17:40 +08:00
def assigned_modules(user)
role = user_role(user)
if role.blank?
MyModule.none
elsif role == 'owner'
2016-08-18 16:55:29 +08:00
project_my_modules
.joins(:experiment)
.where('experiments.archived=false')
2016-08-18 17:53:57 +08:00
.where('my_modules.archived=false')
2016-08-17 19:17:40 +08:00
else
project_my_modules
.joins(:user_my_modules)
2016-08-18 16:55:29 +08:00
.joins(:experiment)
.where('experiments.archived=false AND user_my_modules.user_id IN (?)',
user.id)
2016-08-18 17:53:57 +08:00
.where('my_modules.archived=false')
2016-08-17 19:17:40 +08:00
.distinct
end
end
def notifications_count(user)
res = 0
assigned_modules(user).find_each do |t|
res += 1 if t.is_overdue? || t.is_one_day_prior?
end
res
end
2016-02-12 23:52:43 +08:00
end