socialforge/app/models/journal.rb

248 lines
9.0 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#coding=utf-8
# Redmine - project management software
# Copyright (C) 2006-2013 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 Journal < ActiveRecord::Base
require 'net/http'
require 'json'
include UserScoreHelper
belongs_to :journalized, :polymorphic => true,:touch => true
# added as a quick fix to allow eager loading of the polymorphic association
# since always associated to an issue, for now
belongs_to :issue, :foreign_key => :journalized_id,:touch => true
belongs_to :user
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
# added by fq
has_one :journal_reply
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
# 被ForgeActivity虚拟关联
#has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy 评论不应该算入
# 被ForgeMessage虚拟关联
has_many :forge_messages, :class_name => 'ForgeMessage',:as =>:forge_message ,:dependent => :destroy
has_many :at_messages, as: :at_message, dependent: :destroy
acts_as_attachable
attr_accessor :indice
acts_as_event :title =>Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.project_index}#{status}: #{o.issue.subject}" },
:description =>:notes,
:author => :user,
:group => :issue,
:type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
acts_as_activity_provider :type => 'issues',
:author_key => :user_id,
:find_options => {:include => [{:issue => :project}, :details, :user],
:conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
"(#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
before_create :split_private_notes, :add_journals_count
# fq
after_save :act_as_activity,:be_user_score, :act_as_forge_message, act_as_at_message(:notes, :user_id)
# end
#after_destroy :down_user_score
#before_save :be_user_score
after_destroy :down_user_score, :decrease_issues_journal_count
scope :visible, lambda {|*args|
user = args.shift || User.current
includes(:issue => :project).
where(Issue.visible_condition(user, *args)).
where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
}
def save(*args)
# Do not save an empty journal
(details.empty? && notes.blank?) ? false : super
end
# Returns the new status if the journal contains a status change, otherwise nil
def new_status
c = details.detect {|detail| detail.prop_key == 'status_id'}
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
end
def new_value_for(prop)
c = details.detect {|detail| detail.prop_key == prop}
c ? c.value : nil
end
def editable_by?(usr)
usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
end
def project
journalized.respond_to?(:project) ? journalized.project : nil
end
def attachments
journalized.respond_to?(:attachments) ? journalized.attachments : nil
end
# Returns a string of css classes
def css_classes
s = 'journal'
s << ' has-notes' unless notes.blank?
s << ' has-details' unless details.blank?
s << ' private-notes' if private_notes?
s
end
def notify?
@notify != false
end
def notify=(arg)
@notify = arg
end
def recipients
notified = journalized.notified_users
if private_notes?
notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
end
notified.map(&:mail)
end
def watcher_recipients
notified = journalized.notified_watchers
if private_notes?
notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
end
notified.map(&:mail)
end
## added_by_fq
def self.reference_message(user_id)
message = Journal.find_by_sql("select id, journalized_id, user_id, notes, created_on from journals where id in (select journal_id from journal_replies where reply_id = #{user_id})")
message += Journal.find_by_sql("select id, journalized_id, user_id, notes, created_on from journals where journalized_id in (select id from issues where assigned_to_id = #{user_id})")
message
end
##
private
def split_private_notes
if private_notes?
if notes.present?
if details.any?
# Split the journal (notes/changes) so we don't have half-private journals
journal = Journal.new(:journalized => journalized, :user => user, :notes => nil, :private_notes => false)
journal.details = details
journal.save
self.details = []
self.created_on = journal.created_on
end
else
# Blank notes should not be private
self.private_notes = false
end
end
true
end
# fq
def act_as_activity
self.acts << Activity.new(:user_id => self.user_id)
end
# end
# # Time 2015-02-27 13:30:19
# # Author lizanle
# # Description 公共表中需要保存一份该记录
# def act_as_forge_activity
# self.forge_acts << ForgeActivity.new(:user_id => self.user_id,
# :project_id => self.issue.project.id)
#
# end
# 缺陷状态更改,消息提醒
def act_as_forge_message
receivers = []
# 直接回复
if self.user_id != self.issue.author_id
receivers << self.issue.author_id
end
if self.user_id != self.issue.assigned_to_id && self.issue.assigned_to_id != self.issue.author_id # 指派人不是自己的话,则给指派人发送
receivers << self.issue.assigned_to_id
end
receivers.each do |r|
self.forge_messages << ForgeMessage.new(:user_id => r, :project_id => self.issue.project_id, :viewed => false)
end
end
# 更新用户分数 -by zjc
def be_user_score
#新建了缺陷留言且留言不为空,不为空白
if !self.notes.nil? && self.notes.gsub(' ','') != ''
#协同得分加分
UserScore.joint(:post_issue_message, self.user,self.issue.author,self, { message_id: self.id })
update_messges_for_issue(self.user,1)
update_messges_for_issue(self.user,2,self.issue.project)
end
end
# 减少用户分数 -by zjc
def down_user_score
#删除有效缺陷留言
if !self.notes.nil? && self.notes.gsub(' ','') != ''
#协同得分减分
UserScore.joint(:delete_issue_message, self.user,self.issue.author,self, { message_id: self.id })
update_messges_for_issue(self.user,1)
update_messges_for_issue(self.user,2,self.issue.project)
end
end
# 减少留言数量统计
def decrease_issues_journal_count
unless self.issue.project.nil?
journal_count = self.issue.project.project_score.issue_journal_num - 1
# project = self.issue.project
self.issue.project.project_score.update_attribute(:issue_journal_num, journal_count < 0 ? 0 : journal_count)
end
end
# issue留言总数更新
def add_journals_count
if !self.issue.project.nil? && self.journalized_type == "Issue" && !self.issue.project.project_score.nil?
project = self.issue.project
project.project_score.update_attribute(:issue_journal_num, project.project_score.issue_journal_num + 1)
end
end
# 回复issue的时候更新issue的时候
def update_issue_time
if self.journalized_type == "Issue"
forge_activity = ForgeActivity.where("forge_act_id =? and forge_act_type =?", self.issue, "Issue").first
forge_activity.update_attribute(:created_at, self.created_on) unless forge_activity.nil?
end
end
#缺陷回复微信模板消息
# def issue_wechat_message
# if !self.notes.nil? && self.notes.gsub(' ','') != ''
# ws = WechatService.new
# content = strip_html self.notes.html_safe, 200
# ws.comment_template self.issue.author_id, "issues", self.journalized_id, "#{l(:label_issue_comment_template)}", self.user.try(:realname), format_time(self.created_on), content
# end
# end
end