100 lines
3.9 KiB
Ruby
100 lines
3.9 KiB
Ruby
# == Schema Information
|
|
# Schema version: 20090119155930
|
|
#
|
|
# Table name: order_articles
|
|
#
|
|
# id :integer not null, primary key
|
|
# order_id :integer default(0), not null
|
|
# article_id :integer default(0), not null
|
|
# quantity :integer default(0), not null
|
|
# tolerance :integer default(0), not null
|
|
# units_to_order :integer default(0), not null
|
|
# lock_version :integer default(0), not null
|
|
# article_price_id :integer
|
|
#
|
|
|
|
# An OrderArticle represents a single Article that is part of an Order.
|
|
class OrderArticle < ActiveRecord::Base
|
|
|
|
belongs_to :order
|
|
belongs_to :article
|
|
belongs_to :article_price
|
|
has_many :group_order_articles, :dependent => :destroy
|
|
|
|
validates_presence_of :order_id
|
|
validates_presence_of :article_id
|
|
validates_uniqueness_of :article_id, :scope => :order_id # an article can only have one record per order
|
|
validate :article_and_price_exist
|
|
|
|
named_scope :ordered, :conditions => "units_to_order >= 1"
|
|
|
|
# TODO: How to create/update articles/article_prices during balancing
|
|
# # Accessors for easy create of new order_articles in balancing process
|
|
# attr_accessor :name, :order_number, :units_to_order, :unit_quantity, :unit, :net_price, :tax, :deposit
|
|
#
|
|
# before_validation_on_create :create_new_article
|
|
|
|
# This method returns either the ArticlePrice or the Article
|
|
# The first will be set, when the the order is finished
|
|
def price
|
|
article_price || article
|
|
end
|
|
|
|
# Count quantities of belonging group_orders.
|
|
# In balancing this can differ from ordered (by supplier) quantity for this article.
|
|
def group_orders_sum
|
|
quantity = group_order_articles.collect(&:result).sum
|
|
{:quantity => quantity, :price => quantity * price.fc_price}
|
|
end
|
|
|
|
# Update quantity/tolerance/units_to_order from group_order_articles
|
|
# This is only used in opened orders.
|
|
def update_results!
|
|
quantity = group_order_articles.collect(&:quantity).sum
|
|
tolerance = group_order_articles.collect(&:tolerance).sum
|
|
update_attributes(:quantity => quantity, :tolerance => tolerance,
|
|
:units_to_order => calculate_units_to_order(quantity, tolerance))
|
|
end
|
|
|
|
# Returns how many units of the belonging article need to be ordered given the specified order quantity and tolerance.
|
|
# This is determined by calculating how many units can be ordered from the given order quantity, using
|
|
# the tolerance to order an additional unit if the order quantity is not quiet sufficient.
|
|
# There must always be at least one item in a unit that is an ordered quantity (no units are ever entirely
|
|
# filled by tolerance items only).
|
|
#
|
|
# Example:
|
|
#
|
|
# unit_quantity | quantity | tolerance | calculate_units_to_order
|
|
# --------------+----------+-----------+-----------------------
|
|
# 4 | 0 | 2 | 0
|
|
# 4 | 0 | 5 | 0
|
|
# 4 | 2 | 2 | 1
|
|
# 4 | 4 | 2 | 1
|
|
# 4 | 4 | 4 | 1
|
|
# 4 | 5 | 3 | 2
|
|
# 4 | 5 | 4 | 2
|
|
#
|
|
def calculate_units_to_order(quantity, tolerance = 0)
|
|
unit_size = price.unit_quantity
|
|
units = quantity / unit_size
|
|
remainder = quantity % unit_size
|
|
units += ((remainder > 0) && (remainder + tolerance >= unit_size) ? 1 : 0)
|
|
end
|
|
|
|
def ordered_quantities_equal_to_group_orders?
|
|
(units_to_order * price.unit_quantity) == group_orders_sum[:quantity]
|
|
end
|
|
|
|
private
|
|
|
|
def article_and_price_exist
|
|
errors.add(:article, "muss angegeben sein und einen aktuellen Preis haben") if !(article = Article.find(article_id)) || article.fc_price.nil?
|
|
end
|
|
|
|
# def create_new_article
|
|
# old_article = order.articles.find_by_name(name) # Check if there is already an Article with this name
|
|
# unless old_article
|
|
# self.article.build
|
|
# end
|
|
# end
|
|
end
|