用于 Spree 6 中处理货物送达客户的相关开发:履约单(Spree::Fulfillment,前缀 ful_)表示由某一配送方式从某库存地点送往客户的一批商品。一个购物车或订单按“库存地点 × 配送配置 × 拆分器输出”生成履约单,客户为每张履约单选择配送费率。
核心模型:履约单包含库存地点(sloc_)、履约项(fi_)、配送费率(dr_)与配送方式(dm_)、配送单(dlv_)、运输标签(lbl_)及税费/折扣行。产品关联配送配置(fp_),含起运组(og_)、配送区域(dz_)与区域成员(dzm_)、配送方式及规则(dmrule_)、包裹类型(pkgtype_)。
状态:履约单使用 status 字符串字段,取值 unfulfilled、fulfilled、delivered、canceled,只前进不回退。付款/缺货就绪性不是状态,由 Spree::Fulfillments::Fulfill 在发货时检查,可返回 order_not_paid、backordered_units、insufficient_stock_on_hand、order_draft;工作人员可传 force: true(草稿订单除外)。承运商状态记录在 Spree::Delivery 上。订单通过 order.fulfillment_status 汇总,不要自行写入。
状态转换须调用工作流(通过 DI 键,便于替换):fulfillment_fulfill_workflow、fulfillment_mark_delivered_workflow、fulfillment_cancel_workflow、fulfillment_create_workflow、fulfillment_update_workflow、fulfillment_purchase_label_workflow、delivery_update_tracking_workflow,均带 validate 等钩子。示例: result = Spree.fulfillment_fulfill_workflow.call(fulfillment: fulfillment, items: [{ line_item: line_item, quantity: 1 }], tracking: '1Z999AA10123456784', notify_customer: true, force: false) result.value # 实际发货的履约单;部分发货时是新的拆分履约单
费率可选计算器(算术定价,内置在 Spree::Calculator::Shipping::*)或费率提供者(外部价格,Spree::DeliveryRateProvider::Base 子类);Freight 处理需审核报价;资格限制用 DeliveryMethodRule。金额计算器带货币偏好,货币不匹配则不参与,不换算。
履约提供者(默认 Manual,另有 Digital、Pickup、PickupPoint)负责出站环节,可子类化 Spree::FulfillmentProvider::Base 并实现 create_fulfillment、cancel_fulfillment,承运商可覆盖 generates_labels?、purchase_label 等;在 after_initialize 中注册 Spree.fulfillment_providers << MyProvider。
订单路由与拆分:路由策略默认 Rules,依据渠道的 OrderRoutingRule 行;拆分器默认 [Splitter::DeliveryProfile, Splitter::Backordered],Weight 为可选。注意店铺结算通过 Cart#rebuild_fulfillments! 直接调用 Coordinator,不走路由策略;路由策略在 Order#rebuild_fulfillments! 中运行,且不改动已下单订单的履约单重建。自定义应经工作流钩子或订阅者实现副作用。资料未提供具体价格、收费与效果数据。