如何创建自定义运费 - Spree

How to create custom shipping costs - Spree

我拥有的是一个具有多个不同用户角色的网站。通常只有管理员和用户。我有多个针对不同的用户(零售、贸易等)。

客户想要的是每件产品都有单独的运费。实际成本因用户而异(因此贸易运费可能为 8 美元,而零售为 10 美元)。如果选择了多个产品,第一个产品将收取 100% 的运费,每增加一个产品将收取 50% 的运费。此价格因客户送货地点而异。它还根据项目的类别而有所不同(例如,他们有座位类别和鱼箱类别。座位类别可能是 15 美元,鱼箱可能是 17 美元。

我的想法是每个类别都有自己的运输类别,然后运输方式就是地点。这可以正常工作,但棘手的部分是如何根据登录的用户进行调整。我得到的价格与零售运输和贸易运输之间的差异一致(贸易运输始终占零售运输的 80%)。

基本上,如果我能找到计算运费的地方,那就太好了。这样我就可以测试用户是否是贸易客户并将值更改为实际值 * .80,否则该值是正常的。

如果你们中有人能抽出时间帮助我解决这个问题,我将不胜感激。

Basically, what would be great is if I could find out where the shipping calculation is done.

计算在 Spree::Calculator::Shipping 类 中完成(FlatRate、'PerItem` 等)- 检查 source.

您可能想要自定义计算器(或修饰现有方法),因此在 models/spree/calculator/shipping/my_custom_method.rb 中添加文件:

module Spree
  module Calculator::Shipping
    class MyCustomMethod < ShippingCalculator
      preference :amount, :decimal, default: 0
      preference :something_i_need, :string, default: :foo #and so on, those preferences will be ready to set/change in admin panel

      def self.description
        Spree.t(:my_custom_method) # just a label
      end

      # here is where magic happens
      def compute_package(package)
        package.order.shipment_total
      end

    end
  end
end

如您所见,正在 package 对象上调用方法 compute_package,该对象有几个有用的方法 (source),但您可以直接调用 package.order 来获取所有line_itemsshipments、订单的 user 以及计算有效金额所需的所有事项。

如果你想创建新方法,不要忘记注册它,这样它就会出现在管理面板中,这样你就可以更改设置 - 当然,如果你愿意,你可以通过编程方式进行:

initializers/shipping_methods.rb:

 Rails.application.config.spree.calculators.shipping_methods << Spree::Calculator::Shipping::MyCustomMethod

好的,这就是我目前所知道的。

在app/models/spree/calculator/shipping/per_item.rb (我从 \vendor\bundle\ruby.9.1\gems\spree_core-2.4.7\app\models\spree\calculator\shipping\per_item.rb 复制的 Spree 标准模型)

require_dependency spree/shipping_calculator

module Spree
  module Calculator::Shipping
    class PerItem < ShippingCalculator
    preference :amount, :decimal, default: 0
    preference :currency, :string, default: ->{ Spree::Config[:currency] }

  def self.description
    Spree.t(:shipping_flat_rate_per_item)
  end

  def compute_package(package)
    if package.contents.sum(&:quantity) > 1
      compute_from_multiple(package.contents.sum(&:quantity))
    else
      compute_from_single(package.contents.sum(&:quantity))
    end
  end

  def compute_from_multiple(quantity)
    (self.preferred_amount / 2) + ((self.preferred_amount * quantity) / 2
  end

  def compute_from_single(quantity)
    self.preferred_amount * quantity
  end

end

这将测试购物车中的商品数量,如果超过 1 件,它会给一件商品 100% 的运费,其余的 50%。

我现在想不通的是如何访问当前用户。

例如

    if current_spree_user.has_spree_role?("admin")
      (self.preferred_amount / 2) + ((self.preferred_amount * quantity) / 2)
    else
      ((self.preferred_amount / 2) + ((self.preferred_amount * quantity) / 2)) * 0.87
    end

这给出了一个错误:

 undefined local variable or method `spree_current_user'

有谁知道如何在模型中检查当前用户???