API v1 group_order_articles endpoints
This commit is contained in:
parent
ed9192c47f
commit
e1d50e5b9c
11 changed files with 646 additions and 10 deletions
108
app/controllers/api/v1/user/group_order_articles_controller.rb
Normal file
108
app/controllers/api/v1/user/group_order_articles_controller.rb
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
class Api::V1::User::GroupOrderArticlesController < Api::V1::BaseController
|
||||
include Concerns::CollectionScope
|
||||
|
||||
before_action ->{ doorkeeper_authorize! 'group_orders:user' }
|
||||
|
||||
before_action :require_ordergroup
|
||||
before_action :require_minimum_balance, only: [:create, :update] # destroy is ok
|
||||
before_action :require_enough_apples, only: [:create, :update] # destroy is ok
|
||||
# @todo allow decreasing amounts when minimum balance isn't met
|
||||
|
||||
def index
|
||||
render_collection search_scope
|
||||
end
|
||||
|
||||
def show
|
||||
goa = scope.find(params.require(:id))
|
||||
render_goa_with_oa(goa)
|
||||
end
|
||||
|
||||
def create
|
||||
goa = nil
|
||||
GroupOrderArticle.transaction do
|
||||
oa = order_articles_scope_for_create.find(create_params.require(:order_article_id))
|
||||
go = current_ordergroup.group_orders.find_or_create_by!(order_id: oa.order_id)
|
||||
goa = go.group_order_articles.create!(order_article: oa)
|
||||
goa.update_quantities((create_params[:quantity] || 0).to_i, (create_params[:tolerance] || 0).to_i)
|
||||
oa.update_results!
|
||||
go.update_price!
|
||||
go.update_attributes! updated_by: current_user
|
||||
end
|
||||
render_goa_with_oa(goa)
|
||||
end
|
||||
|
||||
def update
|
||||
goa = nil
|
||||
GroupOrderArticle.transaction do
|
||||
goa = scope_for_update.includes(:group_order_article_quantities).find(params.require(:id))
|
||||
goa.update_quantities((update_params[:quantity] || goa.quantity).to_i, (update_params[:tolerance] || goa.tolerance).to_i)
|
||||
goa.order_article.update_results!
|
||||
goa.group_order.update_price!
|
||||
goa.group_order.update_attributes! updated_by: current_user
|
||||
end
|
||||
render_goa_with_oa(goa)
|
||||
end
|
||||
|
||||
def destroy
|
||||
goa = nil
|
||||
GroupOrderArticle.transaction do
|
||||
goa = scope_for_update.find(params.require(:id))
|
||||
goa.destroy!
|
||||
goa.order_article.update_results!
|
||||
goa.group_order.update_price!
|
||||
goa.group_order.update_attributes! updated_by: current_user
|
||||
end
|
||||
render_goa_with_oa(nil, goa.order_article)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def max_per_page
|
||||
nil
|
||||
end
|
||||
|
||||
def scope
|
||||
GroupOrderArticle.
|
||||
joins(:group_order).
|
||||
includes(order_article: :article, group_order: :order).
|
||||
where(group_orders: { ordergroup_id: current_ordergroup.id })
|
||||
end
|
||||
|
||||
def scope_for_update
|
||||
scope.references(order_article: { group_order: :order }).merge(Order.open)
|
||||
end
|
||||
|
||||
def order_articles_scope_for_create
|
||||
OrderArticle.joins(:order).merge(Order.open)
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:group_order_article).permit(:order_article_id, :quantity, :tolerance)
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.require(:group_order_article).permit(:quantity, :tolerance)
|
||||
end
|
||||
|
||||
def require_minimum_balance
|
||||
minimum_balance = FoodsoftConfig[:minimum_balance] or return
|
||||
if current_ordergroup.account_balance < minimum_balance
|
||||
raise Api::Errors::PermissionRequired.new(t('application.controller.error_minimum_balance', min: minimum_balance))
|
||||
end
|
||||
end
|
||||
|
||||
def require_enough_apples
|
||||
if current_ordergroup.not_enough_apples?
|
||||
s = t('group_orders.messages.not_enough_apples', apples: current_ordergroup.apples, stop_ordering_under: FoodsoftConfig[:stop_ordering_under])
|
||||
raise Api::Errors::PermissionRequired.new(s)
|
||||
end
|
||||
end
|
||||
|
||||
def render_goa_with_oa(goa, oa = goa.order_article)
|
||||
data = {}
|
||||
data[:group_order_article] = GroupOrderArticleSerializer.new(goa) if goa
|
||||
data[:order_article] = OrderArticleSerializer.new(oa) if oa
|
||||
|
||||
render json: data, root: nil
|
||||
end
|
||||
end
|
||||
|
|
@ -21,6 +21,14 @@ class GroupOrder < ApplicationRecord
|
|||
|
||||
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 = {}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,25 @@ class GroupOrderArticle < ApplicationRecord
|
|||
|
||||
belongs_to :group_order
|
||||
belongs_to :order_article
|
||||
has_many :group_order_article_quantities, :dependent => :destroy
|
||||
has_many :group_order_article_quantities, dependent: :destroy
|
||||
|
||||
validates_presence_of :group_order, :order_article
|
||||
validates_uniqueness_of :order_article_id, :scope => :group_order_id # just once an article per group order
|
||||
validate :check_order_not_closed # don't allow changes to closed (aka settled) orders
|
||||
validates :quantity, :tolerance, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
|
||||
scope :ordered, -> { includes(:group_order => :ordergroup).order('groups.name') }
|
||||
|
||||
localize_input_of :result
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w(id quantity tolerance result)
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
%w(order_article group_order)
|
||||
end
|
||||
|
||||
# Setter used in group_order_article#new
|
||||
# We have to create an group_order, if the ordergroup wasn't involved in the order yet
|
||||
def ordergroup_id=(id)
|
||||
|
|
@ -86,7 +95,7 @@ class GroupOrderArticle < ApplicationRecord
|
|||
|
||||
# Check if something went terribly wrong and quantites have not been adjusted as desired.
|
||||
if (self.quantity != quantity || self.tolerance != tolerance)
|
||||
raise 'Invalid state: unable to update GroupOrderArticle/-Quantities to desired quantities!'
|
||||
raise ActiveRecord::RecordNotSaved.new('Unable to update GroupOrderArticle/-Quantities to desired quantities!', self)
|
||||
end
|
||||
|
||||
# Remove zero-only items.
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ class Order < ApplicationRecord
|
|||
|
||||
# Finders
|
||||
scope :started, -> { where('starts <= ?', Time.now) }
|
||||
scope :closed, -> { where(state: 'closed').order('ends DESC') }
|
||||
scope :stockit, -> { where(supplier_id: nil).order('ends DESC') }
|
||||
scope :recent, -> { order('starts DESC').limit(10) }
|
||||
scope :closed, -> { where(state: 'closed').order(ends: :desc) }
|
||||
scope :stockit, -> { where(supplier_id: nil).order(ends: :desc) }
|
||||
scope :recent, -> { order(starts: :desc).limit(10) }
|
||||
scope :stock_group_order, -> { group_orders.where(ordergroup_id: nil).first }
|
||||
scope :with_invoice, -> { where.not(invoice: nil) }
|
||||
|
||||
|
|
@ -42,9 +42,9 @@ class Order < ApplicationRecord
|
|||
# So orders can
|
||||
# 1. ...only transition in one direction (e.g. an order that has been `finished` currently cannot be reopened)
|
||||
# 2. ...be set to `closed` when having the `finished` state. (`received` is optional)
|
||||
scope :open, -> { where(state: 'open').order('ends DESC') }
|
||||
scope :finished, -> { where(state: %w[finished received closed]).order('ends DESC') }
|
||||
scope :finished_not_closed, -> { where(state: %w[finished received]).order('ends DESC') }
|
||||
scope :open, -> { where(state: 'open').order(ends: :desc) }
|
||||
scope :finished, -> { where(state: %w[finished received closed]).order(ends: :desc) }
|
||||
scope :finished_not_closed, -> { where(state: %w[finished received]).order(ends: :desc) }
|
||||
|
||||
# Allow separate inputs for date and time
|
||||
# with workaround for https://github.com/einzige/date_time_attribute/issues/14
|
||||
|
|
|
|||
8
app/serializers/group_order_article_serializer.rb
Normal file
8
app/serializers/group_order_article_serializer.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class GroupOrderArticleSerializer < ActiveModel::Serializer
|
||||
attributes :id, :order_article_id
|
||||
attributes :quantity, :tolerance, :result, :total_price
|
||||
|
||||
def total_price
|
||||
object.total_price.to_f
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue