foodsoft/app/models/group_order.rb

109 lines
4 KiB
Ruby
Raw Normal View History

# A GroupOrder represents an Order placed by an Ordergroup.
class GroupOrder < ApplicationRecord
2016-06-04 21:37:47 +02:00
include FindEachWithOrder
attr_accessor :group_order_articles_attributes
2009-01-06 11:49:19 +01:00
belongs_to :order
belongs_to :ordergroup, optional: true
2009-01-06 11:49:19 +01:00
has_many :group_order_articles, :dependent => :destroy
has_many :order_articles, :through => :group_order_articles
has_one :financial_transaction
belongs_to :updated_by, optional: true, class_name: 'User', foreign_key: 'updated_by_user_id'
2009-01-06 11:49:19 +01:00
validates_presence_of :order_id
validates_numericality_of :price
validates_uniqueness_of :ordergroup_id, :scope => :order_id # order groups can only order once per order
2009-01-06 11:49:19 +01:00
scope :in_open_orders, -> { joins(:order).merge(Order.open) }
scope :in_finished_orders, -> { joins(:order).merge(Order.finished_not_closed) }
scope :stock, -> { where(ordergroup: 0) }
scope :ordered, -> { includes(:ordergroup).order('groups.name') }
2018-10-13 16:27:24 +02:00
def self.ransackable_attributes(auth_object = nil)
%w(id price)
end
def self.ransackable_associations(auth_object = nil)
%w(order group_order_articles)
end
# Generate some data for the javascript methods in ordering view
def load_data
data = {}
2023-02-14 12:25:41 +01:00
data[:account_balance] = ordergroup.nil? ? BigDecimal('+Infinity') : ordergroup.account_balance
data[:available_funds] = ordergroup.nil? ? BigDecimal('+Infinity') : ordergroup.get_available_funds(self)
# load prices and other stuff....
data[:order_articles] = {}
order.articles_grouped_by_category.each do |article_category, order_articles|
order_articles.each do |order_article|
# Get the result of last time ordering, if possible
goa = group_order_articles.detect { |goa| goa.order_article_id == order_article.id }
# Build hash with relevant data
data[:order_articles][order_article.id] = {
:price => order_article.article.fc_price,
:unit => order_article.article.unit_quantity,
:quantity => (goa ? goa.quantity : 0),
:others_quantity => order_article.quantity - (goa ? goa.quantity : 0),
:used_quantity => (goa ? goa.result(:quantity) : 0),
:tolerance => (goa ? goa.tolerance : 0),
:others_tolerance => order_article.tolerance - (goa ? goa.tolerance : 0),
:used_tolerance => (goa ? goa.result(:tolerance) : 0),
:total_price => (goa ? goa.total_price : 0),
:missing_units => order_article.missing_units,
:quantity_available => (order.stockit? ? order_article.article.quantity_available : 0)
}
end
end
data
end
def save_group_order_articles
for order_article in order.order_articles
# Find the group_order_article, create a new one if necessary...
group_order_article = group_order_articles.where(order_article_id: order_article.id).first_or_create
# Get ordered quantities and update group_order_articles/_quantities...
2015-09-23 22:38:20 +02:00
if group_order_articles_attributes
quantities = group_order_articles_attributes.fetch(order_article.id.to_s, { :quantity => 0, :tolerance => 0 })
2015-09-23 22:38:20 +02:00
group_order_article.update_quantities(quantities[:quantity].to_i, quantities[:tolerance].to_i)
end
# Also update results for the order_article
logger.debug "[save_group_order_articles] update order_article.results!"
order_article.update_results!
end
# set attributes to nil to avoid and infinite loop of
end
# Updates the "price" attribute.
def update_price!
total = group_order_articles.includes(:order_article => [:article, :article_price]).to_a.sum(&:total_price)
update_attribute(:price, total)
2009-01-06 11:49:19 +01:00
end
# Save GroupOrder and updates group_order_articles/quantities accordingly
def save_ordering!
transaction do
save!
save_group_order_articles
update_price!
end
end
def ordergroup_name
ordergroup ? ordergroup.name : I18n.t('model.group_order.stock_ordergroup_name', :user => updated_by.try(:name) || '?')
end
2020-03-19 00:22:20 +01:00
def total
return price + transport if transport
2020-03-19 00:22:20 +01:00
price
end
2009-01-06 11:49:19 +01:00
end