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
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,4 +3,5 @@ tmp/**/*
|
||||||
config/*.yml
|
config/*.yml
|
||||||
db/*.sqlite3
|
db/*.sqlite3
|
||||||
nbproject/
|
nbproject/
|
||||||
|
config/environments/development.rb
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,15 @@ class ApplicationController < ActionController::Base
|
||||||
Thread.current[:application_controller]
|
Thread.current[:application_controller]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Use this method to call a rake task,,
|
||||||
|
# e.g. to deliver mails after there are created.
|
||||||
|
def call_rake(task, options = {})
|
||||||
|
options[:rails_env] ||= Rails.env
|
||||||
|
args = options.map { |n, v| "#{n.to_s.upcase}='#{v}'" }
|
||||||
|
system "/usr/bin/rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
|
@ -139,7 +148,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
# Sends any pending emails that were created during this request.
|
# Sends any pending emails that were created during this request.
|
||||||
def send_email_messages
|
def send_email_messages
|
||||||
Message.send_emails if Message.pending?
|
call_rake :send_emails unless Message.pending.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,8 +6,6 @@ class HomeController < ApplicationController
|
||||||
if @orderGroup
|
if @orderGroup
|
||||||
@financial_transactions = @orderGroup.financial_transactions.find(:all, :order => 'created_on desc', :limit => 3)
|
@financial_transactions = @orderGroup.financial_transactions.find(:all, :order => 'created_on desc', :limit => 3)
|
||||||
end
|
end
|
||||||
# unread messages
|
|
||||||
@messages = Message.find_all_by_recipient_id_and_read(@current_user.id, false, :order => 'messages.created_on desc', :include => :sender)
|
|
||||||
# unaccepted tasks
|
# unaccepted tasks
|
||||||
@unaccepted_tasks = @current_user.unaccepted_tasks
|
@unaccepted_tasks = @current_user.unaccepted_tasks
|
||||||
# task in next week
|
# task in next week
|
||||||
|
|
|
@ -1,25 +1,8 @@
|
||||||
class MessagesController < ApplicationController
|
class MessagesController < ApplicationController
|
||||||
verify :method => :post, :only => [:create, :destroy], :redirect_to => { :action => :index }
|
|
||||||
|
|
||||||
MESSAGE_SEND_SUCCESS = 'Nachricht erfolgreich abgeschickt.'
|
|
||||||
MESSAGE_DELETE_SUCCESS = 'Nachricht gelöscht.'
|
|
||||||
MESSAGES_DELETE_SUCCESS = 'Nachrichten gelöscht.'
|
|
||||||
ERROR_SEND_FAILED = 'Nachricht konnte nicht verschickt werden.'
|
|
||||||
ERROR_CANNOT_DELETE = 'Nachricht kann nicht gelöscht werden.'
|
|
||||||
ERROR_CANNOT_REPLY = 'Auf diese Nachricht kann nicht geantwortet werden.'
|
|
||||||
ERROR_UNKNOWN_USER = 'Unbekannte_r Empfänger_in.'
|
|
||||||
ERROR_INVALID_GROUP = 'Empfängergruppe ist unbekannt oder hat keine Mitglieder.'
|
|
||||||
ERROR_NO_RECIPIENTS = 'Es sind keine Empfänger_innen ausgewählt.'
|
|
||||||
|
|
||||||
# Renders the "inbox" action.
|
# Renders the "inbox" action.
|
||||||
def index
|
def index
|
||||||
inbox
|
@messages = Message.user
|
||||||
render :action => 'inbox'
|
|
||||||
end
|
|
||||||
|
|
||||||
# Shows the user's message inbox.
|
|
||||||
def inbox
|
|
||||||
@messages = Message.find_all_by_recipient_id(@current_user.id, :order => 'messages.created_on desc', :include => :sender)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a new message object.
|
# Creates a new message object.
|
||||||
|
@ -29,136 +12,58 @@ class MessagesController < ApplicationController
|
||||||
|
|
||||||
# Creates a new message.
|
# Creates a new message.
|
||||||
def create
|
def create
|
||||||
# Determine recipient(s)...
|
@message = @current_user.send_messages.new(params[:message])
|
||||||
@recipient_nicks = ''
|
if @message.save
|
||||||
if (params[:everyone] == 'yes')
|
flash[:notice] = "Nachricht ist gespeichert und wird versendet."
|
||||||
@everyone = true
|
redirect_to messages_path
|
||||||
recipients = User.find(:all)
|
|
||||||
else
|
else
|
||||||
recipients = Array.new
|
|
||||||
# users
|
|
||||||
for nick in params[:recipient][:nicks].split(%r{,\s*})
|
|
||||||
if (user = User.find_by_nick(nick))
|
|
||||||
recipients << user
|
|
||||||
@recipient_nicks += "#{nick}, "
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@recipient_nicks = @recipient_nicks[0..-3] unless @recipient_nicks.empty?
|
|
||||||
# group
|
|
||||||
group = Group.find_by_id(params[:recipient][:group_id]) if params[:recipient][:group_id]
|
|
||||||
recipients = recipients | group.users if group
|
|
||||||
end
|
|
||||||
|
|
||||||
# Construct message(s) and save them...
|
|
||||||
if recipients.empty?
|
|
||||||
@message = Message.new(params[:message])
|
|
||||||
@message.sender = @current_user
|
|
||||||
@group = group
|
|
||||||
flash[:error] = ERROR_NO_RECIPIENTS
|
|
||||||
render :action => 'new'
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if (@everyone)
|
|
||||||
recipients_text = 'alle'
|
|
||||||
else
|
|
||||||
recipients_text = @recipient_nicks
|
|
||||||
recipients_text += (group.nil? ? '' : (recipients_text.empty? ? group.name : ", #{group.name}"))
|
|
||||||
end
|
|
||||||
Message.transaction do
|
|
||||||
for recipient in recipients
|
|
||||||
@message = Message.new(
|
|
||||||
:subject => params[:message][:subject],
|
|
||||||
:body => params[:message][:body],
|
|
||||||
:recipient => recipient,
|
|
||||||
:recipients => recipients_text
|
|
||||||
)
|
|
||||||
@message.sender = @current_user
|
|
||||||
@message.save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
flash[:notice] = MESSAGE_SEND_SUCCESS
|
|
||||||
redirect_to :action=> 'index'
|
|
||||||
rescue
|
|
||||||
@group = group
|
|
||||||
flash[:error] = ERROR_SEND_FAILED
|
|
||||||
render :action => 'new'
|
render :action => 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Deletes the message(s) specified by the id/ids param if the current user is the recipient.
|
|
||||||
def destroy
|
|
||||||
ids = Array.new
|
|
||||||
ids << params[:id] if params[:id]
|
|
||||||
ids = ids + params[:ids] if (params[:ids] && params[:ids].is_a?(Array))
|
|
||||||
for id in ids
|
|
||||||
message = Message.find(id)
|
|
||||||
if (message && message.recipient && message.recipient == @current_user)
|
|
||||||
message.destroy
|
|
||||||
else
|
|
||||||
flash[:error] = ERROR_CANNOT_DELETE
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
flash[:notice] = MESSAGE_DELETE_SUCCESS if (flash[:error].blank? && ids.size == 1)
|
|
||||||
flash[:notice] = "#{ids.size} #{MESSAGES_DELETE_SUCCESS}" if (flash[:error].blank? && ids.size > 1)
|
|
||||||
redirect_to :action=> 'index'
|
|
||||||
end
|
|
||||||
|
|
||||||
# Shows a single message.
|
# Shows a single message.
|
||||||
def show
|
def show
|
||||||
@message = Message.find_by_id_and_recipient_id(params[:id], @current_user.id)
|
@message = Message.find(params[:id])
|
||||||
@message.update_attribute('read', true) if (@message && !@message.read?)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Replys to the message specified through :id.
|
# Replys to the message specified through :id.
|
||||||
def reply
|
def reply
|
||||||
message = Message.find(params[:id])
|
message = Message.find(params[:id])
|
||||||
if (message && message.recipient && message.recipient == @current_user && message.sender && message.sender.nick)
|
@message = Message.new(:recipient => message.sender, :subject => "Re: #{message.subject}")
|
||||||
@message = Message.new(
|
@message.body = "#{message.sender.nick} schrieb am #{I18n.l(message.created_at.to_date)} um #{I18n.l(message.created_at, :format => :time)}:\n"
|
||||||
:recipient => message.sender,
|
|
||||||
:subject => "Re: #{message.subject}",
|
|
||||||
:body => "#{message.sender.nick} schrieb am #{I18n.l(message.created_on.to_date)} um #{I18n.l(message.created_on, :format => :time)}:\n"
|
|
||||||
)
|
|
||||||
if (message.body)
|
|
||||||
message.body.each_line{|l| @message.body += "> #{l}"}
|
message.body.each_line{|l| @message.body += "> #{l}"}
|
||||||
end
|
|
||||||
@recipient_nicks = message.sender.nick
|
|
||||||
render :action => 'new'
|
render :action => 'new'
|
||||||
else
|
|
||||||
flash[:error] = ERROR_CANNOT_REPLY
|
|
||||||
redirect_to :action=> 'index'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shows new-message form with the recipient user specified through :id.
|
# Shows new-message form with the recipient user specified through :id.
|
||||||
def user
|
def user
|
||||||
if (recipient = User.find(params[:id]))
|
if (recipient = User.find(params[:id]))
|
||||||
@recipient_nicks = recipient.nick
|
@message = Message.new(:recipient => recipient)
|
||||||
@message = Message.new
|
|
||||||
render :action => 'new'
|
render :action => 'new'
|
||||||
else
|
else
|
||||||
flash[:error] = ERROR_UNKNOWN_USER
|
flash[:error] = 'Unbekannte_r EmpfängerIn.'
|
||||||
redirect_to :action=> 'index'
|
redirect_to :action=> 'index'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shows new-message form with the recipient user specified through :id.
|
# Shows new-message form with the recipient user specified through :id.
|
||||||
def group
|
def group
|
||||||
recipient = Group.find(params[:id], :include => :memberships)
|
group = Group.find(params[:id], :include => :memberships)
|
||||||
if (recipient && !recipient.memberships.empty?)
|
if (group && !group.memberships.empty?)
|
||||||
@message = Message.new
|
@message = Message.new(:group_id => group.id)
|
||||||
@group = recipient
|
|
||||||
render :action => 'new'
|
render :action => 'new'
|
||||||
else
|
else
|
||||||
flash[:error] = ERROR_INVALID_GROUP
|
flash[:error] = 'Empfängergruppe ist unbekannt oder hat keine Mitglieder.'
|
||||||
redirect_to :action=> 'index'
|
redirect_to :action=> 'index'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Auto-complete for recipient user list.
|
# Auto-complete for recipient user list.
|
||||||
def auto_complete_for_recipient_nicks
|
def auto_complete_for_message_recipients_nicks
|
||||||
@users = User.find(:all, :conditions => ['LOWER(nick) LIKE ?', '%' + params[:recipient][:nicks].downcase + '%'], :order => :nick, :limit => 8)
|
@users = User.find(:all,
|
||||||
|
:conditions => ['LOWER(nick) LIKE ?', '%' + params[:message][:recipients_nicks].downcase + '%'],
|
||||||
|
:order => :nick, :limit => 8)
|
||||||
render :partial => '/shared/auto_complete_users'
|
render :partial => '/shared/auto_complete_users'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
17
app/helpers/messages_helper.rb
Normal file
17
app/helpers/messages_helper.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module MessagesHelper
|
||||||
|
def groups_for_select
|
||||||
|
groups = [[" -- Arbeitsgruppen -- ", ""]]
|
||||||
|
groups += Workgroup.find(:all, :order => 'name', :include => :memberships).reject{ |g| g.memberships.empty? }.collect do |g|
|
||||||
|
[g.name, g.id]
|
||||||
|
end
|
||||||
|
groups += [[" -- Bestellgruppen -- ", ""]]
|
||||||
|
groups += Ordergroup.find(:all, :order => 'name', :include => :memberships).reject{ |g| g.memberships.empty? }.collect do |g|
|
||||||
|
[g.name, g.id]
|
||||||
|
end
|
||||||
|
groups
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_subject(message)
|
||||||
|
truncate "<b>#{link_to(h(message.subject), message)}</b> <span style='color:grey'>#{h(message.body)}</span>", :length => 200
|
||||||
|
end
|
||||||
|
end
|
|
@ -21,9 +21,9 @@ class Mailer < ActionMailer::Base
|
||||||
from (message.system_message? ? "FoodSoft <#{APP_CONFIG[:email_sender]}>" : "#{message.sender.nick} <#{message.sender.email}>")
|
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),
|
body :body => message.body, :sender => (message.system_message? ? 'Foodsoft' : message.sender.nick),
|
||||||
:recipients => message.recipients,
|
:recipients => message.recipients,
|
||||||
:reply => url_for(:host => request.host, :controller => "messages", :action => "reply", :id => message),
|
:reply => url_for(:host => request.host, reply_message_path(message),
|
||||||
:profile => url_for(:host => request.host, :controller => "index", :action => "myProfile", :id => message.recipient),
|
:profile => url_for(:host => request.host, my_profile_path),
|
||||||
:link => url_for(:host => request.host, :controller => "messages", :action => "show", :id => message),
|
:link => url_for(:host => request.host, message_path(message),
|
||||||
:foodsoftUrl => url_for(:host => request.host, :controller => "index")
|
:foodsoftUrl => url_for(:host => request.host, :controller => "index")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,59 +1,63 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
# Schema version: 20090102171850
|
# Schema version: 20090115123421
|
||||||
#
|
#
|
||||||
# Table name: messages
|
# Table name: messages
|
||||||
#
|
#
|
||||||
# id :integer(4) not null, primary key
|
# id :integer(4) not null, primary key
|
||||||
# sender_id :integer(4)
|
# sender_id :integer(4)
|
||||||
# recipient_id :integer(4) default(0), not null
|
# recipients_ids :text default(""), not null
|
||||||
# recipients :string(255) default(""), not null
|
# subject :string(255) not null
|
||||||
# subject :string(255) default(""), not null
|
# body :text
|
||||||
# body :text default(""), not null
|
|
||||||
# read :boolean(1) not null
|
|
||||||
# email_state :integer(4) default(0), not null
|
# email_state :integer(4) default(0), not null
|
||||||
# created_on :datetime not null
|
# private :boolean(1)
|
||||||
|
# created_at :datetime
|
||||||
#
|
#
|
||||||
|
|
||||||
class Message < ActiveRecord::Base
|
class Message < ActiveRecord::Base
|
||||||
belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
|
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
|
# Values for the email_state attribute: :none, :pending, :sent, :failed
|
||||||
EMAIL_STATE = {
|
EMAIL_STATE = {
|
||||||
:none => 0,
|
:pending => 0,
|
||||||
:pending => 1,
|
:sent => 1,
|
||||||
:sent => 2,
|
:failed => 2
|
||||||
:failed => 3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validates_presence_of :recipient_id
|
validates_presence_of :recipients_ids, :subject, :body
|
||||||
validates_length_of :subject, :in => 1..255
|
validates_length_of :subject, :in => 1..255
|
||||||
validates_presence_of :recipients
|
|
||||||
validates_presence_of :body
|
|
||||||
validates_inclusion_of :email_state, :in => EMAIL_STATE.values
|
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
|
def before_validation_on_create
|
||||||
if (recipient && recipient.settings["messages.sendAsEmail"] == '1')
|
self.recipients_ids = recipients_ids.uniq.reject { |id| id.blank? } unless recipients_ids.nil?
|
||||||
self.email_state = EMAIL_STATE[:pending]
|
self.recipients_ids = User.all.collect(&:id) if sent_to_all == 1
|
||||||
else
|
|
||||||
self.email_state = EMAIL_STATE[:none]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determines if this new message is a pending email.
|
def add_recipients(users)
|
||||||
def after_create
|
self.recipients_ids = [] if recipients_ids.blank?
|
||||||
@@pending = @@pending || self.email_state == EMAIL_STATE[:pending]
|
self.recipients_ids += users.collect(&:id) unless users.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if there might be pending emails.
|
def group_id=(group_id)
|
||||||
def self.pending?
|
@group_id = group_id
|
||||||
@@pending
|
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
|
end
|
||||||
|
|
||||||
# Returns true if this message is a system message, i.e. was sent automatically by the FoodSoft itself.
|
# Returns true if this message is a system message, i.e. was sent automatically by the FoodSoft itself.
|
||||||
|
@ -61,28 +65,24 @@ class Message < ActiveRecord::Base
|
||||||
self.sender_id.nil?
|
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.
|
# Sends all pending messages that are to be send as emails.
|
||||||
def self.send_emails
|
def self.send_emails
|
||||||
transaction do
|
messages = Message.pending
|
||||||
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
|
for message in messages
|
||||||
if (message.recipient && message.recipient.email && !message.recipient.email.empty?)
|
for recipient in message.recipients
|
||||||
begin
|
if recipient.settings['messages.sendAsEmail'] == 1 && !recipient.email.blank?
|
||||||
Mailer.deliver_message(message)
|
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}\"")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
logger.debug("Done sending emails.") unless messages.empty?
|
message.update_attribute(:email_state, 1)
|
||||||
@@pending = false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -322,20 +322,17 @@ class Order < ActiveRecord::Base
|
||||||
ordergroup = Ordergroup.find_by_name(group_order.group_name)
|
ordergroup = Ordergroup.find_by_name(group_order.group_name)
|
||||||
# Determine group users that want a notification message:
|
# Determine group users that want a notification message:
|
||||||
users = ordergroup.users.reject{|u| u.settings["notify.orderFinished"] != '1'}
|
users = ordergroup.users.reject{|u| u.settings["notify.orderFinished"] != '1'}
|
||||||
unless (users.empty?)
|
unless users.empty?
|
||||||
# Assemble the order message text:
|
# Assemble the order message text:
|
||||||
results = group_order.group_order_article_results.find(:all, :include => [:order_article_result])
|
results = group_order.group_order_article_results.find(:all, :include => [:order_article_result])
|
||||||
# Create user notification messages:
|
# Create user notification messages:
|
||||||
recipients = users.collect{|u| u.nick}.join(', ')
|
|
||||||
for user in users
|
|
||||||
Message.from_template(
|
Message.from_template(
|
||||||
'order_finished',
|
'order_finished',
|
||||||
{:user => user, :group => ordergroup, :order => self, :results => results, :total => group_order.price},
|
{:group => ordergroup, :order => self, :results => results, :total => group_order.price},
|
||||||
{:recipient_id => user.id, :recipients => recipients, :subject => "Bestellung beendet: #{self.name}"}
|
{:recipients_ids => users.collect(&:id), :subject => "Bestellung beendet: #{self.name}"}
|
||||||
).save!
|
).save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -119,13 +119,11 @@ class Ordergroup < Group
|
||||||
# Notify only when order group had a positive balance before the last 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)
|
if (transaction.amount < 0 && self.account_balance < 0 && self.account_balance - transaction.amount >= 0)
|
||||||
users = self.users.reject { |u| u.settings["notify.negativeBalance"] != '1' }
|
users = self.users.reject { |u| u.settings["notify.negativeBalance"] != '1' }
|
||||||
unless (users.empty?)
|
unless users.empty?
|
||||||
recipients = users.collect{|u| u.nick}.join(', ')
|
|
||||||
for user in users
|
|
||||||
Message.from_template(
|
Message.from_template(
|
||||||
'negative_balance',
|
'negative_balance',
|
||||||
{:user => user, :group => self, :transaction => transaction},
|
{:group => self, :transaction => transaction},
|
||||||
{:recipient_id => user.id, :recipients => recipients, :subject => "Gruppenkonto im Minus"}
|
{:recipients_ids => users.collect(&:id), :subject => "Gruppenkonto im Minus"}
|
||||||
).save!
|
).save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,6 +26,7 @@ class User < ActiveRecord::Base
|
||||||
has_many :ordergroups, :through => :memberships, :source => :group
|
has_many :ordergroups, :through => :memberships, :source => :group
|
||||||
has_many :assignments, :dependent => :destroy
|
has_many :assignments, :dependent => :destroy
|
||||||
has_many :tasks, :through => :assignments
|
has_many :tasks, :through => :assignments
|
||||||
|
has_many :send_messages, :class_name => "Message", :foreign_key => "sender_id"
|
||||||
|
|
||||||
attr_accessor :password, :setting_attributes
|
attr_accessor :password, :setting_attributes
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,6 @@
|
||||||
= _("There are") + " #{@unassigned_tasks_number} " + link_to(_("unassigned task(s)"), :controller => "tasks")
|
= _("There are") + " #{@unassigned_tasks_number} " + link_to(_("unassigned task(s)"), :controller => "tasks")
|
||||||
%p{:style => "clear:both"}= link_to _("My tasks"), :controller => "tasks", :action => "myTasks"
|
%p{:style => "clear:both"}= link_to _("My tasks"), :controller => "tasks", :action => "myTasks"
|
||||||
|
|
||||||
- unless @messages.empty?
|
|
||||||
.box_title
|
|
||||||
%h2=_ "Unread messages"
|
|
||||||
.column_content
|
|
||||||
= render :partial => 'messages/unread'
|
|
||||||
%p= link_to _("All messages"), :controller => 'messages', :action => 'inbox'
|
|
||||||
|
|
||||||
- if @orderGroup
|
- if @orderGroup
|
||||||
// Current orders
|
// Current orders
|
||||||
= render :partial => 'ordering/currentOrders'
|
= render :partial => 'ordering/currentOrders'
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
tabs = [
|
tabs = [
|
||||||
{ :name => "Start", :url => root_path, :active => ["index", "messages", "home"],
|
{ :name => "Start", :url => root_path, :active => ["index", "messages", "home"],
|
||||||
:subnav => [
|
:subnav => [
|
||||||
{ :name => "Messages", :url => "/messages/inbox"},
|
{ :name => "Messages", :url => "/messages"},
|
||||||
{ :name => "My tasks", :url => "/home/tasks" },
|
{ :name => "My tasks", :url => "/home/tasks" },
|
||||||
{ :name => "My ordergroup", :url => "/home/ordergroup"},
|
{ :name => "My ordergroup", :url => "/home/ordergroup"},
|
||||||
{ :name => "My profile", :url => "/home/profile"}
|
{ :name => "My profile", :url => "/home/profile"}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
- unless @messages.empty?
|
|
||||||
- form_tag :action => 'destroy' do
|
|
||||||
%table.list
|
|
||||||
%thead
|
|
||||||
%tr
|
|
||||||
%th
|
|
||||||
%input{:type => 'checkbox', :name => 'checkall', :id => 'checkall', :onclick => 'checkUncheckAll(this)'}
|
|
||||||
%th Betreff
|
|
||||||
%th Absender
|
|
||||||
%th Datum
|
|
||||||
%th
|
|
||||||
%tbody
|
|
||||||
- for message in @messages
|
|
||||||
- style = message.read? ? '' : 'font-weight:bold'
|
|
||||||
%tr{:class => cycle('even','odd', :name => 'inbox'), :style => style, :id => message.id, :onclick => "checkRow('#{message.id}')"}
|
|
||||||
%td
|
|
||||||
%input{:type => 'checkbox', :name => 'ids[]', :id => "checkbox_#{message.id}", :value => message.id, :onclick => "checkRow('#{message.id}')"}
|
|
||||||
%td= link_to(h(message.subject), {:controller => 'messages', :action => 'show', :id => message})
|
|
||||||
%td= message.sender ? h(message.sender.nick) : 'FoodSoft'
|
|
||||||
%td= format_time(message.created_on)
|
|
||||||
%td
|
|
||||||
= link_to(image_tag('b_drop.png', :size => "16x16", :border => 0, :alt => 'löschen'), {:controller => 'messages', :action => 'destroy', :id => message}, :method => "post")
|
|
||||||
= link_to('Antworten', :controller => 'messages', :action => 'reply', :id => message) unless message.system_message?
|
|
||||||
%tr
|
|
||||||
%td{:colspan => 5}= submit_tag 'Löschen'
|
|
||||||
|
|
12
app/views/messages/_messages.html.haml
Normal file
12
app/views/messages/_messages.html.haml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
- unless @messages.empty?
|
||||||
|
- form_tag :action => 'destroy' do
|
||||||
|
%table.list
|
||||||
|
%tbody
|
||||||
|
- for message in @messages
|
||||||
|
%tr{:class => cycle('even','odd', :name => 'messages')}
|
||||||
|
%td
|
||||||
|
%b= h(message.sender_name)
|
||||||
|
%td= format_subject(message)
|
||||||
|
%td= format_time(message.created_at)
|
||||||
|
%td= link_to('Antworten', reply_message_path(message))
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
- unless @messages.empty?
|
|
||||||
%table.list
|
|
||||||
%thead
|
|
||||||
%tr
|
|
||||||
%th Betreff
|
|
||||||
%th Absender
|
|
||||||
%th Datum
|
|
||||||
%tbody
|
|
||||||
- for message in @messages
|
|
||||||
%tr{:class => cycle('even','odd', :name => 'inbox')}
|
|
||||||
%td= link_to(h(message.subject), {:controller => 'messages', :action => 'show', :id => message})
|
|
||||||
%td= message.sender ? h(message.sender.nick) : 'FoodSoft'
|
|
||||||
%td= format_time(message.created_on)
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
%h1 Nachrichten - Eingang
|
|
||||||
|
|
||||||
%p= link_to('Neue Nachricht', :action => 'new')
|
|
||||||
|
|
||||||
= render :partial => 'list'
|
|
6
app/views/messages/index.html.haml
Normal file
6
app/views/messages/index.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
- title "Nachrichten im Überblick"
|
||||||
|
|
||||||
|
%p= link_to('Neue Nachricht', :action => 'new')
|
||||||
|
|
||||||
|
#messages
|
||||||
|
= render :partial => 'messages'
|
|
@ -1,6 +1,6 @@
|
||||||
Hallo <%= user.nick %>!
|
Liebe <%= group.name %>,
|
||||||
|
|
||||||
Der Kontostand deiner Bestellgruppe <%= group.name %> ist durch eine Buchung am <%= transaction.created_on.strftime('%d.%m.%Y um %H:%M') %> ins Minus gerutscht: <%= group.account_balance %>
|
euer Kontostand ist durch eine Buchung am <%= transaction.created_on.strftime('%d.%m.%Y um %H:%M') %> ins Minus gerutscht: <%= group.account_balance %>
|
||||||
|
|
||||||
Es wurden <%= transaction.amount %> für "<%= transaction.note %>" abgebucht, die Buchung wurde von <%= transaction.user.nick %> erstellt.
|
Es wurden <%= transaction.amount %> für "<%= transaction.note %>" abgebucht, die Buchung wurde von <%= transaction.user.nick %> erstellt.
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
%h1 Neue Nachricht
|
%h1 Neue Nachricht
|
||||||
|
|
||||||
- form_tag(:action => 'create') do
|
- form_for @message do |f|
|
||||||
= error_messages_for 'message'
|
= f.error_messages
|
||||||
|
|
||||||
%p
|
%p
|
||||||
%label{:for => "message_recipient"} An
|
|
||||||
%fieldset
|
%fieldset
|
||||||
<input type="checkbox" name="everyone" value="yes"
|
= f.check_box :sent_to_all, :onchange => "Element.toggle('recipients')"
|
||||||
= "checked='checked'" if @everyone
|
|
||||||
onchange="Element.toggle('recipients')" />
|
|
||||||
gesamte Foodcoop
|
gesamte Foodcoop
|
||||||
%table{:id => 'recipients', :style => (@everyone ? 'display:none;' : '')}
|
%table#recipients
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b BenutzerInnen:
|
%b BenutzerInnen:
|
||||||
%br/
|
%br/
|
||||||
%small{:style => "color:grey"} (Mehrere Benutzerinnen mit Komma trennen)
|
%small{:style => "color:grey"} (Mehrere Benutzerinnen mit Komma trennen)
|
||||||
%br/
|
%br/
|
||||||
= text_field_with_auto_complete(:recipient, :nicks, {:value => @recipient_nicks}, {:tokens => ","})
|
= text_field_with_auto_complete(:message, :recipients_nicks, {:value => @message.recipients_nicks}, {:tokens => ","})
|
||||||
:javascript
|
:javascript
|
||||||
var userListLoaded = false;
|
var userListLoaded = false;
|
||||||
function checkUserList() {
|
function checkUserList() {
|
||||||
|
@ -27,23 +24,21 @@
|
||||||
return !userListLoaded;
|
return !userListLoaded;
|
||||||
}
|
}
|
||||||
= link_to_remote('Liste', :update => 'user-list', :url => {:action => 'user_list'}, :complete => 'userListLoaded = true', :condition => 'checkUserList()')
|
= link_to_remote('Liste', :update => 'user-list', :url => {:action => 'user_list'}, :complete => 'userListLoaded = true', :condition => 'checkUserList()')
|
||||||
%div{:id => 'user-list', :class => 'auto_complete'}
|
#user-list.auto_complete
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b Gruppe:
|
%b Gruppe:
|
||||||
%br/
|
%br/
|
||||||
%select{:name => 'recipient[group_id]'}
|
= f.select :group_id, groups_for_select, :prompt => " -- Gruppe auswählen --"
|
||||||
%option{:value => '-1'} -- Gruppe --
|
|
||||||
= options_from_collection_for_select(Group.find(:all, :order => 'name', :include => :memberships).reject{|g| g.memberships.empty?}, "id", "name", (@group ? @group.id : nil))
|
|
||||||
|
|
||||||
%p
|
%p
|
||||||
%label{:for => "message_subject"} Betreff
|
= f.label :subject, "Betreff"
|
||||||
%br/
|
%br/
|
||||||
= text_field 'message', 'subject'
|
= f.text_field :subject
|
||||||
|
|
||||||
%p
|
%p
|
||||||
%label{:for => "message_body"} Nachricht
|
= f.label :body, "Nachricht"
|
||||||
%br/
|
%br/
|
||||||
= preserve(text_area 'message', 'body', :cols => '80', :rows => '20')
|
~ f.text_area :body, :cols => '80', :rows => '20'
|
||||||
|
|
||||||
= submit_tag "Senden"
|
= submit_tag "Senden"
|
|
@ -1,8 +1,8 @@
|
||||||
Hallo <%= user.nick %>!
|
Liebe <%= group.name %>,
|
||||||
|
|
||||||
Die Bestellung "<%= order.name %>" wurde am <%= order.ends.strftime('%d.%m.%Y um %H:%M') %> von <%= order.updated_by.nick %> beendet.
|
die Bestellung "<%= order.name %>" wurde am <%= order.ends.strftime('%d.%m.%Y um %H:%M') %> von <%= order.updated_by.nick %> beendet.
|
||||||
|
|
||||||
Für deine Bestellgruppe <%= group.name %> wurden die folgenden Artikel bestellt:
|
Für Euch wurden die folgenden Artikel bestellt:
|
||||||
<% for result in results
|
<% for result in results
|
||||||
article = result.order_article_result -%>
|
article = result.order_article_result -%>
|
||||||
<%= article.name %>: <%= result.quantity %> x <%= article.unit %> = <%= result.quantity * article.gross_price %>
|
<%= article.name %>: <%= result.quantity %> x <%= article.unit %> = <%= result.quantity * article.gross_price %>
|
||||||
|
|
|
@ -1,28 +1,21 @@
|
||||||
%h1 Nachricht anzeigen
|
- title "Nachricht anzeigen"
|
||||||
|
|
||||||
%div{:style => "width:40em"}
|
%div{:style => "width:40em"}
|
||||||
- if @message
|
|
||||||
%table{:style => "width:25em"}
|
%table{:style => "width:25em"}
|
||||||
%tr
|
%tr
|
||||||
%td Von:
|
%td Von:
|
||||||
%td=h @message.system_message? ? 'FoodSoft' : @message.sender.nick
|
%td=h @message.sender_name
|
||||||
%tr
|
|
||||||
%td An:
|
|
||||||
%td=h @message.recipients
|
|
||||||
%tr
|
%tr
|
||||||
%td Betreff:
|
%td Betreff:
|
||||||
%td
|
%td
|
||||||
%b=h @message.subject
|
%b=h @message.subject
|
||||||
%tr
|
%tr
|
||||||
%td Gesendet:
|
%td Gesendet:
|
||||||
%td= format_time(@message.created_on)
|
%td= format_time(@message.created_at)
|
||||||
%hr/
|
%hr/
|
||||||
%p= simple_format(h(@message.body))
|
%p= simple_format(h(@message.body))
|
||||||
%hr/
|
%hr/
|
||||||
%p
|
%p
|
||||||
= link_to('Antworten', :action => 'reply', :id => @message) + ' | ' unless @message.system_message?
|
= link_to('Antworten', reply_message_path(@message))
|
||||||
= link_to('Löschen', {:action => 'destroy', :id => @message}, :method => "post")
|
|
||||||
|
|
|
|
||||||
= link_to 'Nachrichteneingang', :action => 'inbox'
|
= link_to 'Nachricht im Überblick', messages_path
|
||||||
- else
|
|
||||||
%p Nachricht kann nicht angezeigt werden.
|
|
|
@ -1,29 +0,0 @@
|
||||||
# Settings specified here will take precedence over those in config/environment.rb
|
|
||||||
|
|
||||||
# In the development environment your application's code is reloaded on
|
|
||||||
# every request. This slows down response time but is perfect for development
|
|
||||||
# since you don't have to restart the webserver when you make code changes.
|
|
||||||
config.cache_classes = false
|
|
||||||
|
|
||||||
# Log error messages when you accidentally call methods on nil.
|
|
||||||
config.whiny_nils = true
|
|
||||||
|
|
||||||
# Show full error reports and disable caching
|
|
||||||
config.action_controller.consider_all_requests_local = true
|
|
||||||
config.action_controller.perform_caching = false
|
|
||||||
config.action_view.debug_rjs = true
|
|
||||||
|
|
||||||
# Don't care if the mailer can't send
|
|
||||||
config.action_mailer.raise_delivery_errors = false
|
|
||||||
|
|
||||||
# Configure an SMTP server for email sending in development mode:
|
|
||||||
# (cf. http://rails.rubyonrails.com/classes/ActionMailer/Base.html for info on options)
|
|
||||||
#config.action_mailer.smtp_settings = {
|
|
||||||
# :address => "smtp.dresdener27.de",
|
|
||||||
# :port => 25,
|
|
||||||
# :domain => "dresdener27",
|
|
||||||
# :authentication => :login,
|
|
||||||
# :user_name => "benni@dresdener27.de",
|
|
||||||
# :password => "ben234go"
|
|
||||||
#}
|
|
||||||
|
|
|
@ -2,6 +2,9 @@ ActionController::Routing::Routes.draw do |map|
|
||||||
map.my_profile '/home/profile', :controller => 'home', :action => 'profile'
|
map.my_profile '/home/profile', :controller => 'home', :action => 'profile'
|
||||||
map.my_tasks '/home/tasks', :controller => 'tasks', :action => 'myTasks'
|
map.my_tasks '/home/tasks', :controller => 'tasks', :action => 'myTasks'
|
||||||
|
|
||||||
|
map.resources :messages, :only => [:index, :show, :new, :create],
|
||||||
|
:member => { :reply => :get, :user => :get, :group => :get }
|
||||||
|
|
||||||
map.namespace :admin do |admin|
|
map.namespace :admin do |admin|
|
||||||
admin.resources :users
|
admin.resources :users
|
||||||
admin.resources :workgroups, :member => { :memberships => :get }
|
admin.resources :workgroups, :member => { :memberships => :get }
|
||||||
|
|
20
db/migrate/20090115123421_refactor_messaging.rb
Normal file
20
db/migrate/20090115123421_refactor_messaging.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class RefactorMessaging < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
|
||||||
|
drop_table :messages
|
||||||
|
|
||||||
|
create_table :messages do |t|
|
||||||
|
t.references :sender
|
||||||
|
t.text :recipients_ids
|
||||||
|
t.string :subject, :null => false
|
||||||
|
t.text :body
|
||||||
|
t.integer :email_state, :default => 0, :null => false
|
||||||
|
t.boolean :private, :default => false
|
||||||
|
t.datetime :created_at
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
end
|
||||||
|
end
|
16
db/schema.rb
16
db/schema.rb
|
@ -9,7 +9,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20090113111624) do
|
ActiveRecord::Schema.define(:version => 20090114101610) do
|
||||||
|
|
||||||
create_table "article_categories", :force => true do |t|
|
create_table "article_categories", :force => true do |t|
|
||||||
t.string "name", :default => "", :null => false
|
t.string "name", :default => "", :null => false
|
||||||
|
@ -184,18 +184,14 @@ ActiveRecord::Schema.define(:version => 20090113111624) do
|
||||||
|
|
||||||
create_table "messages", :force => true do |t|
|
create_table "messages", :force => true do |t|
|
||||||
t.integer "sender_id"
|
t.integer "sender_id"
|
||||||
t.integer "recipient_id", :default => 0, :null => false
|
t.text "recipients_ids", :null => false
|
||||||
t.string "recipients", :default => "", :null => false
|
t.string "subject", :null => false
|
||||||
t.string "subject", :default => "", :null => false
|
t.text "body"
|
||||||
t.text "body", :null => false
|
|
||||||
t.boolean "read", :default => false, :null => false
|
|
||||||
t.integer "email_state", :default => 0, :null => false
|
t.integer "email_state", :default => 0, :null => false
|
||||||
t.datetime "created_on", :null => false
|
t.boolean "private", :default => false
|
||||||
|
t.datetime "created_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "messages", ["recipient_id"], :name => "index_messages_on_recipient_id"
|
|
||||||
add_index "messages", ["sender_id"], :name => "index_messages_on_sender_id"
|
|
||||||
|
|
||||||
create_table "order_article_results", :force => true do |t|
|
create_table "order_article_results", :force => true do |t|
|
||||||
t.integer "order_id", :default => 0, :null => false
|
t.integer "order_id", :default => 0, :null => false
|
||||||
t.string "name", :default => "", :null => false
|
t.string "name", :default => "", :null => false
|
||||||
|
|
4
lib/tasks/messages.rake
Normal file
4
lib/tasks/messages.rake
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
desc "Deliver messages as emails"
|
||||||
|
task :send_emails => :environment do
|
||||||
|
Message.send_emails
|
||||||
|
end
|
|
@ -240,7 +240,6 @@ table tfoot tr
|
||||||
td
|
td
|
||||||
:padding-top 0.8em
|
:padding-top 0.8em
|
||||||
|
|
||||||
|
|
||||||
tr.edit_inline
|
tr.edit_inline
|
||||||
:background-color = !hover_yellow
|
:background-color = !hover_yellow
|
||||||
td, span
|
td, span
|
||||||
|
|
2
test/fixtures/articles.yml
vendored
2
test/fixtures/articles.yml
vendored
|
@ -1,5 +1,5 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
# Schema version: 20090114101610
|
# Schema version: 20090115123421
|
||||||
#
|
#
|
||||||
# Table name: articles
|
# Table name: articles
|
||||||
#
|
#
|
||||||
|
|
13
test/fixtures/messages.yml
vendored
13
test/fixtures/messages.yml
vendored
|
@ -1,17 +1,16 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
# Schema version: 20090102171850
|
# Schema version: 20090115123421
|
||||||
#
|
#
|
||||||
# Table name: messages
|
# Table name: messages
|
||||||
#
|
#
|
||||||
# id :integer(4) not null, primary key
|
# id :integer(4) not null, primary key
|
||||||
# sender_id :integer(4)
|
# sender_id :integer(4)
|
||||||
# recipient_id :integer(4) default(0), not null
|
# recipients_ids :text default(""), not null
|
||||||
# recipients :string(255) default(""), not null
|
# subject :string(255) not null
|
||||||
# subject :string(255) default(""), not null
|
# body :text
|
||||||
# body :text default(""), not null
|
|
||||||
# read :boolean(1) not null
|
|
||||||
# email_state :integer(4) default(0), not null
|
# email_state :integer(4) default(0), not null
|
||||||
# created_on :datetime not null
|
# private :boolean(1)
|
||||||
|
# created_at :datetime
|
||||||
#
|
#
|
||||||
|
|
||||||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||||
|
|
2
test/fixtures/suppliers.yml
vendored
2
test/fixtures/suppliers.yml
vendored
|
@ -1,5 +1,5 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
# Schema version: 20090114101610
|
# Schema version: 20090115123421
|
||||||
#
|
#
|
||||||
# Table name: suppliers
|
# Table name: suppliers
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in a new issue