From e8d55e50c09381089d6777d8d31fe0cfadb05390 Mon Sep 17 00:00:00 2001 From: Benjamin Meichsner Date: Thu, 15 Jan 2009 18:26:37 +0100 Subject: [PATCH] Complete refactoring of messaging module. From now messages are saved only once and send afterwards via a the 'send_emails'-rake-task. --- .gitignore | 1 + app/controllers/application.rb | 11 +- app/controllers/home_controller.rb | 2 - app/controllers/messages_controller.rb | 139 +++--------------- app/helpers/messages_helper.rb | 17 +++ app/models/mailer.rb | 6 +- app/models/message.rb | 108 +++++++------- app/models/order.rb | 15 +- app/models/ordergroup.rb | 16 +- app/models/user.rb | 1 + app/views/home/index.html.haml | 7 - app/views/layouts/_main_tabnav.html.erb | 2 +- app/views/messages/_list.haml | 26 ---- app/views/messages/_messages.html.haml | 12 ++ app/views/messages/_unread.haml | 15 -- app/views/messages/inbox.haml | 5 - app/views/messages/index.html.haml | 6 + app/views/messages/negative_balance.rhtml | 4 +- app/views/messages/new.haml | 27 ++-- app/views/messages/order_finished.rhtml | 6 +- app/views/messages/show.haml | 45 +++--- config/environments/development.rb | 29 ---- config/routes.rb | 3 + .../20090115123421_refactor_messaging.rb | 20 +++ db/schema.rb | 18 +-- lib/tasks/messages.rake | 4 + public/stylesheets/sass/main.sass | 1 - test/fixtures/articles.yml | 2 +- test/fixtures/messages.yml | 19 ++- test/fixtures/suppliers.yml | 2 +- 30 files changed, 220 insertions(+), 349 deletions(-) create mode 100644 app/helpers/messages_helper.rb delete mode 100644 app/views/messages/_list.haml create mode 100644 app/views/messages/_messages.html.haml delete mode 100644 app/views/messages/_unread.haml delete mode 100644 app/views/messages/inbox.haml create mode 100644 app/views/messages/index.html.haml delete mode 100644 config/environments/development.rb create mode 100644 db/migrate/20090115123421_refactor_messaging.rb create mode 100644 lib/tasks/messages.rake diff --git a/.gitignore b/.gitignore index 80f720bd..1bbfdc76 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ tmp/**/* config/*.yml db/*.sqlite3 nbproject/ +config/environments/development.rb diff --git a/app/controllers/application.rb b/app/controllers/application.rb index c9f60d15..3569d6c2 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -12,6 +12,15 @@ class ApplicationController < ActionController::Base def self.current Thread.current[:application_controller] 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 @@ -139,7 +148,7 @@ class ApplicationController < ActionController::Base # Sends any pending emails that were created during this request. def send_email_messages - Message.send_emails if Message.pending? + call_rake :send_emails unless Message.pending.empty? end end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 0d2817c0..29fbd97c 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -6,8 +6,6 @@ class HomeController < ApplicationController if @orderGroup @financial_transactions = @orderGroup.financial_transactions.find(:all, :order => 'created_on desc', :limit => 3) 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 = @current_user.unaccepted_tasks # task in next week diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 5b060e5f..ca3f1039 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -1,27 +1,10 @@ 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. def index - inbox - render :action => 'inbox' + @messages = Message.user 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 - + # Creates a new message object. def new @message = Message.new @@ -29,136 +12,58 @@ class MessagesController < ApplicationController # Creates a new message. def create - # Determine recipient(s)... - @recipient_nicks = '' - if (params[:everyone] == 'yes') - @everyone = true - recipients = User.find(:all) + @message = @current_user.send_messages.new(params[:message]) + if @message.save + flash[:notice] = "Nachricht ist gespeichert und wird versendet." + redirect_to messages_path 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' - 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. def show - @message = Message.find_by_id_and_recipient_id(params[:id], @current_user.id) - @message.update_attribute('read', true) if (@message && !@message.read?) + @message = Message.find(params[:id]) end # Replys to the message specified through :id. def reply 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}", - :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}"} - end - @recipient_nicks = message.sender.nick - render :action => 'new' - else - flash[:error] = ERROR_CANNOT_REPLY - redirect_to :action=> 'index' - end + @message = Message.new(:recipient => message.sender, :subject => "Re: #{message.subject}") + @message.body = "#{message.sender.nick} schrieb am #{I18n.l(message.created_at.to_date)} um #{I18n.l(message.created_at, :format => :time)}:\n" + message.body.each_line{|l| @message.body += "> #{l}"} + render :action => 'new' end # Shows new-message form with the recipient user specified through :id. def user if (recipient = User.find(params[:id])) - @recipient_nicks = recipient.nick - @message = Message.new + @message = Message.new(:recipient => recipient) render :action => 'new' else - flash[:error] = ERROR_UNKNOWN_USER + flash[:error] = 'Unbekannte_r EmpfängerIn.' redirect_to :action=> 'index' end end # Shows new-message form with the recipient user specified through :id. def group - recipient = Group.find(params[:id], :include => :memberships) - if (recipient && !recipient.memberships.empty?) - @message = Message.new - @group = recipient + group = Group.find(params[:id], :include => :memberships) + if (group && !group.memberships.empty?) + @message = Message.new(:group_id => group.id) render :action => 'new' else - flash[:error] = ERROR_INVALID_GROUP + flash[:error] = 'Empfängergruppe ist unbekannt oder hat keine Mitglieder.' redirect_to :action=> 'index' end end # Auto-complete for recipient user list. - def auto_complete_for_recipient_nicks - @users = User.find(:all, :conditions => ['LOWER(nick) LIKE ?', '%' + params[:recipient][:nicks].downcase + '%'], :order => :nick, :limit => 8) + def auto_complete_for_message_recipients_nicks + @users = User.find(:all, + :conditions => ['LOWER(nick) LIKE ?', '%' + params[:message][:recipients_nicks].downcase + '%'], + :order => :nick, :limit => 8) render :partial => '/shared/auto_complete_users' end diff --git a/app/helpers/messages_helper.rb b/app/helpers/messages_helper.rb new file mode 100644 index 00000000..75d7afae --- /dev/null +++ b/app/helpers/messages_helper.rb @@ -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 "#{link_to(h(message.subject), message)} #{h(message.body)}", :length => 200 + end +end diff --git a/app/models/mailer.rb b/app/models/mailer.rb index f5f100d8..65c4d3c9 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -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 diff --git a/app/models/message.rb b/app/models/message.rb index 0235ca89..7a6d8222 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -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 diff --git a/app/models/order.rb b/app/models/order.rb index 39627d27..7a78d0c2 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -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 diff --git a/app/models/ordergroup.rb b/app/models/ordergroup.rb index 713e5303..98622c14 100644 --- a/app/models/ordergroup.rb +++ b/app/models/ordergroup.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 7c24dee3..ce879be0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 82b40582..4f3c4af9 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -27,13 +27,6 @@ = _("There are") + " #{@unassigned_tasks_number} " + link_to(_("unassigned task(s)"), :controller => "tasks") %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 // Current orders = render :partial => 'ordering/currentOrders' diff --git a/app/views/layouts/_main_tabnav.html.erb b/app/views/layouts/_main_tabnav.html.erb index 153e875c..40fe2dd9 100644 --- a/app/views/layouts/_main_tabnav.html.erb +++ b/app/views/layouts/_main_tabnav.html.erb @@ -3,7 +3,7 @@ tabs = [ { :name => "Start", :url => root_path, :active => ["index", "messages", "home"], :subnav => [ - { :name => "Messages", :url => "/messages/inbox"}, + { :name => "Messages", :url => "/messages"}, { :name => "My tasks", :url => "/home/tasks" }, { :name => "My ordergroup", :url => "/home/ordergroup"}, { :name => "My profile", :url => "/home/profile"} diff --git a/app/views/messages/_list.haml b/app/views/messages/_list.haml deleted file mode 100644 index 61eae23c..00000000 --- a/app/views/messages/_list.haml +++ /dev/null @@ -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' - \ No newline at end of file diff --git a/app/views/messages/_messages.html.haml b/app/views/messages/_messages.html.haml new file mode 100644 index 00000000..0ada3cf8 --- /dev/null +++ b/app/views/messages/_messages.html.haml @@ -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)) + \ No newline at end of file diff --git a/app/views/messages/_unread.haml b/app/views/messages/_unread.haml deleted file mode 100644 index f433ed6c..00000000 --- a/app/views/messages/_unread.haml +++ /dev/null @@ -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) - - diff --git a/app/views/messages/inbox.haml b/app/views/messages/inbox.haml deleted file mode 100644 index d6615d60..00000000 --- a/app/views/messages/inbox.haml +++ /dev/null @@ -1,5 +0,0 @@ -%h1 Nachrichten - Eingang - -%p= link_to('Neue Nachricht', :action => 'new') - -= render :partial => 'list' \ No newline at end of file diff --git a/app/views/messages/index.html.haml b/app/views/messages/index.html.haml new file mode 100644 index 00000000..7d4f4eb1 --- /dev/null +++ b/app/views/messages/index.html.haml @@ -0,0 +1,6 @@ +- title "Nachrichten im Überblick" + +%p= link_to('Neue Nachricht', :action => 'new') + +#messages + = render :partial => 'messages' \ No newline at end of file diff --git a/app/views/messages/negative_balance.rhtml b/app/views/messages/negative_balance.rhtml index 11e15175..d5ff0c66 100644 --- a/app/views/messages/negative_balance.rhtml +++ b/app/views/messages/negative_balance.rhtml @@ -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. diff --git a/app/views/messages/new.haml b/app/views/messages/new.haml index 08426eae..26400a0e 100644 --- a/app/views/messages/new.haml +++ b/app/views/messages/new.haml @@ -1,23 +1,20 @@ %h1 Neue Nachricht -- form_tag(:action => 'create') do - = error_messages_for 'message' +- form_for @message do |f| + = f.error_messages %p - %label{:for => "message_recipient"} An %fieldset - + = f.check_box :sent_to_all, :onchange => "Element.toggle('recipients')" gesamte Foodcoop - %table{:id => 'recipients', :style => (@everyone ? 'display:none;' : '')} + %table#recipients %tr %td %b BenutzerInnen: %br/ %small{:style => "color:grey"} (Mehrere Benutzerinnen mit Komma trennen) %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 var userListLoaded = false; function checkUserList() { @@ -27,23 +24,21 @@ return !userListLoaded; } = 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 %td %b Gruppe: %br/ - %select{:name => 'recipient[group_id]'} - %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)) + = f.select :group_id, groups_for_select, :prompt => " -- Gruppe auswählen --" %p - %label{:for => "message_subject"} Betreff + = f.label :subject, "Betreff" %br/ - = text_field 'message', 'subject' + = f.text_field :subject %p - %label{:for => "message_body"} Nachricht + = f.label :body, "Nachricht" %br/ - = preserve(text_area 'message', 'body', :cols => '80', :rows => '20') + ~ f.text_area :body, :cols => '80', :rows => '20' = submit_tag "Senden" \ No newline at end of file diff --git a/app/views/messages/order_finished.rhtml b/app/views/messages/order_finished.rhtml index 270d3e2a..12f67fda 100644 --- a/app/views/messages/order_finished.rhtml +++ b/app/views/messages/order_finished.rhtml @@ -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 article = result.order_article_result -%> <%= article.name %>: <%= result.quantity %> x <%= article.unit %> = <%= result.quantity * article.gross_price %> diff --git a/app/views/messages/show.haml b/app/views/messages/show.haml index 78fe6f62..322d5247 100644 --- a/app/views/messages/show.haml +++ b/app/views/messages/show.haml @@ -1,28 +1,21 @@ -%h1 Nachricht anzeigen +- title "Nachricht anzeigen" %div{:style => "width:40em"} - - if @message - %table{:style => "width:25em"} - %tr - %td Von: - %td=h @message.system_message? ? 'FoodSoft' : @message.sender.nick - %tr - %td An: - %td=h @message.recipients - %tr - %td Betreff: - %td - %b=h @message.subject - %tr - %td Gesendet: - %td= format_time(@message.created_on) - %hr/ - %p= simple_format(h(@message.body)) - %hr/ - %p - = link_to('Antworten', :action => 'reply', :id => @message) + ' | ' unless @message.system_message? - = link_to('Löschen', {:action => 'destroy', :id => @message}, :method => "post") - | - = link_to 'Nachrichteneingang', :action => 'inbox' - - else - %p Nachricht kann nicht angezeigt werden. \ No newline at end of file + %table{:style => "width:25em"} + %tr + %td Von: + %td=h @message.sender_name + %tr + %td Betreff: + %td + %b=h @message.subject + %tr + %td Gesendet: + %td= format_time(@message.created_at) + %hr/ + %p= simple_format(h(@message.body)) + %hr/ + %p + = link_to('Antworten', reply_message_path(@message)) + | + = link_to 'Nachricht im Überblick', messages_path \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb deleted file mode 100644 index 58d07515..00000000 --- a/config/environments/development.rb +++ /dev/null @@ -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" -#} - \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 0cf317b5..f06f33bc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,9 @@ ActionController::Routing::Routes.draw do |map| map.my_profile '/home/profile', :controller => 'home', :action => 'profile' 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| admin.resources :users admin.resources :workgroups, :member => { :memberships => :get } diff --git a/db/migrate/20090115123421_refactor_messaging.rb b/db/migrate/20090115123421_refactor_messaging.rb new file mode 100644 index 00000000..073fdcce --- /dev/null +++ b/db/migrate/20090115123421_refactor_messaging.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 25ba90f0..ee909c10 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # 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| t.string "name", :default => "", :null => false @@ -184,18 +184,14 @@ ActiveRecord::Schema.define(:version => 20090113111624) do create_table "messages", :force => true do |t| t.integer "sender_id" - t.integer "recipient_id", :default => 0, :null => false - t.string "recipients", :default => "", :null => false - t.string "subject", :default => "", :null => false - t.text "body", :null => false - t.boolean "read", :default => false, :null => false - t.integer "email_state", :default => 0, :null => false - t.datetime "created_on", :null => false + t.text "recipients_ids", :null => false + 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 - 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| t.integer "order_id", :default => 0, :null => false t.string "name", :default => "", :null => false diff --git a/lib/tasks/messages.rake b/lib/tasks/messages.rake new file mode 100644 index 00000000..160a1d80 --- /dev/null +++ b/lib/tasks/messages.rake @@ -0,0 +1,4 @@ +desc "Deliver messages as emails" +task :send_emails => :environment do + Message.send_emails +end diff --git a/public/stylesheets/sass/main.sass b/public/stylesheets/sass/main.sass index f6caa10f..d693a16d 100644 --- a/public/stylesheets/sass/main.sass +++ b/public/stylesheets/sass/main.sass @@ -239,7 +239,6 @@ table tfoot tr :background-color #fff td :padding-top 0.8em - tr.edit_inline :background-color = !hover_yellow diff --git a/test/fixtures/articles.yml b/test/fixtures/articles.yml index c3d1c2ca..a7b92343 100644 --- a/test/fixtures/articles.yml +++ b/test/fixtures/articles.yml @@ -1,5 +1,5 @@ # == Schema Information -# Schema version: 20090114101610 +# Schema version: 20090115123421 # # Table name: articles # diff --git a/test/fixtures/messages.yml b/test/fixtures/messages.yml index d8656bb1..14846ad0 100644 --- a/test/fixtures/messages.yml +++ b/test/fixtures/messages.yml @@ -1,17 +1,16 @@ # == 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 # # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html diff --git a/test/fixtures/suppliers.yml b/test/fixtures/suppliers.yml index 4c76c2c4..822a477c 100644 --- a/test/fixtures/suppliers.yml +++ b/test/fixtures/suppliers.yml @@ -1,5 +1,5 @@ # == Schema Information -# Schema version: 20090114101610 +# Schema version: 20090115123421 # # Table name: suppliers #