跳过结账步骤但要进行关联

Tim*_*mer 3 ruby-on-rails spree ruby-on-rails-4

我尝试修改我的CheckoutSteps.我们的客户无法选择送货或付款,因为所有订单都是相同的.(运费为5欧元,订单超过100欧元,然后免费).付款总是Eruopean BankTransfer(我们注意到订单中的客户 - 电子邮件).

所以我从我的订单中删除了州":delivery".跳过该步骤但没有对运输的分配.

我很难在Controller中自动分配它.

我看到正常的assigment是nested_attribute但我很难自己做这些关联.我试图调试控制器和模型,但我找不到正确的关联,并找到一种手动设置它们的方法.参数是

"order"=>{"shipments_attributes"=>{"0"=>{"selected_shipping_rate_id"=>"16", "id"=>"20"}}},
Run Code Online (Sandbox Code Playgroud)

但我找不到任何我可以自己进行调整的代码.如果我们进入结账流程,

Spree::Order.last.shipments
=> []
Run Code Online (Sandbox Code Playgroud)

但是一旦我们进入"交付"页面

Spree::Order.last.shipments
 => #<ActiveRecord::Associations::CollectionProxy [#<Spree::Shipment id: 28, tracking: nil, number: "H43150550345", cost: #<BigDecimal:ff44afc,'0.0',9(18)>, .............
Run Code Online (Sandbox Code Playgroud)

因此运费为0.0

Spree::Order.last.shipments.first.cost.to_f => 0
Run Code Online (Sandbox Code Playgroud)

但是当我们在网页上选择运送方式时,我的运费正确计算.

Spree::Order.last.shipments.first.cost.to_f => 5.0
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,如何在没有user_interaction的情况下以编程方式进行此行为?

我不知道什么事情发生,文档没有帮助.谁能帮我吗?

//编辑

使用了一些模型函数,找到了create_proposed_shipments和shipment.update_amounts.那是"正确的方式"吗?不能让它工作

checkout_flow do
    go_to_state :address
    #go_to_state :delivery #kicked out
    go_to_state :payment, if: ->(order) { 
      order.create_proposed_shipments #create the shipping
      order.shipments.first.update_amounts #"accept" the shipping

      order.payment_required?      
    }
Run Code Online (Sandbox Code Playgroud)

Tim*_*mer 7

好吧,我让它运行得很好,没有碰到流动

第一:您的订单需要决定用户是否可以选择送货方式(或者我们的商店会这样做)

Spree::Order.class_eval do
  def needs_delivery?
    #your logic goes here
    return false
  end
end
Run Code Online (Sandbox Code Playgroud)

然后我们需要我们的订单本身可以选择其运输的功能

Spree::Order.class_eval do        
  def select_default_shipping
    #clone_billing_address #uncomment if user just types in one address
    create_proposed_shipments #creates the shippings
    shipments.first.update_amounts #uses the first shippings
    update_totals #updates the order
  end
end
Run Code Online (Sandbox Code Playgroud)

下一步是在地址之后劫持checkout_controller technicall它将始终进入交付步骤,我们的逻辑在before_delivery中

Spree::CheckoutController.class_eval do     
  def before_delivery
    if @order.needs_delivery?
      #user needs to select shipping, default behaviour
      @order.create_proposed_shipments
    else
      #we select the shipping for the user
      @order.select_default_shipping 
      @order.next #go to next step          
      #default logic for finalizing unless he can't select payment_method
      if @order.completed?
        session[:order_id] = nil
        flash.notice = Spree.t(:order_processed_successfully)
        flash[:commerce_tracking] = "nothing special"
        redirect_to completion_route
      else
        redirect_to checkout_state_path(@order.state)
      end
    end    
  end    
end
Run Code Online (Sandbox Code Playgroud)

花了很多倍,希望节省别人的时间.