diff --git a/app/models/user.rb b/app/models/user.rb index 359bf51c..1b0e818a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,6 +3,7 @@ require 'digest/sha1' # specific user rights through memberships (see Group) class User < ActiveRecord::Base + include RailsSettings::Extend #TODO: acts_as_paraniod ?? has_many :memberships, :dependent => :destroy @@ -19,8 +20,11 @@ class User < ActiveRecord::Base has_many :pages, :foreign_key => 'updated_by' has_many :created_orders, :class_name => 'Order', :foreign_key => 'created_by_user_id', :dependent => :nullify - attr_accessor :password, :setting_attributes - + attr_accessor :password, :settings_attributes + + # makes the current_user (logged-in-user) available in models + cattr_accessor :current_user + validates_presence_of :nick, :email validates_presence_of :password, :on => :create validates_length_of :nick, :in => 2..25 @@ -32,44 +36,23 @@ class User < ActiveRecord::Base validates_length_of :password, :in => 5..25, :allow_blank => true before_validation :set_password - after_save :update_settings - - # Adds support for configuration settings (through "settings" attribute). - acts_as_configurable - - # makes the current_user (logged-in-user) available in models - cattr_accessor :current_user - - # User settings keys - # returns the User-settings and the translated description - def self.setting_keys - { - "notify.orderFinished" => I18n.t('model.user.notify.order_finished'), - "notify.negativeBalance" => I18n.t('model.user.notify.negative_balance'), - "notify.upcoming_tasks" => I18n.t('model.user.notify.upcoming_tasks'), - "messages.sendAsEmail" => I18n.t('model.user.notify.send_as_email'), - "profile.phoneIsPublic" => I18n.t('model.user.notify.phone_is_public'), - "profile.emailIsPublic" => I18n.t('model.user.notify.email_is_public'), - "profile.nameIsPublic" => I18n.t('model.user.notify.name_is_public') - } + after_initialize do + settings.defaults['profile'] = { 'language' => I18n.default_locale } unless settings.profile + settings.defaults['messages'] = { 'send_as_email' => true } unless settings.messages + settings.defaults['notify'] = { 'upcoming_tasks' => true } unless settings.notify end - # retuns the default setting for a NEW user - # for old records nil will returned - # TODO: integrate default behaviour in acts_as_configurable plugin - def settings_default(setting) - # define a default for the settings - defaults = { - "messages.sendAsEmail" => true, - "notify.upcoming_tasks" => true - } - return true if self.new_record? && defaults[setting] - end - - def update_settings - unless setting_attributes.nil? - for setting in User::setting_keys.keys - self.settings[setting] = setting_attributes[setting] && setting_attributes[setting] == '1' ? '1' : nil + + after_save do + settings_attributes.each do |key, value| + value.each do |k, v| + case v + when '1' + value[k] = true + when '0' + value[k] = false + end end + self.settings.merge!(key, value) end end @@ -78,7 +61,7 @@ class User < ActiveRecord::Base end def receive_email? - settings['messages.sendAsEmail'] == "1" && email.present? + settings['messages.send_as_mail'] == "1" && email.present? end # Sets the user's password. It will be stored encrypted along with a random salt. diff --git a/app/views/shared/_user_form_fields.html.haml b/app/views/shared/_user_form_fields.html.haml index fa11b393..21d5fe2b 100644 --- a/app/views/shared/_user_form_fields.html.haml +++ b/app/views/shared/_user_form_fields.html.haml @@ -5,11 +5,19 @@ = f.input :phone = f.input :password, :required => f.object.new_record? = f.input :password_confirmation -.control-group - .controls - - for setting in User::setting_keys.keys - %label.checkbox{:for => "user[setting_attributes][#{setting}]"} - = hidden_field_tag "user[setting_attributes][#{setting}]", '0' - = check_box_tag "user[setting_attributes][#{setting}]", '1', - f.object.settings[setting] == '1' || f.object.settings_default(setting) - = User::setting_keys[setting] + += f.simple_fields_for :settings_attributes do |s| + + = s.simple_fields_for :profile, defaults: { inline_label: true } do |profile| + = profile.input 'language', as: :select, collection: available_locales, required: false, selected: f.object.settings.profile['language'] + = profile.input 'phone_is_public', as: :boolean, label: false, input_html: { checked: f.object.settings.profile['phone_is_public'] } + = profile.input 'email_is_public', as: :boolean, label: false, input_html: { checked: f.object.settings.profile['email_is_public'] } + = profile.input 'name_is_public', as: :boolean, label: false, input_html: { checked: f.object.settings.profile['name_is_public'] } + + = s.simple_fields_for :messages, defaults: { inline_label: true, label: false } do |messages| + = messages.input 'send_as_email', as: :boolean, input_html: { checked: f.object.settings.messages['send_as_email'] } + + = s.simple_fields_for :notify, defaults: { inline_label: true, label: false } do |notify| + = notify.input 'order_finished', as: :boolean, input_html: { checked: f.object.settings.notify['order_finished'] } + = notify.input 'negative_balance', as: :boolean, input_html: { checked: f.object.settings.notify['negative_balance'] } + = notify.input 'upcoming_tasks', as: :boolean, input_html: { checked: f.object.settings.notify['upcoming_tasks'] } diff --git a/app/workers/user_notifier.rb b/app/workers/user_notifier.rb index 297ae978..754477d5 100644 --- a/app/workers/user_notifier.rb +++ b/app/workers/user_notifier.rb @@ -18,7 +18,7 @@ class UserNotifier Order.find(order_id).group_orders.each do |group_order| group_order.ordergroup.users.each do |user| begin - Mailer.order_result(user, group_order).deliver if user.settings["notify.orderFinished"] == '1' + Mailer.order_result(user, group_order).deliver if user.settings.notify["order_finished"] rescue Rails.logger.warn "Can't deliver mail to #{user.email}" end @@ -34,7 +34,7 @@ class UserNotifier Ordergroup.find(ordergroup_id).users.each do |user| begin - Mailer.negative_balance(user, transaction).deliver if user.settings["notify.negativeBalance"] == '1' + Mailer.negative_balance(user, transaction).deliver if user.settings.notify["negative_balance"] rescue Rails.logger.warn "Can't deliver mail to #{user.email}" end diff --git a/config/locales/de/de.defaults.yml b/config/locales/de/de.defaults.yml index 890ee796..ee8633a6 100644 --- a/config/locales/de/de.defaults.yml +++ b/config/locales/de/de.defaults.yml @@ -263,14 +263,6 @@ de: page: redirect: 'Weiterleiting auf [[%{title}]]...' user: - notify: - order_finished: 'Informier mich über meine Bestellergebnisse (nach Ende der Bestellung).' - negative_balance: 'Informiere mich, falls meine Bestellgruppe ins Minus rutscht.' - upcoming_tasks: 'Erinnere mich an anstehende Aufgaben.' - send_as_email: 'Bekomme Nachrichten als Emails.' - phone_is_public: 'Telefon ist für Mitglieder sichtbar' - email_is_public: 'E-Mail ist für Mitglieder sichtbar' - name_is_public: 'Name ist für Mitglieder sichtbar' no_ordergroup: 'keine Bestellgruppe' helpers: diff --git a/config/locales/de/de.simple_form.yml b/config/locales/de/de.simple_form.yml index 5aa5279a..db4a7610 100644 --- a/config/locales/de/de.simple_form.yml +++ b/config/locales/de/de.simple_form.yml @@ -8,6 +8,12 @@ de: mark: '*' error_notification: default_message: "Fehler wurden gefunden. Bitte das Formular überprüfen." + options: + settings: + profile: + language: + de: Deutsch + en: English labels: defaults: password: 'Passwort' @@ -30,6 +36,18 @@ de: nick: "Benutzerinnenname" first_name: "Vorname" last_name: "Nachname" + settings: + profile: + language: Sprache + phone_is_public: 'Telefon ist für Mitglieder sichtbar' + email_is_public: 'E-Mail ist für Mitglieder sichtbar' + name_is_public: 'Name ist für Mitglieder sichtbar' + notify: + order_finished: 'Informier mich über meine Bestellergebnisse (nach Ende der Bestellung).' + negative_balance: 'Informiere mich, falls meine Bestellgruppe ins Minus rutscht.' + upcoming_tasks: 'Erinnere mich an anstehende Aufgaben.' + messages: + send_as_email: 'Bekomme Nachrichten als Emails.' workgroup: weekly_task: 'Monatlichen Job definieren?' weekday: 'Wochentag' diff --git a/config/locales/en/en.defaults.yml b/config/locales/en/en.defaults.yml index ca4b436c..03a1f0e0 100644 --- a/config/locales/en/en.defaults.yml +++ b/config/locales/en/en.defaults.yml @@ -263,14 +263,6 @@ en: page: redirect: 'Redirect to [[%{title}]]...' user: - notify: - order_finished: 'Inform me about my order result (when the order is closed).' - negative_balance: 'inform me when by order group has a negative balance.' - upcoming_tasks: 'Remind me of upcoming tasks.' - send_as_email: 'Receive messages as emails.' - phone_is_public: 'Phone number is visible for other members.' - email_is_public: 'Email is visible for other members.' - name_is_public: 'Name is visible for other members.' no_ordergroup: 'no order group' helpers: diff --git a/config/locales/en/en.simple_form.yml b/config/locales/en/en.simple_form.yml index 31cc4b6c..305dde1e 100644 --- a/config/locales/en/en.simple_form.yml +++ b/config/locales/en/en.simple_form.yml @@ -8,6 +8,12 @@ en: mark: '*' error_notification: default_message: 'Errors were found. Please check the form.' + options: + settings: + profile: + language: + de: German + en: English labels: defaults: password: 'Password' @@ -30,6 +36,18 @@ en: nick: 'Username' first_name: 'First name' last_name: 'Last name' + settings: + profile: + language: Language + phone_is_public: 'Phone number is visible for other members.' + email_is_public: 'Email is visible for other members.' + name_is_public: 'Name is visible for other members.' + notify: + order_finished: 'Inform me about my order result (when the order is closed).' + negative_balance: 'inform me when by order group has a negative balance.' + upcoming_tasks: 'Remind me of upcoming tasks.' + messages: + send_as_email: 'Receive messages as emails.' workgroup: weekly_task: 'Define monthly task?' weekday: 'Weekday' diff --git a/db/migrate/20130605112109_create_settings.rb b/db/migrate/20130605112109_create_settings.rb new file mode 100644 index 00000000..90a0f527 --- /dev/null +++ b/db/migrate/20130605112109_create_settings.rb @@ -0,0 +1,17 @@ +class CreateSettings < ActiveRecord::Migration + def self.up + create_table :settings do |t| + t.string :var, null: false + t.text :value, null: true + t.integer :thing_id, null: true + t.string :thing_type, limit: 30, null: true + t.timestamps + end + + add_index :settings, [ :thing_type, :thing_id, :var ], unique: true + end + + def self.down + drop_table :settings + end +end diff --git a/db/migrate/20130605235825_migrate_user_settings.rb b/db/migrate/20130605235825_migrate_user_settings.rb new file mode 100644 index 00000000..a9722f1b --- /dev/null +++ b/db/migrate/20130605235825_migrate_user_settings.rb @@ -0,0 +1,34 @@ +class MigrateUserSettings < ActiveRecord::Migration + def up + old_settings = ConfigurableSetting.all + + old_settings.each do |old_setting| + # get target (user) + type = old_setting.configurable_type + id = old_setting.configurable_id + user = type.constantize.find(id) + + # get the data (settings) + name = old_setting.name + namespace = name.split('.')[0] + key = name.split('.')[1].underscore # Camelcase to underscore + + # prepare value + value = YAML.load(old_setting.value) + value = value.nil? ? false : value + + # set the settings_attributes (thanks to settings.merge! we can set them one by one) + user.settings_attributes = { + "#{namespace}" => { + "#{key}" => value + } + } + + # save the user to apply after_save callback + user.save + end + end + + def down + end +end diff --git a/db/schema.rb b/db/schema.rb index 188ea83b..477ebbf5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20121230142516) do +ActiveRecord::Schema.define(:version => 20130605235825) do create_table "article_categories", :force => true do |t| t.string "name", :default => "", :null => false @@ -268,6 +268,17 @@ ActiveRecord::Schema.define(:version => 20121230142516) do add_index "pages", ["permalink"], :name => "index_pages_on_permalink" add_index "pages", ["title"], :name => "index_pages_on_title" + create_table "settings", :force => true do |t| + t.string "var", :null => false + t.text "value" + t.integer "thing_id" + t.string "thing_type", :limit => 30 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "settings", ["thing_type", "thing_id", "var"], :name => "index_settings_on_thing_type_and_thing_id_and_var", :unique => true + create_table "stock_changes", :force => true do |t| t.integer "delivery_id" t.integer "order_id" diff --git a/lib/tasks/foodsoft.rake b/lib/tasks/foodsoft.rake index fd96cf9c..5fa4cc2a 100644 --- a/lib/tasks/foodsoft.rake +++ b/lib/tasks/foodsoft.rake @@ -8,7 +8,7 @@ namespace :foodsoft do puts "Send notifications for #{task.name} to .." for user in task.users begin - Mailer.upcoming_tasks(user, task).deliver if user.settings['notify.upcoming_tasks'] == 1 + Mailer.upcoming_tasks(user, task).deliver if user.settings.notify['upcoming_tasks'] == 1 rescue puts "deliver aborted for #{user.email}.." end @@ -38,7 +38,7 @@ namespace :foodsoft do unless task.enough_users_assigned? puts "Notify workgroup: #{workgroup.name} for task #{task.name}" for user in workgroup.users - if user.settings['messages.sendAsEmail'] == "1" && !user.email.blank? + if user.settings.messages['send_as_email'] == "1" && !user.email.blank? begin Mailer.not_enough_users_assigned(task, user).deliver rescue