mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-12-15 00:24:09 +01:00
142 lines
4.6 KiB
Ruby
142 lines
4.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Provides methods for Order
|
|
class Orders::OrderService
|
|
class << self
|
|
include ApplicationHelper
|
|
|
|
ORDERS_PER_PAGE = 20
|
|
|
|
def list(filters, current_user)
|
|
orders = Order.includes(statistic_profile: [user: [:profile]]).where(nil)
|
|
orders = filter_by_user(orders, filters, current_user)
|
|
orders = filter_by_reference(orders, filters, current_user)
|
|
orders = filter_by_state(orders, filters)
|
|
orders = filter_by_period(orders, filters)
|
|
|
|
orders = orders.where.not(state: 'cart') if current_user.member?
|
|
orders = orders_ordering(orders, filters)
|
|
total_count = orders.count
|
|
orders = orders.page(filters[:page] || 1).per(ORDERS_PER_PAGE)
|
|
{
|
|
data: orders,
|
|
page: filters[:page]&.to_i || 1,
|
|
total_pages: orders.page(1).per(ORDERS_PER_PAGE).total_pages,
|
|
page_size: ORDERS_PER_PAGE,
|
|
total_count: total_count
|
|
}
|
|
end
|
|
|
|
def update_state(order, current_user, state, note = nil)
|
|
case state
|
|
when 'in_progress'
|
|
::Orders::SetInProgressService.new.call(order, current_user)
|
|
when 'ready'
|
|
::Orders::OrderReadyService.new.call(order, current_user, note)
|
|
when 'canceled'
|
|
::Orders::OrderCanceledService.new.call(order, current_user)
|
|
when 'delivered'
|
|
::Orders::OrderDeliveredService.new.call(order, current_user)
|
|
when 'refunded'
|
|
::Orders::OrderRefundedService.new.call(order, current_user)
|
|
else
|
|
nil
|
|
end
|
|
|
|
# update in elasticsearch (statistics)
|
|
stat_order = Stats::Order.search(query: { term: { orderId: order.id } })
|
|
sub_type = if state.in?(%w[paid in_progress ready delivered])
|
|
'paid-processed'
|
|
elsif state.in?(%w[payment_failed refunded canceled])
|
|
'aborted'
|
|
end
|
|
|
|
stat_order.map { |s| s.update(subType: sub_type, state: state) } if sub_type.present?
|
|
|
|
order
|
|
end
|
|
|
|
def in_stock?(order, stock_type = 'external')
|
|
order.order_items.each do |item|
|
|
return false if item.orderable.stock[stock_type] < item.quantity || item.orderable.stock[stock_type] < item.orderable.quantity_min
|
|
end
|
|
true
|
|
end
|
|
|
|
def greater_than_quantity_min?(order)
|
|
order.order_items.each do |item|
|
|
return false if item.quantity < item.orderable.quantity_min
|
|
end
|
|
true
|
|
end
|
|
|
|
def item_amount_not_equal?(order)
|
|
order.order_items.each do |item|
|
|
orderable_amount = item.orderable.amount || 0
|
|
return false if item.amount != orderable_amount
|
|
end
|
|
true
|
|
end
|
|
|
|
def all_products_is_active?(order)
|
|
order.order_items.each do |item|
|
|
return false unless item.orderable.is_active
|
|
end
|
|
true
|
|
end
|
|
|
|
def withdrawal_instructions(order)
|
|
res = order&.order_activities&.find_by(activity_type: 'ready')&.note.presence ||
|
|
Setting.get('store_withdrawal_instructions').presence ||
|
|
_t('order.please_contact_FABLAB', FABLAB: Setting.get('fablab_name').presence || 'empty')
|
|
|
|
ActionController::Base.helpers.sanitize(res, tags: %w[p ul li h3 u em strong a], attributes: %w[target rel href])
|
|
end
|
|
|
|
private
|
|
|
|
def filter_by_user(orders, filters, current_user)
|
|
if filters[:user_id]
|
|
statistic_profile_id = current_user.statistic_profile.id
|
|
if (current_user.member? && current_user.id == filters[:user_id].to_i) || current_user.privileged?
|
|
user = User.find(filters[:user_id])
|
|
statistic_profile_id = user.statistic_profile.id
|
|
end
|
|
orders = orders.where(statistic_profile_id: statistic_profile_id)
|
|
elsif current_user.member?
|
|
orders = orders.where(statistic_profile_id: current_user.statistic_profile.id)
|
|
else
|
|
orders = orders.where.not(statistic_profile_id: nil)
|
|
end
|
|
orders
|
|
end
|
|
|
|
def filter_by_reference(orders, filters, current_user)
|
|
return orders unless filters[:reference].present? && current_user.privileged?
|
|
|
|
orders.where(reference: filters[:reference])
|
|
end
|
|
|
|
def filter_by_state(orders, filters)
|
|
return orders if filters[:states].blank?
|
|
|
|
state = filters[:states].split(',')
|
|
orders.where(state: state) unless state.empty?
|
|
end
|
|
|
|
def filter_by_period(orders, filters)
|
|
return orders unless filters[:period_from].present? && filters[:period_to].present?
|
|
|
|
orders.where(created_at: Time.zone.parse(filters[:period_from])..Time.zone.parse(filters[:period_to]).end_of_day)
|
|
end
|
|
|
|
def orders_ordering(orders, filters)
|
|
key, order = filters[:sort]&.split('-')
|
|
key ||= 'created_at'
|
|
order ||= 'desc'
|
|
|
|
orders.order(key => order)
|
|
end
|
|
end
|
|
end
|