mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-09 23:06:06 +00:00
This used to happen via an after_save callback in Shipment, which called `order.update!`. That has recently been removed. After changing a shipment's selected shipping rate (shipping method), we need to ensure the order's totals and states are updated. We don't need to update all of the order's adjustments though (see previous commit).
FYI Spree handled this issue like this: 24388485ed, but there are lots of things about that commit that are clearly awful, like: params handling in a model, duplication of Order::Updater logic across the codebase, the Shipment class having responsiblity for knowing which things need to be updated on the order, etc. The result is ultimately the same as what we're doing here though.
125 lines
3.6 KiB
Ruby
125 lines
3.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'open_food_network/scope_variant_to_hub'
|
|
|
|
module Api
|
|
module V0
|
|
class ShipmentsController < Api::V0::BaseController
|
|
respond_to :json
|
|
|
|
before_action :find_order
|
|
before_action :refuse_changing_cancelled_orders, only: [:add, :remove]
|
|
before_action :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
|
|
|
|
def create
|
|
variant = scoped_variant(params[:variant_id])
|
|
quantity = params[:quantity].to_i
|
|
@shipment = get_or_create_shipment(params[:stock_location_id])
|
|
|
|
@order.contents.add(variant, quantity, nil, @shipment)
|
|
|
|
@shipment.refresh_rates
|
|
@shipment.save!
|
|
|
|
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
|
end
|
|
|
|
def update
|
|
authorize! :read, Spree::Shipment
|
|
@shipment = @order.shipments.find_by!(number: params[:id])
|
|
params[:shipment] ||= []
|
|
unlock = params[:shipment].delete(:unlock)
|
|
|
|
if unlock == 'yes'
|
|
@shipment.fee_adjustment.open
|
|
end
|
|
|
|
if @shipment.update(shipment_params)
|
|
@order.updater.update_totals_and_states
|
|
end
|
|
|
|
if unlock == 'yes'
|
|
@shipment.fee_adjustment.close
|
|
end
|
|
|
|
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
|
end
|
|
|
|
def ready
|
|
authorize! :read, Spree::Shipment
|
|
unless @shipment.ready?
|
|
if @shipment.can_ready?
|
|
@shipment.ready!
|
|
else
|
|
render(json: { error: I18n.t(:cannot_ready, scope: "spree.api.shipment") },
|
|
status: :unprocessable_entity) && return
|
|
end
|
|
end
|
|
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
|
end
|
|
|
|
def ship
|
|
authorize! :read, Spree::Shipment
|
|
unless @shipment.shipped?
|
|
@shipment.ship!
|
|
end
|
|
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
|
end
|
|
|
|
def add
|
|
variant = scoped_variant(params[:variant_id])
|
|
quantity = params[:quantity].to_i
|
|
|
|
@order.contents.add(variant, quantity, nil, @shipment)
|
|
@order.recreate_all_fees!
|
|
|
|
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
|
end
|
|
|
|
def remove
|
|
variant = scoped_variant(params[:variant_id])
|
|
quantity = params[:quantity].to_i
|
|
|
|
@order.contents.remove(variant, quantity, @shipment)
|
|
@order.recreate_all_fees!
|
|
@shipment.reload if @shipment.persisted?
|
|
|
|
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
|
end
|
|
|
|
private
|
|
|
|
def find_order
|
|
@order = Spree::Order.find_by!(number: params[:order_id])
|
|
authorize! :read, @order
|
|
end
|
|
|
|
def find_and_update_shipment
|
|
@shipment = @order.shipments.find_by!(number: params[:id])
|
|
@shipment.update(shipment_params)
|
|
@shipment.reload
|
|
end
|
|
|
|
def refuse_changing_cancelled_orders
|
|
render status: :unprocessable_entity if @order.canceled?
|
|
end
|
|
|
|
def scoped_variant(variant_id)
|
|
variant = Spree::Variant.find(variant_id)
|
|
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
|
|
variant
|
|
end
|
|
|
|
def get_or_create_shipment(stock_location_id)
|
|
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
|
|
end
|
|
|
|
def shipment_params
|
|
return {} unless params.has_key? :shipment
|
|
|
|
params.require(:shipment).permit(:tracking, :selected_shipping_rate_id)
|
|
end
|
|
end
|
|
end
|
|
end
|