2012-04-16 08:48:01 +02:00
|
|
|
# encoding: utf-8
|
|
|
|
#
|
2009-01-14 12:46:01 +01:00
|
|
|
# Ordergroups can order, they are "children" of the class Group
|
2009-01-06 11:49:19 +01:00
|
|
|
#
|
2009-01-14 12:46:01 +01:00
|
|
|
# Ordergroup have the following attributes, in addition to Group
|
2009-01-06 11:49:19 +01:00
|
|
|
# * account_balance (decimal)
|
|
|
|
# * account_updated (datetime)
|
2009-01-14 12:46:01 +01:00
|
|
|
class Ordergroup < Group
|
2009-01-29 01:57:51 +01:00
|
|
|
acts_as_paranoid # Avoid deleting the ordergroup for consistency of order-results
|
2009-08-01 13:41:22 +02:00
|
|
|
serialize :stats
|
2009-01-29 01:57:51 +01:00
|
|
|
|
2009-02-03 21:14:48 +01:00
|
|
|
has_many :financial_transactions, :order => "created_on DESC"
|
2009-01-29 01:57:51 +01:00
|
|
|
has_many :group_orders
|
2009-01-06 11:49:19 +01:00
|
|
|
has_many :orders, :through => :group_orders
|
|
|
|
|
|
|
|
validates_numericality_of :account_balance, :message => 'ist keine gültige Zahl'
|
2011-06-10 13:22:15 +02:00
|
|
|
validate :uniqueness_of_members
|
2009-01-29 01:57:51 +01:00
|
|
|
|
2009-08-01 13:41:22 +02:00
|
|
|
after_create :update_stats!
|
|
|
|
|
2009-02-02 16:35:43 +01:00
|
|
|
def contact
|
|
|
|
"#{contact_phone} (#{contact_person})"
|
|
|
|
end
|
2009-02-01 20:56:23 +01:00
|
|
|
def non_members
|
|
|
|
User.all(:order => 'nick').reject { |u| (users.include?(u) || u.ordergroup) }
|
|
|
|
end
|
2009-01-29 01:57:51 +01:00
|
|
|
|
|
|
|
def value_of_open_orders(exclude = nil)
|
|
|
|
group_orders.open.reject{|go| go == exclude}.collect(&:price).sum
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
|
2009-01-29 01:57:51 +01:00
|
|
|
def value_of_finished_orders(exclude = nil)
|
|
|
|
group_orders.finished.reject{|go| go == exclude}.collect(&:price).sum
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns the available funds for this order group (the account_balance minus price of all non-closed GroupOrders of this group).
|
|
|
|
# * exclude (GroupOrder): exclude this GroupOrder from the calculation
|
|
|
|
def get_available_funds(exclude = nil)
|
|
|
|
account_balance - value_of_open_orders(exclude) - value_of_finished_orders(exclude)
|
|
|
|
end
|
|
|
|
|
2009-01-14 12:46:01 +01:00
|
|
|
# Creates a new FinancialTransaction for this Ordergroup and updates the account_balance accordingly.
|
2009-01-06 11:49:19 +01:00
|
|
|
# Throws an exception if it fails.
|
2011-06-09 21:35:05 +02:00
|
|
|
def add_financial_transaction!(amount, note, user)
|
2009-01-06 11:49:19 +01:00
|
|
|
transaction do
|
2009-01-14 12:46:01 +01:00
|
|
|
trans = FinancialTransaction.new(:ordergroup => self, :amount => amount, :note => note, :user => user)
|
2009-01-06 11:49:19 +01:00
|
|
|
trans.save!
|
2011-06-09 21:35:05 +02:00
|
|
|
self.account_balance = financial_transactions.sum('amount')
|
2009-01-06 11:49:19 +01:00
|
|
|
self.account_updated = trans.created_on
|
|
|
|
save!
|
2009-02-04 16:41:01 +01:00
|
|
|
notify_negative_balance(trans)
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
|
|
|
end
|
2009-02-04 16:41:01 +01:00
|
|
|
|
2009-08-01 13:41:22 +02:00
|
|
|
def update_stats!
|
|
|
|
time = 6.month.ago
|
2011-05-07 21:54:00 +02:00
|
|
|
jobs = users.collect { |u| u.tasks.done.sum('duration', :conditions => ["updated_on > ?", time]) }.sum
|
2010-06-19 12:23:18 +02:00
|
|
|
orders_sum = group_orders.select { |go| !go.order.ends.nil? && go.order.ends > time }.collect(&:price).sum
|
2009-08-01 13:41:22 +02:00
|
|
|
update_attribute(:stats, {:jobs_size => jobs, :orders_sum => orders_sum})
|
|
|
|
end
|
|
|
|
|
|
|
|
def avg_jobs_per_euro
|
|
|
|
stats[:orders_sum] != 0 ? stats[:jobs_size].to_f / stats[:orders_sum].to_f : 0
|
|
|
|
end
|
|
|
|
|
|
|
|
# Global average
|
|
|
|
def self.avg_jobs_per_euro
|
|
|
|
stats = Ordergroup.all.collect(&:stats)
|
|
|
|
stats.collect {|s| s[:jobs_size].to_f }.sum / stats.collect {|s| s[:orders_sum].to_f }.sum
|
|
|
|
end
|
|
|
|
|
2009-02-04 16:41:01 +01:00
|
|
|
private
|
2009-01-06 11:49:19 +01:00
|
|
|
|
|
|
|
# If this order group's account balance is made negative by the given/last transaction,
|
|
|
|
# a message is sent to all users who have enabled notification.
|
2009-02-04 16:41:01 +01:00
|
|
|
def notify_negative_balance(transaction)
|
2009-01-06 11:49:19 +01:00
|
|
|
# Notify only when order group had a positive balance before the last transaction:
|
2009-02-18 01:06:35 +01:00
|
|
|
if (transaction.amount < 0 && self.account_balance < 0 && self.account_balance - transaction.amount >= 0)
|
|
|
|
for user in users
|
2011-05-11 10:53:18 +02:00
|
|
|
Mailer.negative_balance(user,transaction).deliver if user.settings["notify.negativeBalance"] == '1'
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2009-01-15 20:10:50 +01:00
|
|
|
end
|
2009-01-06 11:49:19 +01:00
|
|
|
end
|
2011-06-10 13:22:15 +02:00
|
|
|
|
|
|
|
# Make sure, that a user can only be in one ordergroup
|
|
|
|
def uniqueness_of_members
|
|
|
|
users.each do |user|
|
|
|
|
errors.add :user_tokens, "#{user.nick} ist schon in einer anderen Bestellgruppe" if user.groups.where(:type => 'Ordergroup').size > 1
|
|
|
|
end
|
|
|
|
end
|
2009-01-06 11:49:19 +01:00
|
|
|
|
|
|
|
end
|
2011-05-07 20:50:39 +02:00
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: groups
|
|
|
|
#
|
2011-05-07 21:55:24 +02:00
|
|
|
# id :integer(4) not null, primary key
|
2011-05-07 20:50:39 +02:00
|
|
|
# type :string(255) default(""), not null
|
|
|
|
# name :string(255) default(""), not null
|
|
|
|
# description :string(255)
|
2011-05-07 21:55:24 +02:00
|
|
|
# account_balance :decimal(8, 2) default(0.0), not null
|
2011-05-07 20:50:39 +02:00
|
|
|
# account_updated :datetime
|
|
|
|
# created_on :datetime not null
|
2011-05-07 21:55:24 +02:00
|
|
|
# role_admin :boolean(1) default(FALSE), not null
|
|
|
|
# role_suppliers :boolean(1) default(FALSE), not null
|
|
|
|
# role_article_meta :boolean(1) default(FALSE), not null
|
|
|
|
# role_finance :boolean(1) default(FALSE), not null
|
|
|
|
# role_orders :boolean(1) default(FALSE), not null
|
|
|
|
# weekly_task :boolean(1) default(FALSE)
|
|
|
|
# weekday :integer(4)
|
2011-05-07 20:50:39 +02:00
|
|
|
# task_name :string(255)
|
|
|
|
# task_description :string(255)
|
2011-05-07 21:55:24 +02:00
|
|
|
# task_required_users :integer(4) default(1)
|
2011-05-07 20:50:39 +02:00
|
|
|
# deleted_at :datetime
|
|
|
|
# contact_person :string(255)
|
|
|
|
# contact_phone :string(255)
|
|
|
|
# contact_address :string(255)
|
|
|
|
# stats :text
|
2011-05-07 21:55:24 +02:00
|
|
|
# task_duration :integer(4) default(1)
|
2011-05-07 20:50:39 +02:00
|
|
|
#
|
|
|
|
|