Complete refactoring of messaging module. From now messages are saved only once and send afterwards via a the 'send_emails'-rake-task.
This commit is contained in:
parent
6ce6c2c75a
commit
e8d55e50c0
30 changed files with 220 additions and 349 deletions
|
|
@ -21,9 +21,9 @@ class Mailer < ActionMailer::Base
|
|||
from (message.system_message? ? "FoodSoft <#{APP_CONFIG[:email_sender]}>" : "#{message.sender.nick} <#{message.sender.email}>")
|
||||
body :body => message.body, :sender => (message.system_message? ? 'Foodsoft' : message.sender.nick),
|
||||
:recipients => message.recipients,
|
||||
:reply => url_for(:host => request.host, :controller => "messages", :action => "reply", :id => message),
|
||||
:profile => url_for(:host => request.host, :controller => "index", :action => "myProfile", :id => message.recipient),
|
||||
:link => url_for(:host => request.host, :controller => "messages", :action => "show", :id => message),
|
||||
:reply => url_for(:host => request.host, reply_message_path(message),
|
||||
:profile => url_for(:host => request.host, my_profile_path),
|
||||
:link => url_for(:host => request.host, message_path(message),
|
||||
:foodsoftUrl => url_for(:host => request.host, :controller => "index")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,88 +1,88 @@
|
|||
# == Schema Information
|
||||
# Schema version: 20090102171850
|
||||
# Schema version: 20090115123421
|
||||
#
|
||||
# Table name: messages
|
||||
#
|
||||
# id :integer(4) not null, primary key
|
||||
# sender_id :integer(4)
|
||||
# recipient_id :integer(4) default(0), not null
|
||||
# recipients :string(255) default(""), not null
|
||||
# subject :string(255) default(""), not null
|
||||
# body :text default(""), not null
|
||||
# read :boolean(1) not null
|
||||
# email_state :integer(4) default(0), not null
|
||||
# created_on :datetime not null
|
||||
# id :integer(4) not null, primary key
|
||||
# sender_id :integer(4)
|
||||
# recipients_ids :text default(""), not null
|
||||
# subject :string(255) not null
|
||||
# body :text
|
||||
# email_state :integer(4) default(0), not null
|
||||
# private :boolean(1)
|
||||
# created_at :datetime
|
||||
#
|
||||
|
||||
class Message < ActiveRecord::Base
|
||||
belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
|
||||
belongs_to :recipient, :class_name => "User", :foreign_key => "recipient_id"
|
||||
|
||||
attr_accessible :recipient_id, :recipient, :subject, :body, :recipients
|
||||
|
||||
serialize :recipients_ids, Array
|
||||
attr_accessor :sent_to_all, :group_id, :recipients_nicks
|
||||
|
||||
named_scope :pending, :conditions => { :email_state => 0 }
|
||||
named_scope :sent, :conditions => { :email_state => 1 }
|
||||
named_scope :user, :conditions => "sender_id IS NOT NULL", :order => 'created_at DESC', :include => :sender
|
||||
|
||||
# Values for the email_state attribute: :none, :pending, :sent, :failed
|
||||
EMAIL_STATE = {
|
||||
:none => 0,
|
||||
:pending => 1,
|
||||
:sent => 2,
|
||||
:failed => 3
|
||||
:pending => 0,
|
||||
:sent => 1,
|
||||
:failed => 2
|
||||
}
|
||||
|
||||
validates_presence_of :recipient_id
|
||||
validates_presence_of :recipients_ids, :subject, :body
|
||||
validates_length_of :subject, :in => 1..255
|
||||
validates_presence_of :recipients
|
||||
validates_presence_of :body
|
||||
validates_inclusion_of :email_state, :in => EMAIL_STATE.values
|
||||
|
||||
@@pending = false
|
||||
|
||||
# Automatically determine if this message should be send as an email.
|
||||
|
||||
|
||||
# clean up the recipients_ids
|
||||
def before_validation_on_create
|
||||
if (recipient && recipient.settings["messages.sendAsEmail"] == '1')
|
||||
self.email_state = EMAIL_STATE[:pending]
|
||||
else
|
||||
self.email_state = EMAIL_STATE[:none]
|
||||
end
|
||||
self.recipients_ids = recipients_ids.uniq.reject { |id| id.blank? } unless recipients_ids.nil?
|
||||
self.recipients_ids = User.all.collect(&:id) if sent_to_all == 1
|
||||
end
|
||||
|
||||
# Determines if this new message is a pending email.
|
||||
def after_create
|
||||
@@pending = @@pending || self.email_state == EMAIL_STATE[:pending]
|
||||
def add_recipients(users)
|
||||
self.recipients_ids = [] if recipients_ids.blank?
|
||||
self.recipients_ids += users.collect(&:id) unless users.blank?
|
||||
end
|
||||
|
||||
# Returns true if there might be pending emails.
|
||||
def self.pending?
|
||||
@@pending
|
||||
def group_id=(group_id)
|
||||
@group_id = group_id
|
||||
add_recipients Group.find(group_id).users unless group_id.blank?
|
||||
end
|
||||
|
||||
def recipients_nicks=(nicks)
|
||||
@recipients_nicks = nicks
|
||||
add_recipients nicks.split(",").collect { |nick| User.find_by_nick(nick) }
|
||||
end
|
||||
|
||||
def recipient=(user)
|
||||
@recipients_nicks = user.nick
|
||||
end
|
||||
|
||||
# Returns true if this message is a system message, i.e. was sent automatically by the FoodSoft itself.
|
||||
def system_message?
|
||||
self.sender_id.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def sender_name
|
||||
system_message? ? 'Foodsoft' : sender.nick
|
||||
end
|
||||
|
||||
def recipients
|
||||
User.find(recipients_ids)
|
||||
end
|
||||
|
||||
# Sends all pending messages that are to be send as emails.
|
||||
def self.send_emails
|
||||
transaction do
|
||||
messages = find(:all, :conditions => ["email_state = ?", EMAIL_STATE[:pending]], :lock => true)
|
||||
logger.debug("Sending #{messages.size} pending messages as emails...") unless messages.empty?
|
||||
for message in messages
|
||||
if (message.recipient && message.recipient.email && !message.recipient.email.empty?)
|
||||
begin
|
||||
Mailer.deliver_message(message)
|
||||
message.update_attribute(:email_state, EMAIL_STATE[:sent])
|
||||
logger.debug("Delivered message as email: id = #{message.id}, recipient = #{message.recipient.nick}, subject = \"#{message.subject}\"")
|
||||
rescue => exception
|
||||
message.update_attribute(:email_state, EMAIL_STATE[:failed])
|
||||
logger.warn("Failed to deliver message as email: id = #{message.id}, recipient = #{message.recipient.nick}, subject = \"#{message.subject}\", exception = #{exception.message}")
|
||||
end
|
||||
else
|
||||
message.update_attribute(:email_state, EMAIL_STATE[:failed])
|
||||
logger.warn("Cannot deliver message as email (no user email): id = #{message.id}, recipient = #{message.recipient.nick}, subject = \"#{message.subject}\"")
|
||||
messages = Message.pending
|
||||
for message in messages
|
||||
for recipient in message.recipients
|
||||
if recipient.settings['messages.sendAsEmail'] == 1 && !recipient.email.blank?
|
||||
Mailer.deliver_message(message)
|
||||
end
|
||||
end
|
||||
logger.debug("Done sending emails.") unless messages.empty?
|
||||
@@pending = false
|
||||
message.update_attribute(:email_state, 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -322,18 +322,15 @@ class Order < ActiveRecord::Base
|
|||
ordergroup = Ordergroup.find_by_name(group_order.group_name)
|
||||
# Determine group users that want a notification message:
|
||||
users = ordergroup.users.reject{|u| u.settings["notify.orderFinished"] != '1'}
|
||||
unless (users.empty?)
|
||||
unless users.empty?
|
||||
# Assemble the order message text:
|
||||
results = group_order.group_order_article_results.find(:all, :include => [:order_article_result])
|
||||
# Create user notification messages:
|
||||
recipients = users.collect{|u| u.nick}.join(', ')
|
||||
for user in users
|
||||
Message.from_template(
|
||||
'order_finished',
|
||||
{:user => user, :group => ordergroup, :order => self, :results => results, :total => group_order.price},
|
||||
{:recipient_id => user.id, :recipients => recipients, :subject => "Bestellung beendet: #{self.name}"}
|
||||
).save!
|
||||
end
|
||||
Message.from_template(
|
||||
'order_finished',
|
||||
{:group => ordergroup, :order => self, :results => results, :total => group_order.price},
|
||||
{:recipients_ids => users.collect(&:id), :subject => "Bestellung beendet: #{self.name}"}
|
||||
).save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -118,15 +118,13 @@ class Ordergroup < Group
|
|||
def notifyNegativeBalance(transaction)
|
||||
# Notify only when order group had a positive balance before the last transaction:
|
||||
if (transaction.amount < 0 && self.account_balance < 0 && self.account_balance - transaction.amount >= 0)
|
||||
users = self.users.reject{|u| u.settings["notify.negativeBalance"] != '1'}
|
||||
unless (users.empty?)
|
||||
recipients = users.collect{|u| u.nick}.join(', ')
|
||||
for user in users
|
||||
Message.from_template(
|
||||
'negative_balance',
|
||||
{:user => user, :group => self, :transaction => transaction},
|
||||
{:recipient_id => user.id, :recipients => recipients, :subject => "Gruppenkonto im Minus"}
|
||||
).save!
|
||||
users = self.users.reject { |u| u.settings["notify.negativeBalance"] != '1' }
|
||||
unless users.empty?
|
||||
Message.from_template(
|
||||
'negative_balance',
|
||||
{:group => self, :transaction => transaction},
|
||||
{:recipients_ids => users.collect(&:id), :subject => "Gruppenkonto im Minus"}
|
||||
).save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class User < ActiveRecord::Base
|
|||
has_many :ordergroups, :through => :memberships, :source => :group
|
||||
has_many :assignments, :dependent => :destroy
|
||||
has_many :tasks, :through => :assignments
|
||||
has_many :send_messages, :class_name => "Message", :foreign_key => "sender_id"
|
||||
|
||||
attr_accessor :password, :setting_attributes
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue