Files
openfoodnetwork/app/services/order_cycle_form.rb
Cillian O'Ruanaidh fc4f951a1a Only require OrderCycleShippingMethod records if people want to override the default shipping methods
It makes things much simpler if we return all shipping methods by default without needing OrderCycleShippingMethod records to be added to the database.

Co-authored-by: Maikel <maikel@email.org.au>
2022-09-30 13:13:39 +01:00

124 lines
3.5 KiB
Ruby

# frozen_string_literal: true
require 'open_food_network/permissions'
require 'open_food_network/order_cycle_form_applicator'
require 'order_management/subscriptions/proxy_order_syncer'
class OrderCycleForm
def initialize(order_cycle, order_cycle_params, user)
@order_cycle = order_cycle
@order_cycle_params = order_cycle_params
@user = user
@permissions = OpenFoodNetwork::Permissions.new(user)
@schedule_ids = order_cycle_params.delete(:schedule_ids)
@preferred_shipping_method_ids = order_cycle_params.delete(:preferred_shipping_method_ids)
end
def save
schedule_ids = build_schedule_ids
order_cycle.assign_attributes(order_cycle_params)
return false unless order_cycle.valid?
order_cycle.transaction do
order_cycle.save!
order_cycle.schedule_ids = schedule_ids
order_cycle.save!
apply_exchange_changes
attach_preferred_shipping_methods
sync_subscriptions
true
end
rescue ActiveRecord::RecordInvalid => e
add_exception_to_order_cycle_errors(e)
false
end
private
attr_accessor :order_cycle, :order_cycle_params, :user, :permissions
def add_exception_to_order_cycle_errors(exception)
error = exception.message.split(":").last.strip
order_cycle.errors.add(:base, error) if !order_cycle.errors.to_a.include?(error)
end
def apply_exchange_changes
return if exchanges_unchanged?
OpenFoodNetwork::OrderCycleFormApplicator.new(order_cycle, user).go!
end
def attach_preferred_shipping_methods
return if @preferred_shipping_method_ids.nil?
order_cycle.reload # so outgoing exchanges are up-to-date for shipping method validations
order_cycle.preferred_shipping_method_ids = preferred_shipping_method_ids
order_cycle.save!
end
def exchanges_unchanged?
[:incoming_exchanges, :outgoing_exchanges].all? do |direction|
order_cycle_params[direction].nil?
end
end
def preferred_shipping_method_ids
@preferred_shipping_method_ids = @preferred_shipping_method_ids.reject(&:blank?).map(&:to_i)
if order_cycle.attachable_shipping_methods.map(&:id).sort == @preferred_shipping_method_ids.sort
@preferred_shipping_method_ids = []
end
@preferred_shipping_method_ids
end
def schedule_ids?
@schedule_ids.present?
end
def build_schedule_ids
return unless schedule_ids?
result = existing_schedule_ids
result |= (requested_schedule_ids & permitted_schedule_ids) # Add permitted and requested
result -= ((result & permitted_schedule_ids) - requested_schedule_ids) # Remove permitted but not requested
result
end
def sync_subscriptions
return unless schedule_ids?
return unless schedule_sync_required?
OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscriptions_to_sync).sync!
end
def schedule_sync_required?
removed_schedule_ids.any? || new_schedule_ids.any?
end
def subscriptions_to_sync
Subscription.where(schedule_id: removed_schedule_ids + new_schedule_ids)
end
def requested_schedule_ids
@schedule_ids.map(&:to_i)
end
def permitted_schedule_ids
Schedule.where(id: requested_schedule_ids | existing_schedule_ids)
.merge(permissions.editable_schedules).pluck(:id)
end
def existing_schedule_ids
@existing_schedule_ids ||= order_cycle.persisted? ? order_cycle.schedule_ids : []
end
def removed_schedule_ids
existing_schedule_ids - order_cycle.schedule_ids
end
def new_schedule_ids
@order_cycle.schedule_ids - existing_schedule_ids
end
end