Merge remote-tracking branch 'foodcoops/master' into feature-link_to_group_order
Conflicts: app/views/shared/_open_orders.html.haml
This commit is contained in:
commit
1f08ee4759
58 changed files with 462 additions and 188 deletions
51
Gemfile.lock
51
Gemfile.lock
|
@ -60,17 +60,18 @@ GEM
|
||||||
acts_as_tree (1.4.0)
|
acts_as_tree (1.4.0)
|
||||||
activerecord (>= 3.0.0)
|
activerecord (>= 3.0.0)
|
||||||
afm (0.2.0)
|
afm (0.2.0)
|
||||||
arel (3.0.2)
|
arel (3.0.3)
|
||||||
better_errors (1.0.1)
|
better_errors (1.0.1)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubis (>= 2.6.6)
|
erubis (>= 2.6.6)
|
||||||
binding_of_caller (0.7.2)
|
binding_of_caller (0.7.2)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
bootstrap-datepicker-rails (1.1.1.8)
|
bootstrap-datepicker-rails (1.1.1.9)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
builder (3.0.4)
|
builder (3.0.4)
|
||||||
bullet (4.6.0)
|
bullet (4.7.1)
|
||||||
uniform_notifier
|
activesupport
|
||||||
|
uniform_notifier (>= 1.4.0)
|
||||||
capistrano (2.13.5)
|
capistrano (2.13.5)
|
||||||
highline
|
highline
|
||||||
net-scp (>= 1.0.0)
|
net-scp (>= 1.0.0)
|
||||||
|
@ -104,7 +105,8 @@ GEM
|
||||||
daemons (1.1.9)
|
daemons (1.1.9)
|
||||||
database_cleaner (1.2.0)
|
database_cleaner (1.2.0)
|
||||||
debug_inspector (0.0.2)
|
debug_inspector (0.0.2)
|
||||||
diff-lcs (1.2.4)
|
diff-lcs (1.2.5)
|
||||||
|
docile (1.1.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (1.0.3)
|
eventmachine (1.0.3)
|
||||||
exception_notification (4.0.1)
|
exception_notification (4.0.1)
|
||||||
|
@ -112,15 +114,15 @@ GEM
|
||||||
activesupport (>= 3.0.4)
|
activesupport (>= 3.0.4)
|
||||||
execjs (2.0.2)
|
execjs (2.0.2)
|
||||||
expression_parser (0.9.0)
|
expression_parser (0.9.0)
|
||||||
factory_girl (4.2.0)
|
factory_girl (4.3.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
factory_girl_rails (4.2.1)
|
factory_girl_rails (4.3.0)
|
||||||
factory_girl (~> 4.2.0)
|
factory_girl (~> 4.3.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
faker (1.2.0)
|
faker (1.2.0)
|
||||||
i18n (~> 0.5)
|
i18n (~> 0.5)
|
||||||
ffi (1.9.0)
|
ffi (1.9.3)
|
||||||
haml (4.0.3)
|
haml (4.0.4)
|
||||||
tilt
|
tilt
|
||||||
haml-rails (0.4)
|
haml-rails (0.4)
|
||||||
actionpack (>= 3.1, < 4.1)
|
actionpack (>= 3.1, < 4.1)
|
||||||
|
@ -155,6 +157,7 @@ GEM
|
||||||
actionpack (>= 3.1)
|
actionpack (>= 3.1)
|
||||||
less (~> 2.4.0)
|
less (~> 2.4.0)
|
||||||
libv8 (3.16.14.3)
|
libv8 (3.16.14.3)
|
||||||
|
lockfile (2.1.0)
|
||||||
mail (2.5.4)
|
mail (2.5.4)
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
|
@ -176,7 +179,7 @@ GEM
|
||||||
mini_portile (0.5.2)
|
mini_portile (0.5.2)
|
||||||
mono_logger (1.1.0)
|
mono_logger (1.1.0)
|
||||||
multi_json (1.8.2)
|
multi_json (1.8.2)
|
||||||
mysql2 (0.3.13)
|
mysql2 (0.3.14)
|
||||||
net-scp (1.1.2)
|
net-scp (1.1.2)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-sftp (2.1.2)
|
net-sftp (2.1.2)
|
||||||
|
@ -234,9 +237,9 @@ GEM
|
||||||
rake (10.1.0)
|
rake (10.1.0)
|
||||||
rdoc (3.12.2)
|
rdoc (3.12.2)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
redis (3.0.5)
|
redis (3.0.6)
|
||||||
redis-namespace (1.3.1)
|
redis-namespace (1.3.2)
|
||||||
redis (~> 3.0.0)
|
redis (~> 3.0.4)
|
||||||
ref (1.0.5)
|
ref (1.0.5)
|
||||||
responders (1.0.0)
|
responders (1.0.0)
|
||||||
railties (>= 3.2, < 5)
|
railties (>= 3.2, < 5)
|
||||||
|
@ -246,8 +249,8 @@ GEM
|
||||||
redis-namespace (~> 1.2)
|
redis-namespace (~> 1.2)
|
||||||
sinatra (>= 0.9.2)
|
sinatra (>= 0.9.2)
|
||||||
vegas (~> 0.1.2)
|
vegas (~> 0.1.2)
|
||||||
rspec-core (2.14.6)
|
rspec-core (2.14.7)
|
||||||
rspec-expectations (2.14.3)
|
rspec-expectations (2.14.4)
|
||||||
diff-lcs (>= 1.1.3, < 2.0)
|
diff-lcs (>= 1.1.3, < 2.0)
|
||||||
rspec-mocks (2.14.4)
|
rspec-mocks (2.14.4)
|
||||||
rspec-rails (2.14.0)
|
rspec-rails (2.14.0)
|
||||||
|
@ -265,7 +268,7 @@ GEM
|
||||||
railties (~> 3.2.0)
|
railties (~> 3.2.0)
|
||||||
sass (>= 3.1.10)
|
sass (>= 3.1.10)
|
||||||
tilt (~> 1.3)
|
tilt (~> 1.3)
|
||||||
select2-rails (3.5.0)
|
select2-rails (3.5.1)
|
||||||
thor (~> 0.14)
|
thor (~> 0.14)
|
||||||
selenium-webdriver (2.37.0)
|
selenium-webdriver (2.37.0)
|
||||||
childprocess (>= 0.2.5)
|
childprocess (>= 0.2.5)
|
||||||
|
@ -280,10 +283,12 @@ GEM
|
||||||
simple_form (2.1.0)
|
simple_form (2.1.0)
|
||||||
actionpack (~> 3.0)
|
actionpack (~> 3.0)
|
||||||
activemodel (~> 3.0)
|
activemodel (~> 3.0)
|
||||||
simplecov (0.7.1)
|
simplecov (0.8.1)
|
||||||
multi_json (~> 1.0)
|
docile (~> 1.1.0)
|
||||||
simplecov-html (~> 0.7.1)
|
lockfile (>= 2.1.0)
|
||||||
simplecov-html (0.7.1)
|
multi_json
|
||||||
|
simplecov-html (~> 0.8.0)
|
||||||
|
simplecov-html (0.8.0)
|
||||||
sinatra (1.4.4)
|
sinatra (1.4.4)
|
||||||
rack (~> 1.4)
|
rack (~> 1.4)
|
||||||
rack-protection (~> 1.4)
|
rack-protection (~> 1.4)
|
||||||
|
@ -316,10 +321,10 @@ GEM
|
||||||
rails (>= 3.1)
|
rails (>= 3.1)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
tzinfo (0.3.38)
|
tzinfo (0.3.38)
|
||||||
uglifier (2.3.0)
|
uglifier (2.3.1)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
json (>= 1.8.0)
|
json (>= 1.8.0)
|
||||||
uniform_notifier (1.3.0)
|
uniform_notifier (1.4.0)
|
||||||
vegas (0.1.11)
|
vegas (0.1.11)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
websocket (1.0.7)
|
websocket (1.0.7)
|
||||||
|
|
|
@ -2,13 +2,10 @@ class Admin::UsersController < Admin::BaseController
|
||||||
inherit_resources
|
inherit_resources
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@users = User.order('nick ASC')
|
@users = User.natural_order
|
||||||
|
|
||||||
# if somebody uses the search field:
|
# if somebody uses the search field:
|
||||||
unless params[:user_name].blank?
|
@users = @users.natural_search(params[:user_name]) unless params[:user_name].blank?
|
||||||
@users = @users.where("first_name LIKE :user_name OR last_name LIKE :user_name OR nick LIKE :user_name",
|
|
||||||
user_name: "%#{params[:user_name]}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
@users = @users.page(params[:page]).per(@per_page)
|
@users = @users.page(params[:page]).per(@per_page)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
class Foodcoop::UsersController < ApplicationController
|
class Foodcoop::UsersController < ApplicationController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@users = User.order('nick ASC')
|
@users = User.natural_order
|
||||||
|
|
||||||
# if somebody uses the search field:
|
# if somebody uses the search field:
|
||||||
unless params[:user_name].blank?
|
@users = @users.natural_search(params[:user_name]) unless params[:user_name].blank?
|
||||||
@users = @users.where("first_name LIKE :user_name OR last_name LIKE :user_name OR nick LIKE :user_name",
|
|
||||||
user_name: "%#{params[:user_name]}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:ordergroup_name]
|
if params[:ordergroup_name]
|
||||||
@users = @users.joins(:groups).where("groups.type = 'Ordergroup' AND groups.name LIKE ?", "%#{params[:ordergroup_name]}%")
|
@users = @users.joins(:groups).where("groups.type = 'Ordergroup' AND groups.name LIKE ?", "%#{params[:ordergroup_name]}%")
|
||||||
end
|
end
|
||||||
|
|
||||||
@users = @users.page(params[:page]).per(@per_page).order('users.nick ASC')
|
@users = @users.page(params[:page]).per(@per_page)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html # index.html.haml
|
format.html # index.html.haml
|
||||||
|
|
|
@ -2,9 +2,9 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
# Currently used to display users nick and ids for autocomplete
|
# Currently used to display users nick and ids for autocomplete
|
||||||
def index
|
def index
|
||||||
@users = User.where("nick LIKE ?", "%#{params[:q]}%")
|
@users = User.natural_search(params[:q])
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json { render :json => @users.map { |u| u.token_attributes } }
|
format.json { render :json => @users.map(&:token_attributes) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -155,13 +155,6 @@ module ApplicationHelper
|
||||||
:target => "_blank"
|
:target => "_blank"
|
||||||
end
|
end
|
||||||
|
|
||||||
# offers a link for writing message to user
|
|
||||||
# checks for nil (useful for relations)
|
|
||||||
def link_to_user_message_if_valid(user)
|
|
||||||
user.nil? ? '??' : link_to(user.nick, new_message_path('message[mail_to]' => user.id),
|
|
||||||
:title => I18n.t('helpers.application.write_message'))
|
|
||||||
end
|
|
||||||
|
|
||||||
def bootstrap_flash
|
def bootstrap_flash
|
||||||
flash_messages = []
|
flash_messages = []
|
||||||
flash.each do |type, message|
|
flash.each do |type, message|
|
||||||
|
@ -183,4 +176,32 @@ module ApplicationHelper
|
||||||
render :partial => 'shared/base_errors', :locals => {:error_messages => messages}
|
render :partial => 'shared/base_errors', :locals => {:error_messages => messages}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# show a user, depending on settings
|
||||||
|
def show_user(user=@current_user, options = {})
|
||||||
|
if user.nil?
|
||||||
|
"?"
|
||||||
|
elsif FoodsoftConfig[:use_nick]
|
||||||
|
if options[:full] and options[:markup]
|
||||||
|
raw "<b>#{h user.nick}</b> (#{h user.first_name} #{h user.last_name})"
|
||||||
|
elsif options[:full]
|
||||||
|
"#{user.nick} (#{user.first_name} #{user.last_name})"
|
||||||
|
else
|
||||||
|
# when use_nick was changed from false to true, users may exist without nick
|
||||||
|
user.nick.nil? ? I18n.t('helpers.application.nick_fallback') : user.nick
|
||||||
|
end
|
||||||
|
else
|
||||||
|
"#{user.first_name} #{user.last_name}" + (options[:unique] ? " (\##{user.id})" : '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# render user presentation linking to default action (write message)
|
||||||
|
def show_user_link(user=@current_user)
|
||||||
|
if user.nil?
|
||||||
|
show_user user
|
||||||
|
else
|
||||||
|
link_to show_user(user), new_message_path('message[mail_to]' => user.id),
|
||||||
|
:title => I18n.t('helpers.application.write_message')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ module TasksHelper
|
||||||
|
|
||||||
def task_assignments(task)
|
def task_assignments(task)
|
||||||
task.assignments.map do |ass|
|
task.assignments.map do |ass|
|
||||||
content_tag :span, ass.user.nick, :class => (ass.accepted? ? 'accepted' : 'unaccepted')
|
content_tag :span, show_user(ass.user), :class => (ass.accepted? ? 'accepted' : 'unaccepted')
|
||||||
end.join(", ").html_safe
|
end.join(", ").html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
# ActionMailer class that handles all emails for the FoodSoft.
|
# ActionMailer class that handles all emails for the FoodSoft.
|
||||||
class Mailer < ActionMailer::Base
|
class Mailer < ActionMailer::Base
|
||||||
|
# XXX Quick fix to allow the use of show_user. Proper take would be one of
|
||||||
|
# (1) Use draper, decorate user
|
||||||
|
# (2) Create a helper with this method, include here and in ApplicationHelper
|
||||||
|
helper :application
|
||||||
|
include ApplicationHelper
|
||||||
|
|
||||||
layout 'email' # Use views/layouts/email.txt.erb
|
layout 'email' # Use views/layouts/email.txt.erb
|
||||||
|
|
||||||
|
@ -15,7 +20,7 @@ class Mailer < ActionMailer::Base
|
||||||
|
|
||||||
mail subject: "[#{FoodsoftConfig[:name]}] " + message.subject,
|
mail subject: "[#{FoodsoftConfig[:name]}] " + message.subject,
|
||||||
to: recipient.email,
|
to: recipient.email,
|
||||||
from: "#{message.sender.nick} <#{message.sender.email}>"
|
from: "#{show_user(message.sender)} <#{message.sender.email}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends an email with instructions on how to reset the password.
|
# Sends an email with instructions on how to reset the password.
|
||||||
|
@ -26,7 +31,7 @@ class Mailer < ActionMailer::Base
|
||||||
@link = new_password_url(id: @user.id, token: @user.reset_password_token)
|
@link = new_password_url(id: @user.id, token: @user.reset_password_token)
|
||||||
|
|
||||||
mail :to => @user.email,
|
mail :to => @user.email,
|
||||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.reset_password.subject', :username => @user.nick)
|
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.reset_password.subject', :username => show_user(@user))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends an invite email.
|
# Sends an invite email.
|
||||||
|
@ -75,7 +80,7 @@ class Mailer < ActionMailer::Base
|
||||||
@feedback = feedback
|
@feedback = feedback
|
||||||
|
|
||||||
mail :to => FoodsoftConfig[:notification]["error_recipients"],
|
mail :to => FoodsoftConfig[:notification]["error_recipients"],
|
||||||
:from => "#{user.nick} <#{user.email}>",
|
:from => "#{show_user user} <#{user.email}>",
|
||||||
:sender => FoodsoftConfig[:notification]["sender_address"],
|
:sender => FoodsoftConfig[:notification]["sender_address"],
|
||||||
:errors_to => FoodsoftConfig[:notification]["sender_address"],
|
:errors_to => FoodsoftConfig[:notification]["sender_address"],
|
||||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.feedback.subject', :email => user.email)
|
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.feedback.subject', :email => user.email)
|
||||||
|
|
|
@ -106,7 +106,7 @@ class Article < ActiveRecord::Base
|
||||||
|
|
||||||
# to get the correspondent shared article
|
# to get the correspondent shared article
|
||||||
def shared_article
|
def shared_article
|
||||||
@shared_article ||= self.supplier.shared_supplier.shared_articles.find_by_number(self.order_number)
|
@shared_article ||= self.supplier.shared_supplier.shared_articles.find_by_number(self.order_number) rescue nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# convert units in foodcoop-size
|
# convert units in foodcoop-size
|
||||||
|
|
|
@ -17,7 +17,7 @@ class Group < ActiveRecord::Base
|
||||||
|
|
||||||
# Returns all NONmembers and a checks for possible multiple Ordergroup-Memberships
|
# Returns all NONmembers and a checks for possible multiple Ordergroup-Memberships
|
||||||
def non_members
|
def non_members
|
||||||
User.all(:order => 'nick').reject { |u| users.include?(u) }
|
User.natural_order.all.reject { |u| users.include?(u) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_tokens=(ids)
|
def user_tokens=(ids)
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Message < ActiveRecord::Base
|
||||||
@reply_to = Message.find(message_id)
|
@reply_to = Message.find(message_id)
|
||||||
add_recipients([@reply_to.sender])
|
add_recipients([@reply_to.sender])
|
||||||
self.subject = I18n.t('messages.model.reply_subject', :subject => @reply_to.subject)
|
self.subject = I18n.t('messages.model.reply_subject', :subject => @reply_to.subject)
|
||||||
self.body = I18n.t('messages.model.reply_header', :user => @reply_to.sender.nick, :when => I18n.l(@reply_to.created_at, :format => :short)) + "\n"
|
self.body = I18n.t('messages.model.reply_header', :user => @reply_to.sender.display, :when => I18n.l(@reply_to.created_at, :format => :short)) + "\n"
|
||||||
@reply_to.body.each_line{ |l| self.body += I18n.t('messages.model.reply_indent', :line => l) }
|
@reply_to.body.each_line{ |l| self.body += I18n.t('messages.model.reply_indent', :line => l) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ class Message < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def sender_name
|
def sender_name
|
||||||
system_message? ? I18n.t('layouts.foodsoft') : sender.nick rescue "??"
|
system_message? ? I18n.t('layouts.foodsoft') : sender.display rescue "?"
|
||||||
end
|
end
|
||||||
|
|
||||||
def recipients
|
def recipients
|
||||||
|
@ -77,7 +77,7 @@ class Message < ActiveRecord::Base
|
||||||
begin
|
begin
|
||||||
Mailer.foodsoft_message(self, user).deliver
|
Mailer.foodsoft_message(self, user).deliver
|
||||||
rescue
|
rescue
|
||||||
Rails.logger.warn "Deliver failed for #{user.nick}: #{user.email}"
|
Rails.logger.warn "Deliver failed for user \##{user.id}: #{user.email}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Ordergroup < Group
|
||||||
"#{contact_phone} (#{contact_person})"
|
"#{contact_phone} (#{contact_person})"
|
||||||
end
|
end
|
||||||
def non_members
|
def non_members
|
||||||
User.all(:order => 'nick').reject { |u| (users.include?(u) || u.ordergroup) }
|
User.natural_order.all.reject { |u| (users.include?(u) || u.ordergroup) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def value_of_open_orders(exclude = nil)
|
def value_of_open_orders(exclude = nil)
|
||||||
|
@ -102,7 +102,7 @@ class Ordergroup < Group
|
||||||
# Make sure, that a user can only be in one ordergroup
|
# Make sure, that a user can only be in one ordergroup
|
||||||
def uniqueness_of_members
|
def uniqueness_of_members
|
||||||
users.each do |user|
|
users.each do |user|
|
||||||
errors.add :user_tokens, I18n.t('ordergroups.model.error_single_group', :user => user.nick) if user.groups.where(:type => 'Ordergroup').size > 1
|
errors.add :user_tokens, I18n.t('ordergroups.model.error_single_group', :user => user.display) if user.groups.where(:type => 'Ordergroup').size > 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,19 @@ class User < ActiveRecord::Base
|
||||||
# makes the current_user (logged-in-user) available in models
|
# makes the current_user (logged-in-user) available in models
|
||||||
cattr_accessor :current_user
|
cattr_accessor :current_user
|
||||||
|
|
||||||
validates_presence_of :nick, :email
|
validates_presence_of :email
|
||||||
validates_presence_of :password, :on => :create
|
validates_presence_of :password, :on => :create
|
||||||
validates_length_of :nick, :in => 2..25
|
|
||||||
validates_uniqueness_of :nick, :case_sensitive => false
|
|
||||||
validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
||||||
validates_uniqueness_of :email, :case_sensitive => false
|
validates_uniqueness_of :email, :case_sensitive => false
|
||||||
validates_length_of :first_name, :in => 2..50
|
validates_length_of :first_name, :in => 2..50
|
||||||
validates_confirmation_of :password
|
validates_confirmation_of :password
|
||||||
validates_length_of :password, :in => 5..25, :allow_blank => true
|
validates_length_of :password, :in => 5..25, :allow_blank => true
|
||||||
|
# allow nick to be nil depending on foodcoop config
|
||||||
|
# TODO Rails 4 may have a more beautiful way
|
||||||
|
# http://stackoverflow.com/questions/19845910/conditional-allow-nil-part-of-validation
|
||||||
|
validates_length_of :nick, :in => 2..25, :allow_nil => true, :unless => Proc.new { FoodsoftConfig[:use_nick] }
|
||||||
|
validates_length_of :nick, :in => 2..25, :allow_nil => false, :if => Proc.new { FoodsoftConfig[:use_nick] }
|
||||||
|
validates_uniqueness_of :nick, :case_sensitive => false, :allow_nil => true # allow_nil in length validation
|
||||||
|
|
||||||
before_validation :set_password
|
before_validation :set_password
|
||||||
after_initialize do
|
after_initialize do
|
||||||
|
@ -55,6 +59,22 @@ class User < ActiveRecord::Base
|
||||||
self.settings.merge!(key, value)
|
self.settings.merge!(key, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# sorted by display name
|
||||||
|
def self.natural_order
|
||||||
|
# would be sensible to match ApplicationController#show_user
|
||||||
|
if FoodsoftConfig[:use_nick]
|
||||||
|
order('nick ASC')
|
||||||
|
else
|
||||||
|
order('first_name ASC, last_name ASC')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# search by (nick)name
|
||||||
|
def self.natural_search(q)
|
||||||
|
# we always use both nick and name, to make sure a user is found
|
||||||
|
where("CONCAT(first_name, CONCAT(' ', last_name)) LIKE :q OR nick LIKE :q", q: "%#{q}%")
|
||||||
|
end
|
||||||
|
|
||||||
def locale
|
def locale
|
||||||
settings.profile['language']
|
settings.profile['language']
|
||||||
|
@ -132,8 +152,8 @@ class User < ActiveRecord::Base
|
||||||
self.groups.find(:all, :conditions => {:type => ""})
|
self.groups.find(:all, :conditions => {:type => ""})
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.authenticate(nick, password)
|
def self.authenticate(login, password)
|
||||||
user = find_by_nick(nick)
|
user = (find_by_nick(login) or find_by_email(login))
|
||||||
if user && user.has_password(password)
|
if user && user.has_password(password)
|
||||||
user
|
user
|
||||||
else
|
else
|
||||||
|
@ -141,8 +161,21 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# XXX this is view-related; need to move out things like token_attributes
|
||||||
|
# then this can be removed
|
||||||
|
def display
|
||||||
|
# would be sensible to match ApplicationHelper#show_user
|
||||||
|
if FoodsoftConfig[:use_nick]
|
||||||
|
nick.nil? ? I18n.t('helpers.application.nick_fallback') : nick
|
||||||
|
else
|
||||||
|
name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def token_attributes
|
def token_attributes
|
||||||
{:id => id, :name => "#{nick} (#{ordergroup.try(:name)})"}
|
# would be sensible to match ApplicationController#show_user
|
||||||
|
# this should not be part of the model anyway
|
||||||
|
{:id => id, :name => "#{display} (#{ordergroup.try(:name)})"}
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,13 +9,15 @@
|
||||||
%table.table.table-striped
|
%table.table.table-striped
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th= t '.username'
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
%th= t '.username'
|
||||||
%th= t '.name'
|
%th= t '.name'
|
||||||
%th= t '.created_at'
|
%th= t '.created_at'
|
||||||
- for user in @users
|
- for user in @users
|
||||||
%tr{:class => cycle('even','odd', :name => 'users')}
|
%tr{:class => cycle('even','odd', :name => 'users')}
|
||||||
%td= link_to user.nick, [:admin, user]
|
%td= link_to show_user(user), [:admin, user]
|
||||||
%td=h user.name
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
%td= link_to user.name
|
||||||
%td= format_date(user.created_on)
|
%td= format_date(user.created_on)
|
||||||
= link_to t('.all_users'), admin_users_path
|
= link_to t('.all_users'), admin_users_path
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
%table.table.table-striped
|
%table.table.table-striped
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th= t '.login'
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
%th= t '.login'
|
||||||
%th= t '.name'
|
%th= t '.name'
|
||||||
%th= t '.email'
|
%th= t '.email'
|
||||||
%th= t 'admin.access_to'
|
%th= t 'admin.access_to'
|
||||||
|
@ -13,8 +14,9 @@
|
||||||
%tbody
|
%tbody
|
||||||
- for user in @users
|
- for user in @users
|
||||||
%tr
|
%tr
|
||||||
%td= link_to user.nick, [:admin, user]
|
%td= link_to show_user(user), [:admin, user]
|
||||||
%td= user.name
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
%td= user.name
|
||||||
%td= user.email
|
%td= user.email
|
||||||
%td= format_roles(user)
|
%td= format_roles(user)
|
||||||
%td= format_time(user.last_login)
|
%td= format_time(user.last_login)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- title @user.nick
|
- title show_user(@user)
|
||||||
|
|
||||||
.row-fluid
|
.row-fluid
|
||||||
.span3
|
.span3
|
||||||
|
@ -6,8 +6,9 @@
|
||||||
%h4= t '.person'
|
%h4= t '.person'
|
||||||
%p= t '.member_since', time: distance_of_time_in_words(Time.now, @user.created_on)
|
%p= t '.member_since', time: distance_of_time_in_words(Time.now, @user.created_on)
|
||||||
%dl
|
%dl
|
||||||
%dt= t '.nick'
|
- if FoodsoftConfig[:use_nick]
|
||||||
%dd= @user.nick
|
%dt= t '.nick'
|
||||||
|
%dd= @user.nick
|
||||||
%dt= t '.name'
|
%dt= t '.name'
|
||||||
%dd= h @user.name
|
%dd= h @user.name
|
||||||
%dt= t '.email'
|
%dt= t '.email'
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
%td= link_to truncate(order.name), new_finance_order_path(order_id: order.id)
|
%td= link_to truncate(order.name), new_finance_order_path(order_id: order.id)
|
||||||
%td=h format_time(order.ends) unless order.ends.nil?
|
%td=h format_time(order.ends) unless order.ends.nil?
|
||||||
%td= order.closed? ? t('.cleared', amount: number_to_currency(order.foodcoop_result)) : t('.ended')
|
%td= order.closed? ? t('.cleared', amount: number_to_currency(order.foodcoop_result)) : t('.ended')
|
||||||
%td= order.updated_by.nil? ? '??' : order.updated_by.nick
|
%td= show_user(order.updated_by)
|
||||||
%td
|
%td
|
||||||
- unless order.closed?
|
- unless order.closed?
|
||||||
= link_to t('.clear'), new_finance_order_path(order_id: order.id), class: 'btn btn-mini btn-primary'
|
= link_to t('.clear'), new_finance_order_path(order_id: order.id), class: 'btn btn-mini btn-primary'
|
||||||
|
|
|
@ -12,6 +12,6 @@
|
||||||
- @financial_transactions.each do |t|
|
- @financial_transactions.each do |t|
|
||||||
%tr
|
%tr
|
||||||
%td= format_time(t.created_on)
|
%td= format_time(t.created_on)
|
||||||
%td= h t.user.nil? ? '??' : t.user.nick
|
%td= h show_user(t.user)
|
||||||
%td= h t.note
|
%td= h t.note
|
||||||
%td.currency{:style => "color:#{t.amount < 0 ? 'red' : 'black'}; width:5em"}= number_to_currency(t.amount)
|
%td.currency{:style => "color:#{t.amount < 0 ? 'red' : 'black'}; width:5em"}= number_to_currency(t.amount)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
- for ordergroup in @ordergroups
|
- for ordergroup in @ordergroups
|
||||||
%tr
|
%tr
|
||||||
%td= ordergroup.name
|
%td= ordergroup.name
|
||||||
%td=h ordergroup.users.collect { |u| u.nick }.join(", ")
|
%td=h ordergroup.users.collect { |u| show_user(u) }.join(", ")
|
||||||
%td= format_date ordergroup.orders.order('orders.starts DESC').first.try(:starts)
|
%td= format_date ordergroup.orders.order('orders.starts DESC').first.try(:starts)
|
||||||
%td= link_to_new_message(message_params: {group_id: ordergroup.id})
|
%td= link_to_new_message(message_params: {group_id: ordergroup.id})
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
%table.table.table-striped
|
%table.table.table-striped
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th= heading_helper User, :nick
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
%th= heading_helper User, :nick
|
||||||
%th= heading_helper User, :name
|
%th= heading_helper User, :name
|
||||||
%th= heading_helper User, :email
|
%th= heading_helper User, :email
|
||||||
%th= heading_helper User, :phone
|
%th= heading_helper User, :phone
|
||||||
|
@ -13,8 +14,9 @@
|
||||||
%tbody
|
%tbody
|
||||||
- for user in @users
|
- for user in @users
|
||||||
%tr
|
%tr
|
||||||
%td= user.nick
|
- if FoodsoftConfig[:use_nick]
|
||||||
%td= user.name if @current_user.role_admin? || user.settings.profile["name_is_public"]
|
%td= show_user user
|
||||||
|
%td= user.name if @current_user.role_admin? || user.settings.profile["name_is_public"] || !FoodsoftConfig[:use_nick]
|
||||||
%td= user.email if @current_user.role_admin? || user.settings.profile["email_is_public"]
|
%td= user.email if @current_user.role_admin? || user.settings.profile["email_is_public"]
|
||||||
%td= user.phone if @current_user.role_admin? || user.settings.profile["phone_is_public"]
|
%td= user.phone if @current_user.role_admin? || user.settings.profile["phone_is_public"]
|
||||||
%td= user.ordergroup_name
|
%td= user.ordergroup_name
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
%dt= t '.note'
|
%dt= t '.note'
|
||||||
%dd= @order.note
|
%dd= @order.note
|
||||||
%dt= t '.created_by'
|
%dt= t '.created_by'
|
||||||
%dd= link_to_user_message_if_valid(@order.created_by)
|
%dd= show_user_link(@order.created_by)
|
||||||
%dt= t '.ending'
|
%dt= t '.ending'
|
||||||
%dd= format_time(@order.ends)
|
%dd= format_time(@order.ends)
|
||||||
- unless @order.stockit? or @order.supplier.min_order_quantity.blank?
|
- unless @order.stockit? or @order.supplier.min_order_quantity.blank?
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
%dd= number_to_currency @order.sum
|
%dd= number_to_currency @order.sum
|
||||||
%dt= t '.last_update'
|
%dt= t '.last_update'
|
||||||
%dd
|
%dd
|
||||||
= @group_order.updated_by.nick if @group_order.updated_by
|
= show_user(@group_order.updated_by) if @group_order.updated_by
|
||||||
(#{format_time(@group_order.updated_on)})
|
(#{format_time(@group_order.updated_on)})
|
||||||
%dt= t '.funds'
|
%dt= t '.funds'
|
||||||
%dd= number_to_currency(@ordering_data[:available_funds])
|
%dd= number_to_currency(@ordering_data[:available_funds])
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
- else
|
- else
|
||||||
= t '.not_ordered'
|
= t '.not_ordered'
|
||||||
- if @order.closed?
|
- if @order.closed?
|
||||||
%p= t '.closed_by', user: @order.updated_by.nick
|
%p= t '.closed_by', user: show_user(@order.updated_by)
|
||||||
= link_to t('.comment'), "#comments"
|
= link_to t('.comment'), "#comments"
|
||||||
|
|
||||||
// Article box
|
// Article box
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
- for ft in current_user.ordergroup.financial_transactions.limit(5).order('created_on DESC')
|
- for ft in current_user.ordergroup.financial_transactions.limit(5).order('created_on DESC')
|
||||||
%tr
|
%tr
|
||||||
%td= format_time(ft.created_on)
|
%td= format_time(ft.created_on)
|
||||||
%td= h(ft.user.nil? ? '?' : ft.user.nick)
|
%td= h(show_user(ft.user))
|
||||||
%td= h(ft.note)
|
%td= h(ft.note)
|
||||||
- color = ft.amount < 0 ? 'red' : 'black'
|
- color = ft.amount < 0 ? 'red' : 'black'
|
||||||
%td{:style => "color:#{color}; width:5em", :class => "currency"}= number_to_currency(ft.amount)
|
%td{:style => "color:#{color}; width:5em", :class => "currency"}= number_to_currency(ft.amount)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
= number_to_currency(@ordergroup.get_available_funds())
|
= number_to_currency(@ordergroup.get_available_funds())
|
||||||
%p
|
%p
|
||||||
%b= Ordergroup.human_attribute_name(:user_tokens) + ':'
|
%b= Ordergroup.human_attribute_name(:user_tokens) + ':'
|
||||||
= @ordergroup.memberships.map{|m| m.user.nick}.join(', ')
|
= @ordergroup.memberships.map{|m| show_user m.user}.join(', ')
|
||||||
= link_to t('.invite'), new_invite_path(:id => @ordergroup), :remote => true, class: 'btn btn-primary'
|
= link_to t('.invite'), new_invite_path(:id => @ordergroup), :remote => true, class: 'btn btn-primary'
|
||||||
.span8
|
.span8
|
||||||
%h2= t('.account_summary')
|
%h2= t('.account_summary')
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
.row-fluid
|
.row-fluid
|
||||||
.span7
|
.span7
|
||||||
%h3
|
%h3
|
||||||
= h(t('.user.title', user: @current_user.nick))
|
= h(t('.user.title', user: show_user))
|
||||||
%small= t '.user.since', when: distance_of_time_in_words(Time.now, @current_user.created_on)
|
%small= t '.user.since', when: distance_of_time_in_words(Time.now, @current_user.created_on)
|
||||||
= simple_form_for(@current_user, :url => update_profile_path) do |f|
|
= simple_form_for(@current_user, :url => update_profile_path) do |f|
|
||||||
= render :partial => 'shared/user_form_fields', :locals => {:f => f}
|
= render :partial => 'shared/user_form_fields', :locals => {:f => f}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
%ul.nav.nav-pills.pull-right
|
%ul.nav.nav-pills.pull-right
|
||||||
%li.dropdown
|
%li.dropdown
|
||||||
%a.dropdown-toggle(data-toggle="dropdown" href="#")
|
%a.dropdown-toggle(data-toggle="dropdown" href="#")
|
||||||
= current_user.nick
|
= show_user current_user
|
||||||
%b.caret
|
%b.caret
|
||||||
%ul.dropdown-menu
|
%ul.dropdown-menu
|
||||||
%li= link_to t('.profile'), my_profile_path
|
%li= link_to t('.profile'), my_profile_path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- content_for :javascript do
|
- content_for :javascript do
|
||||||
:javascript
|
:javascript
|
||||||
$('user_nick').focus();
|
$(#{FoodsoftConfig[:use_nick] ? 'user_nick' : 'user_first_name'}).focus();
|
||||||
|
|
||||||
- title t('.title', name: FoodsoftConfig[:name])
|
- title t('.title', name: FoodsoftConfig[:name])
|
||||||
= t('.body', group: h(@invite.group.name), foodcoop: h(FoodsoftConfig[:name])).html_safe
|
= t('.body', group: h(@invite.group.name), foodcoop: h(FoodsoftConfig[:name])).html_safe
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- title t('.title')
|
- title t('.title')
|
||||||
= t('.body', user: h(@user.nick)).html_safe
|
= raw t('.body', user: h(show_user(@user)))
|
||||||
= simple_form_for @user, :url => update_password_path(@user.id, :token => @user.reset_password_token) do |form|
|
= simple_form_for @user, :url => update_password_path(@user.id, :token => @user.reset_password_token) do |form|
|
||||||
= form.input :password
|
= form.input :password
|
||||||
= form.input :password_confirmation
|
= form.input :password_confirmation
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
= t '.header', user: @user.nick, date: I18n.l(Time.now, :format => :short)
|
= t '.header', user: show_user(@user), date: I18n.l(Time.now, :format => :short)
|
||||||
\
|
\
|
||||||
= @feedback
|
= @feedback
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= t '.text', group: @group.name, when: @transaction.created_on.strftime('%d.%m.%Y um %H:%M'), balance: @group.account_balance, amount:@transaction.amount, note: @transaction.note, user: @transaction.user.nick, foodcoop: FoodsoftConfig[:name]
|
= t '.text', group: @group.name, when: @transaction.created_on.strftime('%d.%m.%Y um %H:%M'), balance: @group.account_balance, amount:@transaction.amount, note: @transaction.note, user: show_user(@transaction.user), foodcoop: FoodsoftConfig[:name]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= raw t '.text0', ordergroup: @group_order.ordergroup.name, order: @order.name, when: I18n.l(@order.ends), user: @order.updated_by.nick
|
= raw t '.text0', ordergroup: @group_order.ordergroup.name, order: @order.name, when: I18n.l(@order.ends), user: show_user(@order.updated_by)
|
||||||
- for group_order_article in @group_order.group_order_articles.ordered.all(:include => :order_article)
|
- for group_order_article in @group_order.group_order_articles.ordered.all(:include => :order_article)
|
||||||
- article = group_order_article.order_article.article
|
- article = group_order_article.order_article.article
|
||||||
\- #{article.name}: #{group_order_article.result} x #{article.unit} = #{group_order_article.result * article.fc_price}
|
\- #{article.name}: #{group_order_article.result} x #{article.unit} = #{group_order_article.result * article.fc_price}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= raw t '.text', user: @user.nick, link: @link, expires: I18n.l(@user.reset_password_expires)
|
= raw t '.text', user: show_user(@user), link: @link, expires: I18n.l(@user.reset_password_expires)
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
= t '.list.mail', email: mail_to(FoodsoftConfig[:mailing_list_subscribe])
|
= t '.list.mail', email: mail_to(FoodsoftConfig[:mailing_list_subscribe])
|
||||||
|
|
||||||
#recipients
|
#recipients
|
||||||
= f.input :recipient_tokens, :input_html => { 'data-pre' => User.find_all_by_id(@message.recipients_ids).map { |u| u.token_attributes }.to_json }
|
= f.input :recipient_tokens, :input_html => { 'data-pre' => User.find_all_by_id(@message.recipients_ids).map(&:token_attributes).to_json }
|
||||||
= f.input :group_id, :as => :select, :collection => Group.undeleted.order('type DESC, name ASC').all.reject { |g| g.memberships.empty? }
|
= f.input :group_id, :as => :select, :collection => Group.undeleted.order('type DESC, name ASC').all.reject { |g| g.memberships.empty? }
|
||||||
= f.input :private
|
= f.input :private
|
||||||
= f.input :subject, input_html: {class: 'input-xxlarge'}
|
= f.input :subject, input_html: {class: 'input-xxlarge'}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
%dt= t '.note'
|
%dt= t '.note'
|
||||||
%dd= @order.note
|
%dd= @order.note
|
||||||
%dt= t '.created_by'
|
%dt= t '.created_by'
|
||||||
%dd= link_to_user_message_if_valid(@order.created_by)
|
%dd= show_user_link(@order.created_by)
|
||||||
%dt= t '.begin'
|
%dt= t '.begin'
|
||||||
%dd= format_time(@order.starts)
|
%dd= format_time(@order.starts)
|
||||||
%dt= t '.ending'
|
%dt= t '.ending'
|
||||||
|
|
|
@ -12,12 +12,14 @@
|
||||||
|
|
||||||
= form_tag sessions_path, class: 'form-horizontal' do
|
= form_tag sessions_path, class: 'form-horizontal' do
|
||||||
.control-group
|
.control-group
|
||||||
%label(for='nick' class='control-label')= t '.user'
|
%label(for='nick' class='control-label')
|
||||||
|
= User.human_attribute_name (FoodsoftConfig[:use_nick] ? :user : :email)
|
||||||
.controls
|
.controls
|
||||||
= text_field_tag 'nick', nil, autocapitalize: 'off', autocorrect: 'off'
|
= text_field_tag 'nick', nil, autocapitalize: 'off', autocorrect: 'off'
|
||||||
|
|
||||||
.control-group
|
.control-group
|
||||||
%label(for='password' class='control-label')= t '.password'
|
%label(for='password' class='control-label')
|
||||||
|
= User.human_attribute_name :password
|
||||||
.controls
|
.controls
|
||||||
= password_field_tag 'password', nil, autocapitalize: 'off', autocorrect: 'off'
|
= password_field_tag 'password', nil, autocapitalize: 'off', autocorrect: 'off'
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- comments.each do |comment|
|
- comments.each do |comment|
|
||||||
.comment[comment]
|
.comment[comment]
|
||||||
%strong= comment.user.try(:ordergroup_name)
|
%strong= comment.user.try(:ordergroup_name)
|
||||||
%small (#{comment.user.try(:nick)} am #{format_time(comment.created_at)}):
|
%small (#{show_user comment.user} am #{format_time(comment.created_at)}):
|
||||||
= simple_format(comment.text)
|
= simple_format(comment.text)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
%dd
|
%dd
|
||||||
- members = group.users
|
- members = group.users
|
||||||
= "(#{members.size})"
|
= "(#{members.size})"
|
||||||
= members.collect(&:nick).join(", ")
|
= members.collect{|u| show_user(u)}.join(", ")
|
||||||
- unless group.is_a?(Workgroup)
|
- unless group.is_a?(Workgroup)
|
||||||
%dt= t '.apple_limit'
|
%dt= t '.apple_limit'
|
||||||
%dd= group.ignore_apple_restriction ? t('.deactivated') : t('.activated')
|
%dd= group.ignore_apple_restriction ? t('.deactivated') : t('.activated')
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
= yield
|
= yield
|
||||||
|
|
||||||
= f.input :user_tokens, :as => :string,
|
= f.input :user_tokens, :as => :string,
|
||||||
:input_html => { 'data-pre' => f.object.users.map { |u| u.token_attributes }.to_json }
|
:input_html => { 'data-pre' => f.object.users.map(&:token_attributes).to_json }
|
||||||
|
|
||||||
- content_for :javascript do
|
- content_for :javascript do
|
||||||
:javascript
|
:javascript
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
%td= format_time(order.ends) unless order.ends.nil?
|
%td= format_time(order.ends) unless order.ends.nil?
|
||||||
- if group_order = order.group_order(ordergroup)
|
- if group_order = order.group_order(ordergroup)
|
||||||
- total += group_order.price
|
- total += group_order.price
|
||||||
%td= "#{group_order.updated_by.nick} (#{format_time(group_order.updated_on)})"
|
%td= "#{show_user group_order.updated_by} (#{format_time(group_order.updated_on)})"
|
||||||
%td.numeric
|
%td.numeric
|
||||||
= link_to_ordering(order, show: true) do
|
= link_to_ordering(order, show: true) do
|
||||||
- number_to_currency(group_order.price)
|
- number_to_currency(group_order.price)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
= f.input :nick
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
-# use_nil option to user model validators break required mark
|
||||||
|
= f.input :nick, required: true
|
||||||
= f.input :first_name
|
= f.input :first_name
|
||||||
= f.input :last_name
|
= f.input :last_name
|
||||||
= f.input :email
|
= f.input :email
|
||||||
|
@ -19,7 +21,8 @@
|
||||||
= t 'simple_form.labels.settings.settings_group.privacy'
|
= t 'simple_form.labels.settings.settings_group.privacy'
|
||||||
= profile.input 'phone_is_public', as: :boolean, label: false, input_html: { checked: f.object.settings.profile['phone_is_public'] }
|
= 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 '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'] }
|
- if FoodsoftConfig[:use_nick]
|
||||||
|
= profile.input 'name_is_public', as: :boolean, label: false, input_html: { checked: f.object.settings.profile['name_is_public'] }
|
||||||
|
|
||||||
.settings-group
|
.settings-group
|
||||||
%div{class: 'control-group'}
|
%div{class: 'control-group'}
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
%div{id: "collapse#{workgroup.id}", class: 'accordion-body collapse'}
|
%div{id: "collapse#{workgroup.id}", class: 'accordion-body collapse'}
|
||||||
.accordion-inner
|
.accordion-inner
|
||||||
%ul.unstyled
|
%ul.unstyled
|
||||||
- workgroup.users.includes(:groups).order('nick').each do |user|
|
- workgroup.users.includes(:groups).natural_order.each do |user|
|
||||||
%li
|
%li
|
||||||
= user.nick
|
= show_user(user)
|
||||||
%small (#{user.ordergroup.try(:name)})
|
%small (#{user.ordergroup.try(:name)})
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
= simple_form_for(@stock_taking) do |f|
|
= simple_form_for(@stock_taking) do |f|
|
||||||
= f.input :date, as: :date_picker
|
= f.input :date, as: :date_picker
|
||||||
= f.input :note, :input_html => {:size => "28x7", :value => "#{@current_user.nick}: ..."}
|
= f.input :note, :input_html => {:size => "28x7", :value => "#{show_user @current_user, unique: true}: ..."}
|
||||||
%h2= t '.stock_articles'
|
%h2= t '.stock_articles'
|
||||||
|
|
||||||
#stock_changes
|
#stock_changes
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
= f.input :name
|
= f.input :name
|
||||||
= f.input :description, as: :text, input_html: {rows: 10}
|
= f.input :description, as: :text, input_html: {rows: 10}
|
||||||
= f.input :duration, :as => :select, :collection => 1..3
|
= f.input :duration, :as => :select, :collection => 1..3
|
||||||
= f.input :user_list, :as => :string, :input_html => { 'data-pre' => @task.users.map { |u| u.token_attributes }.to_json }
|
= f.input :user_list, :as => :string, :input_html => { 'data-pre' => @task.users.map(&:token_attributes).to_json }
|
||||||
= f.input :required_users
|
= f.input :required_users
|
||||||
= f.association :workgroup
|
= f.association :workgroup
|
||||||
= f.input :due_date, as: :date_picker
|
= f.input :due_date, as: :date_picker
|
||||||
|
|
|
@ -52,6 +52,11 @@ default: &defaults
|
||||||
# not fully enforced right now, since the check is only client-side
|
# not fully enforced right now, since the check is only client-side
|
||||||
# minimum_balance: 0
|
# minimum_balance: 0
|
||||||
|
|
||||||
|
# When use_nick is enabled, there will be a nickname field in the user form,
|
||||||
|
# and the option to show a nickname instead of full name to foodcoop members.
|
||||||
|
# Members of a user's groups and administrators can still see full names.
|
||||||
|
use_nick: false
|
||||||
|
|
||||||
# email address to be used as sender
|
# email address to be used as sender
|
||||||
email_sender: foodsoft@foodcoop.test
|
email_sender: foodsoft@foodcoop.test
|
||||||
|
|
||||||
|
|
|
@ -1328,9 +1328,7 @@ de:
|
||||||
login: Anmelden
|
login: Anmelden
|
||||||
nojs: Achtung, Cookies und Javascript müssen aktiviert sein! %{link} bitte abschalten.
|
nojs: Achtung, Cookies und Javascript müssen aktiviert sein! %{link} bitte abschalten.
|
||||||
noscript: NoScript
|
noscript: NoScript
|
||||||
password: Passwort
|
|
||||||
title: Foodsoft anmelden
|
title: Foodsoft anmelden
|
||||||
user: Benutzerin
|
|
||||||
shared:
|
shared:
|
||||||
articles:
|
articles:
|
||||||
ordered: Bestellt
|
ordered: Bestellt
|
||||||
|
|
|
@ -1284,7 +1284,7 @@ en:
|
||||||
headings: Heading
|
headings: Heading
|
||||||
italic: italic
|
italic: italic
|
||||||
list_item_1: First list item
|
list_item_1: First list item
|
||||||
list_item_2: Secound list item
|
list_item_2: Second list item
|
||||||
noformat: No wiki-formatting
|
noformat: No wiki-formatting
|
||||||
ordered_list: Numbered list
|
ordered_list: Numbered list
|
||||||
section_block: Block formatting
|
section_block: Block formatting
|
||||||
|
@ -1332,9 +1332,7 @@ en:
|
||||||
login: Login
|
login: Login
|
||||||
nojs: Attention, cookies and javascript have to be activated! Please switch off %{link}.
|
nojs: Attention, cookies and javascript have to be activated! Please switch off %{link}.
|
||||||
noscript: NoScript
|
noscript: NoScript
|
||||||
password: Password
|
|
||||||
title: Foodsoft login
|
title: Foodsoft login
|
||||||
user: User
|
|
||||||
shared:
|
shared:
|
||||||
articles:
|
articles:
|
||||||
ordered: Ordered
|
ordered: Ordered
|
||||||
|
|
|
@ -1335,9 +1335,7 @@ fr:
|
||||||
login: Te connecter
|
login: Te connecter
|
||||||
nojs: Attention, les cookies et le javascript doivent être activés! Merci de désactiver %{link}.
|
nojs: Attention, les cookies et le javascript doivent être activés! Merci de désactiver %{link}.
|
||||||
noscript: NoScript
|
noscript: NoScript
|
||||||
password: Mot de passe
|
|
||||||
title: Te connecter à Foodsoft
|
title: Te connecter à Foodsoft
|
||||||
user: Identifiant
|
|
||||||
shared:
|
shared:
|
||||||
articles:
|
articles:
|
||||||
ordered: Commandé
|
ordered: Commandé
|
||||||
|
|
|
@ -58,8 +58,8 @@ nl:
|
||||||
note: Notitie
|
note: Notitie
|
||||||
starts: Start op
|
starts: Start op
|
||||||
order_article:
|
order_article:
|
||||||
units_to_order:
|
units_to_order: Aantal eenheden
|
||||||
update_current_price:
|
update_current_price: Huidige prijs overal bijwerken
|
||||||
order_comment:
|
order_comment:
|
||||||
text: Commentaar voor deze bestelling toevoegen ...
|
text: Commentaar voor deze bestelling toevoegen ...
|
||||||
ordergroup:
|
ordergroup:
|
||||||
|
@ -67,12 +67,12 @@ nl:
|
||||||
contact_person: Contactpersoon
|
contact_person: Contactpersoon
|
||||||
contact_phone: Telefoon
|
contact_phone: Telefoon
|
||||||
description: Omschrijving
|
description: Omschrijving
|
||||||
ignore_apple_restriction:
|
ignore_apple_restriction: Bestelstop vanwege appelpunten negeren
|
||||||
name: Naam
|
name: Naam
|
||||||
user_tokens: Leden
|
user_tokens: Leden
|
||||||
page:
|
page:
|
||||||
body: Bericht
|
body: Bericht
|
||||||
parent_id:
|
parent_id: Ouderpagina
|
||||||
title: Titel
|
title: Titel
|
||||||
stock_article:
|
stock_article:
|
||||||
price: Prijs
|
price: Prijs
|
||||||
|
@ -354,10 +354,10 @@ nl:
|
||||||
error_nosel: Je hebt geen artikelen geselecteerd
|
error_nosel: Je hebt geen artikelen geselecteerd
|
||||||
parse_upload:
|
parse_upload:
|
||||||
body: <p><i>Ingelezen artikelen graag controleren.</i></p> <p><i>Let op, momenteel vind er geen controle op dubbele artikelen plaats.</i></p>
|
body: <p><i>Ingelezen artikelen graag controleren.</i></p> <p><i>Let op, momenteel vind er geen controle op dubbele artikelen plaats.</i></p>
|
||||||
title:
|
title: Artikelen uploaden
|
||||||
sync:
|
sync:
|
||||||
outlist:
|
outlist:
|
||||||
alert_used:
|
alert_used: Opgelet, %{article} wordt gebruikt in een lopende bestelling. Haal het eerst uit de bestelling.
|
||||||
body: ! 'De volgende artikelen zijn uit de lijst gehaald en worden <b>verwijderd</b>:'
|
body: ! 'De volgende artikelen zijn uit de lijst gehaald en worden <b>verwijderd</b>:'
|
||||||
body_skip: Er zijn geen artikelen om te verwijderen.
|
body_skip: Er zijn geen artikelen om te verwijderen.
|
||||||
title: Uit de lijst halen ...
|
title: Uit de lijst halen ...
|
||||||
|
@ -382,7 +382,7 @@ nl:
|
||||||
title: Artikelen uploaden voor %{supplier}
|
title: Artikelen uploaden voor %{supplier}
|
||||||
deliveries:
|
deliveries:
|
||||||
add_stock_change:
|
add_stock_change:
|
||||||
how_many_units:
|
how_many_units: ! 'Hoeveel eenheden (%{unit}) leveren? Voorraadartikel: %{name}.'
|
||||||
create:
|
create:
|
||||||
notice: Levering is aangemaakt. Vergeet niet een factuur te maken!
|
notice: Levering is aangemaakt. Vergeet niet een factuur te maken!
|
||||||
create_stock_article:
|
create_stock_article:
|
||||||
|
@ -390,22 +390,22 @@ nl:
|
||||||
destroy:
|
destroy:
|
||||||
notice: Levering is verwijdered.
|
notice: Levering is verwijdered.
|
||||||
edit:
|
edit:
|
||||||
title:
|
title: Levering aanpassen
|
||||||
form:
|
form:
|
||||||
actions:
|
actions: Taken
|
||||||
article: Artikel
|
article: Artikel
|
||||||
category: Categorie
|
category: Categorie
|
||||||
create_from_blank: Nieuwe artikel invoeren
|
create_from_blank: Nieuwe artikel invoeren
|
||||||
create_stock_article:
|
create_stock_article: Voorraadartikel maken
|
||||||
price:
|
price: Netto prijs
|
||||||
quantity:
|
quantity: Hoeveelheid
|
||||||
title_fill_quantities:
|
title_fill_quantities: 2. Hoeveel mag er geleverd worden
|
||||||
title_finish_delivery:
|
title_finish_delivery: 3. Levering afmaken
|
||||||
title_select_stock_articles:
|
title_select_stock_articles: 1. Kies voorraadartikelen
|
||||||
unit:
|
unit: Eenheid
|
||||||
index:
|
index:
|
||||||
confirm_delete:
|
confirm_delete: Zeker weten?
|
||||||
new_delivery:
|
new_delivery: Nieuwe levering maken voor %{supplier}
|
||||||
title:
|
title:
|
||||||
invoice_amount:
|
invoice_amount:
|
||||||
invoice_net_amount:
|
invoice_net_amount:
|
||||||
|
@ -429,12 +429,12 @@ nl:
|
||||||
stock_article_form:
|
stock_article_form:
|
||||||
copy_stock_article:
|
copy_stock_article:
|
||||||
stock_change_fields:
|
stock_change_fields:
|
||||||
remove_article:
|
remove_article: Artikel uit levering halen
|
||||||
suppliers_overview:
|
suppliers_overview: Leverancieroverzicht
|
||||||
update:
|
update:
|
||||||
notice: Levering is bijgewerkt.
|
notice: Levering is bijgewerkt.
|
||||||
update_stock_article:
|
update_stock_article:
|
||||||
notice:
|
notice: Voorraadartikel "%{name}" is bijgewerkt.
|
||||||
documents:
|
documents:
|
||||||
order_by_articles:
|
order_by_articles:
|
||||||
filename: Bestelling %{name}-%{date} - Artikellijst
|
filename: Bestelling %{name}-%{date} - Artikellijst
|
||||||
|
@ -483,8 +483,8 @@ nl:
|
||||||
new:
|
new:
|
||||||
first_paragraph: Probleem gevonden? Voorstel? Idee? Verbeterpunt? We horen graag je feedback.
|
first_paragraph: Probleem gevonden? Voorstel? Idee? Verbeterpunt? We horen graag je feedback.
|
||||||
second_paragraph:
|
second_paragraph:
|
||||||
send:
|
send: Verzenden
|
||||||
title:
|
title: Feedback geven
|
||||||
finance:
|
finance:
|
||||||
balancing:
|
balancing:
|
||||||
close:
|
close:
|
||||||
|
@ -555,7 +555,7 @@ nl:
|
||||||
no_closed_orders: Momenteel zijn er geen gesloten bestellingen.
|
no_closed_orders: Momenteel zijn er geen gesloten bestellingen.
|
||||||
state: Status
|
state: Status
|
||||||
summary:
|
summary:
|
||||||
changed:
|
changed: Waarden zijn gewijzigd!
|
||||||
duration: Van %{starts} tot %{ends}
|
duration: Van %{starts} tot %{ends}
|
||||||
fc_amount: ! 'FC-bedrag:'
|
fc_amount: ! 'FC-bedrag:'
|
||||||
fc_profit: FC Winst
|
fc_profit: FC Winst
|
||||||
|
@ -603,7 +603,7 @@ nl:
|
||||||
group_order_articles:
|
group_order_articles:
|
||||||
form:
|
form:
|
||||||
amount_change_for:
|
amount_change_for:
|
||||||
result_hint:
|
result_hint: ! 'Eenheid: %{unit}'
|
||||||
index:
|
index:
|
||||||
amount: Bedrag
|
amount: Bedrag
|
||||||
amount_fc: Bedrag(FC)
|
amount_fc: Bedrag(FC)
|
||||||
|
@ -684,7 +684,7 @@ nl:
|
||||||
title: Werkgroepen
|
title: Werkgroepen
|
||||||
workgroup:
|
workgroup:
|
||||||
edit: Groep bewerken
|
edit: Groep bewerken
|
||||||
show_tasks:
|
show_tasks: Alle taken weergeven
|
||||||
group_orders:
|
group_orders:
|
||||||
archive:
|
archive:
|
||||||
desc: Bekijk hier alle %{link}.
|
desc: Bekijk hier alle %{link}.
|
||||||
|
@ -716,7 +716,7 @@ nl:
|
||||||
note: Notitie
|
note: Notitie
|
||||||
price: Prijs
|
price: Prijs
|
||||||
reset_article_search:
|
reset_article_search:
|
||||||
search_article:
|
search_article: Artikel zoeken...
|
||||||
sum: Som
|
sum: Som
|
||||||
sum_amount: ! 'Huidig totaalbedrag:'
|
sum_amount: ! 'Huidig totaalbedrag:'
|
||||||
supplier: Leverancier
|
supplier: Leverancier
|
||||||
|
@ -949,11 +949,11 @@ nl:
|
||||||
dateformat: ! '%d %b'
|
dateformat: ! '%d %b'
|
||||||
feedback:
|
feedback:
|
||||||
header: ! '%{user} schreef op %{date}:'
|
header: ! '%{user} schreef op %{date}:'
|
||||||
subject:
|
subject: Feedback van %{email}
|
||||||
foodsoft_message:
|
foodsoft_message:
|
||||||
footer:
|
footer:
|
||||||
invite:
|
invite:
|
||||||
subject:
|
subject: Uitnodiging voor de foodcoop
|
||||||
text:
|
text:
|
||||||
negative_balance:
|
negative_balance:
|
||||||
subject:
|
subject:
|
||||||
|
@ -1009,21 +1009,21 @@ nl:
|
||||||
create:
|
create:
|
||||||
notice: Bericht is opgeslagen en wordt verzonden.
|
notice: Bericht is opgeslagen en wordt verzonden.
|
||||||
index:
|
index:
|
||||||
new:
|
new: Nieuw bericht
|
||||||
title:
|
title: Berichten
|
||||||
messages:
|
messages:
|
||||||
reply:
|
reply: Antwoorden
|
||||||
model:
|
model:
|
||||||
reply_header:
|
reply_header: ! '%{user} schreef op %{when}:'
|
||||||
reply_indent:
|
reply_indent: ! '> %{line}'
|
||||||
reply_subject:
|
reply_subject: ! 'Re: %{subject}'
|
||||||
new:
|
new:
|
||||||
list:
|
list:
|
||||||
desc:
|
desc: ! 'Berichten voor alle leden graag via de mailing-lijst verzenden: %{list}'
|
||||||
mail: bijvoorbeeld door een email te sturen naar %{email}.
|
mail: bijvoorbeeld door een email te sturen naar %{email}.
|
||||||
subscribe:
|
subscribe: Lees meer over de mailing-lijst op %{link}.
|
||||||
subscribe_msg:
|
subscribe_msg: Mogelijk moet je je eerst aanmelden voor de mailing-lijst.
|
||||||
wiki:
|
wiki: Wiki (mailing-lijst pagina)
|
||||||
no_user_found: Geen gebruiker gevonden
|
no_user_found: Geen gebruiker gevonden
|
||||||
search: Zoeken ...
|
search: Zoeken ...
|
||||||
search_user: Gebruiker zoeken
|
search_user: Gebruiker zoeken
|
||||||
|
@ -1152,28 +1152,30 @@ nl:
|
||||||
show:
|
show:
|
||||||
action_end: Sluiten!
|
action_end: Sluiten!
|
||||||
amounts:
|
amounts:
|
||||||
articles:
|
articles: Artikeloverzicht
|
||||||
articles_ordered:
|
articles_ordered: ! 'Bestelde artikelen:'
|
||||||
begin:
|
begin: ! 'Begin:'
|
||||||
comments:
|
comments:
|
||||||
title:
|
title: Commentaar
|
||||||
comments_link:
|
comments_link: Commentaar
|
||||||
confirm_delete:
|
confirm_delete:
|
||||||
confirm_end:
|
confirm_end: ! 'Wil je de bestelling %{order} echt sluiten?
|
||||||
created_by:
|
|
||||||
|
Hierna kan zij niet opnieuw geopend worden.'
|
||||||
|
created_by: ! 'Geopend door:'
|
||||||
download:
|
download:
|
||||||
article_pdf:
|
article_pdf: Artikelen PDF
|
||||||
download_file:
|
download_file: Bestand downloaden
|
||||||
fax_pdf:
|
fax_pdf: Fax PDF
|
||||||
fax_txt:
|
fax_txt: Fax text
|
||||||
group_pdf:
|
group_pdf: Huishoudens PDF
|
||||||
matrix_pdf:
|
matrix_pdf: Matrix PDF
|
||||||
title:
|
title: Downloaden
|
||||||
ending:
|
ending: ! 'Einde:'
|
||||||
group_orders:
|
group_orders: ! 'Ledenbestellingen:'
|
||||||
note:
|
note: ! 'Notitie:'
|
||||||
sort_article:
|
sort_article: Gesorteerd naar artikel
|
||||||
sort_group:
|
sort_group: Gesorteerd naar huishouden
|
||||||
supplier:
|
supplier:
|
||||||
title:
|
title:
|
||||||
warn_not_closed: Opgelet, bestelling is nog niet afgerekend.
|
warn_not_closed: Opgelet, bestelling is nog niet afgerekend.
|
||||||
|
@ -1213,17 +1215,17 @@ nl:
|
||||||
heading:
|
heading:
|
||||||
headings:
|
headings:
|
||||||
italic:
|
italic:
|
||||||
list_item_1:
|
list_item_1: Eerste in de lijst
|
||||||
list_item_2:
|
list_item_2: Tweede in de lijst
|
||||||
noformat:
|
noformat: Zonder wiki-opmaak
|
||||||
ordered_list:
|
ordered_list: Genummerde lijst
|
||||||
section_block:
|
section_block: Paragrafen
|
||||||
section_character:
|
section_character: Tekens
|
||||||
section_link:
|
section_link: Links
|
||||||
section_table:
|
section_table: Tabellen
|
||||||
see_tables:
|
see_tables: zie %{tables_link}
|
||||||
tables_link:
|
tables_link: Tabellen
|
||||||
text:
|
text: tekst
|
||||||
title:
|
title:
|
||||||
unordered_list:
|
unordered_list:
|
||||||
wiki_link_ex:
|
wiki_link_ex:
|
||||||
|
@ -1262,9 +1264,7 @@ nl:
|
||||||
login: Aanmelden
|
login: Aanmelden
|
||||||
nojs: Opgelet, cookies en javascript moeten toegelaten worden! %{link} uitzetten, alsjeblieft.
|
nojs: Opgelet, cookies en javascript moeten toegelaten worden! %{link} uitzetten, alsjeblieft.
|
||||||
noscript: NoScript
|
noscript: NoScript
|
||||||
password: Wachtwoord
|
|
||||||
title: Foodsoft aanmelden
|
title: Foodsoft aanmelden
|
||||||
user: Gebruiker
|
|
||||||
shared:
|
shared:
|
||||||
articles:
|
articles:
|
||||||
ordered: Besteld
|
ordered: Besteld
|
||||||
|
|
9
db/migrate/20130920201529_allow_missing_nick.rb
Normal file
9
db/migrate/20130920201529_allow_missing_nick.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class AllowMissingNick < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
change_column :users, :nick, :string, :default => nil, :null => true
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
change_column :users, :nick, :string, :default => "", :null => false
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,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 => 20130718183101) do
|
ActiveRecord::Schema.define(:version => 20130920201529) 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
|
||||||
|
@ -324,7 +324,7 @@ ActiveRecord::Schema.define(:version => 20130718183101) do
|
||||||
add_index "tasks", ["workgroup_id"], :name => "index_tasks_on_workgroup_id"
|
add_index "tasks", ["workgroup_id"], :name => "index_tasks_on_workgroup_id"
|
||||||
|
|
||||||
create_table "users", :force => true do |t|
|
create_table "users", :force => true do |t|
|
||||||
t.string "nick", :default => "", :null => false
|
t.string "nick"
|
||||||
t.string "password_hash", :default => "", :null => false
|
t.string "password_hash", :default => "", :null => false
|
||||||
t.string "password_salt", :default => "", :null => false
|
t.string "password_salt", :default => "", :null => false
|
||||||
t.string "first_name", :default => "", :null => false
|
t.string "first_name", :default => "", :null => false
|
||||||
|
|
|
@ -9,6 +9,8 @@ class FoodsoftConfig
|
||||||
set_config Rails.env
|
set_config Rails.env
|
||||||
# Overwrite scope to have a better namescope than 'production'
|
# Overwrite scope to have a better namescope than 'production'
|
||||||
self.scope = config[:default_scope] or raise "No default_scope is set"
|
self.scope = config[:default_scope] or raise "No default_scope is set"
|
||||||
|
# Set defaults for backward-compatibility
|
||||||
|
set_missing
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set config and database connection for specific foodcoop
|
# Set config and database connection for specific foodcoop
|
||||||
|
@ -46,5 +48,13 @@ class FoodsoftConfig
|
||||||
ActiveRecord::Base.establish_connection(database_config)
|
ActiveRecord::Base.establish_connection(database_config)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# When new options are introduced, put backward-compatible defaults here, so that
|
||||||
|
# configuration files that haven't been updated, still work as they did.
|
||||||
|
def set_missing
|
||||||
|
config.replace({
|
||||||
|
use_nick: true
|
||||||
|
}.merge(config))
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
%tr
|
%tr
|
||||||
%td{:style => "padding-left: #{ident}px"}
|
%td{:style => "padding-left: #{ident}px"}
|
||||||
= link_to page.title, wiki_page_path(page.permalink)
|
= link_to page.title, wiki_page_path(page.permalink)
|
||||||
%td #{page.user.try(:nick)} (#{format_datetime_timespec(page.updated_at, t('.date_format'))})
|
%td #{show_user page.user} (#{format_datetime_timespec(page.updated_at, t('.date_format'))})
|
||||||
-if siteMap == 1
|
-if siteMap == 1
|
||||||
-for child in page.children.all
|
-for child in page.children.all
|
||||||
= render :partial => 'page_list_item', :locals => {:page => child, :level => level+1, :siteMap => 1}
|
= render :partial => 'page_list_item', :locals => {:page => child, :level => level+1, :siteMap => 1}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
- @page.versions.reverse.each do |version|
|
- @page.versions.reverse.each do |version|
|
||||||
%li
|
%li
|
||||||
= link_to I18n.l(version.updated_at, :format => t('.date_format')), version_page_path(@page, :version => version.lock_version)
|
= link_to I18n.l(version.updated_at, :format => t('.date_format')), version_page_path(@page, :version => version.lock_version)
|
||||||
= "(#{User.find_by_id(version.updated_by).try(:nick)})"
|
= "(#{show_user(User.find_by_id(version.updated_by))})"
|
||||||
|
|
||||||
- unless @page.children.empty?
|
- unless @page.children.empty?
|
||||||
#subpages.well.well-small{:style => "display:none"}
|
#subpages.well.well-small{:style => "display:none"}
|
||||||
|
@ -48,4 +48,4 @@
|
||||||
%i.icon-edit= t '.edit'
|
%i.icon-edit= t '.edit'
|
||||||
= link_to t('.delete'), @page, class: 'btn btn-danger', :method => :delete,
|
= link_to t('.delete'), @page, class: 'btn btn-danger', :method => :delete,
|
||||||
:confirm => t('.delete_confirm')
|
:confirm => t('.delete_confirm')
|
||||||
!= '| ' + t('.last_updated', user: h(@page.user.try(:nick)), when: format_datetime(@page.updated_at))
|
!= '| ' + t('.last_updated', user: show_user(@page.user), when: format_datetime(@page.updated_at))
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
%h3= t '.title_version'
|
%h3= t '.title_version'
|
||||||
%b= "#{format_datetime_timespec(@version.updated_at, t('.date_format'))}"
|
%b= "#{format_datetime_timespec(@version.updated_at, t('.date_format'))}"
|
||||||
%ul
|
%ul
|
||||||
%li= t '.author', user: User.find(@version.updated_by).nick
|
%li= t '.author', user: show_user(User.find(@version.updated_by))
|
||||||
%li= link_to t('.view_current'), wiki_page_path(:permalink => @page.permalink)
|
%li= link_to t('.view_current'), wiki_page_path(:permalink => @page.permalink)
|
||||||
%li= link_to t('.revert'), revert_page_path(@page, :version => @version.lock_version)
|
%li= link_to t('.revert'), revert_page_path(@page, :version => @version.lock_version)
|
||||||
|
|
||||||
|
|
85
lib/foodsoft_wiki/config/locales/en.yml
Normal file
85
lib/foodsoft_wiki/config/locales/en.yml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
en:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
page:
|
||||||
|
body: Body
|
||||||
|
parent_id: Parent page
|
||||||
|
title: Title
|
||||||
|
model:
|
||||||
|
page:
|
||||||
|
redirect: Redirect to [[%{title}]]...
|
||||||
|
navigation:
|
||||||
|
wiki:
|
||||||
|
all_pages: All Pages
|
||||||
|
home: Home
|
||||||
|
title: Wiki
|
||||||
|
pages:
|
||||||
|
all:
|
||||||
|
new_page: Create new page
|
||||||
|
recent_changes: Recent changes
|
||||||
|
search:
|
||||||
|
action: Search
|
||||||
|
placeholder: Page title ..
|
||||||
|
site_map: Sitemap
|
||||||
|
title: All Wiki pages
|
||||||
|
title_list: List of pages
|
||||||
|
body:
|
||||||
|
title_toc: Content
|
||||||
|
create:
|
||||||
|
notice: Page was created
|
||||||
|
cshow:
|
||||||
|
error_noexist: Page doesn’t exist!
|
||||||
|
redirect_notice: Redirected from %{page} ...
|
||||||
|
destroy:
|
||||||
|
notice: The page '%{page}' and all subpages have been deleted successfully.
|
||||||
|
edit:
|
||||||
|
title: Edit page
|
||||||
|
error_stale_object: Warning, the page has just been edited by someone else. Please try again.
|
||||||
|
form:
|
||||||
|
help:
|
||||||
|
bold: bold
|
||||||
|
external_link_ex: External page
|
||||||
|
external_links: External links
|
||||||
|
heading: level %{level}
|
||||||
|
headings: Heading
|
||||||
|
italic: italic
|
||||||
|
list_item_1: First list item
|
||||||
|
list_item_2: Second list item
|
||||||
|
noformat: No wiki-formatting
|
||||||
|
ordered_list: Numbered list
|
||||||
|
section_block: Block formatting
|
||||||
|
section_character: Character formatting
|
||||||
|
section_link: Link formatting
|
||||||
|
section_table: Table formatting
|
||||||
|
see_tables: see %{tables_link}
|
||||||
|
tables_link: Tables
|
||||||
|
text: text
|
||||||
|
title: Quick formatting help
|
||||||
|
unordered_list: Item list
|
||||||
|
wiki_link_ex: Foodsoft Wiki Page
|
||||||
|
wiki_links: Wiki-links
|
||||||
|
preview: Preview
|
||||||
|
last_updated: Last updated
|
||||||
|
new:
|
||||||
|
title: Create new wiki page
|
||||||
|
page_list_item:
|
||||||
|
date_format: ! '%a, %d %B %Y %H:%M:%S'
|
||||||
|
show:
|
||||||
|
date_format: ! '%d-%m-%y %H:%M'
|
||||||
|
delete: Delete page
|
||||||
|
delete_confirm: ! 'Warning: all subpages will be deleted as well. Are you sure?'
|
||||||
|
edit: Edit page
|
||||||
|
last_updated: Last updated by <b>%{user}</b> on %{when}
|
||||||
|
subpages: subpages
|
||||||
|
title_versions: Versions
|
||||||
|
versions: Versions (%{count})
|
||||||
|
title: Title
|
||||||
|
update:
|
||||||
|
notice: Page was updated
|
||||||
|
version:
|
||||||
|
author: ! 'Author: %{user}'
|
||||||
|
date_format: ! '%a, %d-%m-%Y, %H:%M'
|
||||||
|
revert: Revert to this version
|
||||||
|
title: ! '%{title} - version %{version}'
|
||||||
|
title_version: Version
|
||||||
|
view_current: See current version
|
|
@ -4,7 +4,7 @@ describe 'the session', :type => :feature do
|
||||||
let(:user) { create :user }
|
let(:user) { create :user }
|
||||||
|
|
||||||
describe 'login page', :type => :feature do
|
describe 'login page', :type => :feature do
|
||||||
it 'is accesible' do
|
it 'is accessible' do
|
||||||
get login_path
|
get login_path
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
end
|
||||||
|
@ -16,6 +16,13 @@ describe 'the session', :type => :feature do
|
||||||
login user.nick, 'XX'+user.password
|
login user.nick, 'XX'+user.password
|
||||||
expect(page).to have_selector('.alert-error')
|
expect(page).to have_selector('.alert-error')
|
||||||
end
|
end
|
||||||
|
it 'can log me in using an email address' do
|
||||||
|
visit login_path
|
||||||
|
fill_in 'nick', :with => user.email
|
||||||
|
fill_in 'password', :with => user.password
|
||||||
|
find('input[type=submit]').click
|
||||||
|
expect(page).to_not have_selector('.alert-error')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -52,4 +52,58 @@ describe Article do
|
||||||
order = create :order, supplier: supplier, article_ids: [article.id]
|
order = create :order, supplier: supplier, article_ids: [article.id]
|
||||||
expect(article.in_open_order).to eq(order)
|
expect(article.in_open_order).to eq(order)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
it 'has no shared article by default' do
|
||||||
|
expect(article.shared_article).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'connected to a shared database', :type => :feature do
|
||||||
|
let(:shared_supplier) { create(:supplier) }
|
||||||
|
let(:shared_article) { create :article, supplier: shared_supplier, order_number: Faker::Lorem.characters(rand(1..12)) }
|
||||||
|
let(:supplier) { create :supplier, shared_supplier_id: shared_supplier.id }
|
||||||
|
let(:article) { create :article, supplier: supplier, order_number: shared_article.order_number }
|
||||||
|
|
||||||
|
it 'can be found in the shared database' do
|
||||||
|
expect(article.shared_article).to_not be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can find updates' do
|
||||||
|
changed = article.shared_article_changed?
|
||||||
|
expect(changed).to_not be_false
|
||||||
|
expect(changed.length).to be > 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can be synchronised' do
|
||||||
|
# TODO move article sync from supplier to article
|
||||||
|
article # need to reference for it to exist when syncing
|
||||||
|
updated_article = supplier.sync_all[0].select{|s| s[0].id==article.id}.first[0]
|
||||||
|
article.update_attributes updated_article.attributes.reject{|k,v| k=='id' or k=='type'}
|
||||||
|
expect(article.name).to eq(shared_article.name)
|
||||||
|
# now synchronising shouldn't change anything anymore
|
||||||
|
expect(article.shared_article_changed?).to be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not need to synchronise an imported article' do
|
||||||
|
article = SharedArticle.find(shared_article.id).build_new_article(supplier)
|
||||||
|
expect(article.shared_article_changed?).to be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adapts to foodcoop units when synchronising' do
|
||||||
|
shared_article.unit = '1kg'
|
||||||
|
shared_article.unit_quantity = 1
|
||||||
|
shared_article.save!
|
||||||
|
article = SharedArticle.find(shared_article.id).build_new_article(supplier)
|
||||||
|
article.article_category = create :article_category
|
||||||
|
article.unit = '200g'
|
||||||
|
article.shared_updated_on -= 1 # to make update do something
|
||||||
|
article.save!
|
||||||
|
# TODO get sync functionality in article
|
||||||
|
updated_article = supplier.sync_all[0].select{|s| s[0].id==article.id}.first[0]
|
||||||
|
article.update_attributes! updated_article.attributes.reject{|k,v| k=='id' or k=='type'}
|
||||||
|
expect(article.unit).to eq '200g'
|
||||||
|
expect(article.unit_quantity).to eq 5
|
||||||
|
expect(article.price).to be_within(1e-3).of(shared_article.price/5)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,6 +49,16 @@ describe User do
|
||||||
it 'has a unique email' do
|
it 'has a unique email' do
|
||||||
expect(build(:user, email: "#{user.email}")).to be_invalid
|
expect(build(:user, email: "#{user.email}")).to be_invalid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'can authenticate using email address' do
|
||||||
|
expect(User.authenticate(user.email, 'blahblah')).to be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can authenticate when there is no nick' do
|
||||||
|
user.nick = nil
|
||||||
|
expect(user).to be_valid
|
||||||
|
expect(User.authenticate(user.email, 'blahblah')).to be_true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'admin' do
|
describe 'admin' do
|
||||||
|
|
29
spec/support/shared_database.rb
Normal file
29
spec/support/shared_database.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# http://stackoverflow.com/questions/8774227
|
||||||
|
# http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite
|
||||||
|
class ActiveRecord::Base
|
||||||
|
mattr_accessor :shared_connection
|
||||||
|
@@shared_connection = nil
|
||||||
|
|
||||||
|
def self.connection
|
||||||
|
@@shared_connection || retrieve_connection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Forces all threads to share the same connection. This works on
|
||||||
|
# Capybara because it starts the web server in a thread.
|
||||||
|
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
|
||||||
|
|
||||||
|
ActiveSupport.on_load(:after_initialize) do
|
||||||
|
# We simulate the shared database by pointing to our own database.
|
||||||
|
# This allows running tests without additional database setup.
|
||||||
|
# But take care when designing tests using the shared database.
|
||||||
|
SharedSupplier.establish_connection Rails.env
|
||||||
|
SharedArticle.establish_connection Rails.env
|
||||||
|
# hack for different structure of shared database
|
||||||
|
SharedArticle.class_eval do
|
||||||
|
alias_attribute :number, :order_number
|
||||||
|
alias_attribute :updated_on, :updated_at
|
||||||
|
def self.find_by_number(n)
|
||||||
|
find_by_order_number(n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue