93143c28f2
see https://github.com/foodcoops/foodsoft/pull/907 for reference and original work by viehlieb Co-authored-by: viehlieb <pf@pragma-shift.net> fix PDF Pdf make explicit deposit in invoices work add ordergroupname to invoice file name mark bold sum for vat exempt foodcoops download multiple group order invoice as zip
114 lines
4 KiB
Ruby
114 lines
4 KiB
Ruby
# A GroupOrder represents an Order placed by an Ordergroup.
|
|
class GroupOrder < ApplicationRecord
|
|
include FindEachWithOrder
|
|
|
|
attr_accessor :group_order_articles_attributes
|
|
|
|
belongs_to :order
|
|
belongs_to :ordergroup, optional: true
|
|
has_many :group_order_articles, dependent: :destroy
|
|
has_many :order_articles, through: :group_order_articles
|
|
has_one :financial_transaction
|
|
has_one :group_order_invoice
|
|
belongs_to :updated_by, optional: true, class_name: 'User', foreign_key: 'updated_by_user_id'
|
|
|
|
validates :order_id, presence: true
|
|
validates :price, numericality: true
|
|
validates :ordergroup_id, uniqueness: { scope: :order_id } # order groups can only order once per order
|
|
|
|
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') }
|
|
|
|
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 = {}
|
|
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...
|
|
if group_order_articles_attributes
|
|
quantities = group_order_articles_attributes.fetch(order_article.id.to_s, { quantity: 0, tolerance: 0 })
|
|
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: %i[article article_price]).to_a.sum(&:total_price)
|
|
update_attribute(:price, total)
|
|
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
|
|
if ordergroup
|
|
ordergroup.name
|
|
else
|
|
I18n.t('model.group_order.stock_ordergroup_name',
|
|
user: updated_by.try(:name) || '?')
|
|
end
|
|
end
|
|
|
|
def total
|
|
return price + transport if transport
|
|
|
|
price
|
|
end
|
|
end
|