openbuildings / shipping
向 openbuildings/purchases 包件添加复杂的配送
Requires
- php: ^7.3
- clippings/freezable: ^0.3
- composer/installers: *
- openbuildings/jam: ^0.6
- openbuildings/purchases: ^0.12
Requires (Dev)
- dev-master
- 0.15.0
- 0.14.1
- 0.14.0
- 0.13.0
- 0.12.0
- 0.11.10
- 0.11.9
- 0.11.8
- 0.11.7
- 0.11.6
- 0.11.5
- 0.11.4
- 0.11.3
- 0.11.2
- 0.11.1
- 0.11.0
- 0.11.0-alpha.1
- 0.10.2
- 0.10.1
- 0.10.0
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.1
- 0.8.0
- 0.8.0-rc.4
- 0.8.0-rc.3
- 0.8.0-rc.2
- 0.8.0-rc.1
- 0.7.x-dev
- 0.7.1
- 0.7.0
- 0.7.0-rc.1
- 0.7.0-alpha.1
- 0.6.3
- 0.6.2
- 0.6.1
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.12
- 0.4.11
- 0.4.10
- 0.4.9
- 0.4.8
- 0.4.7
- 0.4.6
- 0.4.5
- 0.4.4
- 0.4.3
- 0.4.2
- 0.4.1
- 0.4.0
- 0.3.19
- 0.3.18
- 0.3.17
- 0.3.16
- 0.3.15
- 0.3.14
- 0.3.13
- 0.3.12
- 0.3.11
- 0.3.10
- 0.3.9
- 0.3.8
- 0.3.7
- 0.3.6
- 0.3.5
- 0.3.4
- 0.3.3
- 0.3.2
- 0.3.1
- 0.3.0
- 0.2.0
- 0.1.6
- 0.1.5
- 0.1.4
- 0.1.3
- 0.1.2
- 0.1.1
- 0.1.0
- dev-dependabot/composer/guzzlehttp/psr7-1.8.5
- dev-upgrade-phpunit9
- dev-dependabot/composer/symfony/http-foundation-4.4.7
- dev-clippings-commission-fix
This package is auto-updated.
Last update: 2024-08-29 04:03:17 UTC
README
使用方法
您想运输的采购项目必须实现 Shippable,例如这样
class Model_Product extends Jam_Model implements Sellable, Shippable { public static function initialize(Jam_Meta $meta) { $meta ->associations(array( 'shipping' => Jam::association('belongsto', array('inverse_of' => 'products')), )) ->fields(array( 'id' => Jam::field('primary'), 'name' => Jam::field('string'), 'currency' => Jam::field('string'), 'price' => Jam::field('price'), )) ->validator('type', 'price', 'quantity', array( 'present' => TRUE )); } // Implement Sellable public function price(Model_Purchase_Item $item) { return $this->price; } // Implement Sellable public function currency() { return $this->currency; } // Implement Shippable // Must return a ``Model_Shipping`` object holding all the data for the shipping public function shipping() { return $this->shipping; } // Implement Shippable // Must return a boolean whether or not the product ships can to that location public function ships_to(Model_Location $location) { return $this->shipping ? $this->shipping->ships_to($location) : FALSE; } } class Model_Purchase_Item_Product extends Kohana_Model_Purchase_Item_Product { public static function initialize(Jam_Meta $meta) { parent::initialize($meta); $meta ->behaviors(array( 'shippable_purchase_item' => Jam::behavior('shippable_purchase_item'), )); } } class Model_Shipping extends Kohana_Model_Shipping { public static function initialize(Jam_Meta $meta) { parent::initialize($meta); $meta ->associations(array( 'products' => Jam::association('hasmany', [ 'inverse_of' => 'shipping', ]), )); } }
此外,您还需要将可运输的采购项目添加到您的采购和品牌采购中
class Model_Brand_Purchase extends Kohana_Model_Brand_Purchase { public static function initialize(Jam_Meta $meta) { parent::initialize($meta); $meta ->behaviors(array( 'shippable_brand_purchase' => Jam::behavior('shippable_brand_purchase'), )); } } class Model_Purchase extends Kohana_Model_Purchase { public static function initialize(Jam_Meta $meta) { parent::initialize($meta); $meta ->behaviors(array( 'shippable_purchase' => Jam::behavior('shippable_purchase'), )); } }
这些行为将为 brand_pruchase 添加 'shipping' 关联,并监听 update_items 事件以添加一个运输采购项目,并监听 filter_items 事件,添加更多筛选标志。
一旦您已将运输数据添加到您的产品中
$post = Jam::find('shipping_method', 'Post'); $europe = Jam::find('location', 'Europe'); $france = Jam::find('location', 'France'); $product->shipping = Jam::create('shipping', array( 'currency' => 'GBP', 'ships_from' => $france, 'groups' => array( // Ships to all of Europe for 20 GBP array('method' => $post, 'location' => $europe, 'price' => 20), // Specifically for France - only 10 GBP array('method' => $post, 'location' => $france, 'price' => 10), ) ));
您就可以开始选择哪些运输适用于每个采购项目。
$brand_purchase = Jam::find('brand_purchase', 1); // If you want to set the informaction explicitly on which purchase_item what shipping_group to use $brand_purchase->build('shipping', array( 'items' => array( array( 'purchase_item' => $brand_purchase->items[0], 'shipping_group' => $brand_purchase->items[0]->reference->shipping()->groups[0], ), ) )); // Or if you want ones selected automatically, based on a preffered shipping method and purchaser location $post = Jam::find('shipping_method', 'Post'); $france = Jam::find('location', 'France'); $brand_purchase_shipping = $brand_purchase->build('shipping', array( 'location' => $france, )); $brand_purchase_shipping->build_items_from($brand_purchase->items, $post);
配置完成后,您现在可以在 purchase / brand_purchase 上调用 update_items()
方法,为 purchase_items 添加一个运输项目。
$brand_purchase->update_items(); echo $brand_purchase->items_count('shipping'); // should return 1
运输组和价格计算
每个运输组有几个属性会影响此物品运输的成本
- 价格 - 这是运输 1 件物品的基础价格。
- 额外项目价格 - 对于多个物品,第二、第三等物品需要此价格,而不是基础价格。
- 折扣阈值 - 只要品牌采购超过此金额,则免费运输
以下是一些示例
如果一个物品的价格为 10,额外项目价格为 6,那么您将支付 10+6+6 的费用,用于 3 件相同的物品。
此外,项目将按运输方式、按 "ships_from" 位置进行分组,因此通过邮寄邮寄的 3 件不同物品将被分组。只有最昂贵的基准价格会被使用,所有其他的价格将使用额外项目价格。所以
Item 1: price 10, additional_item_price 6, quantity: 3
Item 2: price 12, additional_item_price 8, quantity: 2
Total Price will be (12 + 8) + 6 * 3
在搜索国家时,将使用最具体的国家进行计算,因此如果您正在为法国运输,并且您有一个针对欧洲的运输组和一个针对法国的运输组,则将使用第二个。
高级项目拆分
如果您想允许人们为不同的产品使用不同的方法,以下是您可以如何实现的方法
首先,找到所有可以 / 不可以运输到您国家的采购项目
$available = $brand_purchase->items(array('can_ship' => TRUE)); $not_shippable = $brand_purchase->items(array('can_ship' => FALSE));
如果您想更精确,您可以获取可用的项目,但按可用的运输方式分组,这样如果您的采购项目可以通过 邮寄 和 快递 进行运输,而其他项目只能通过 邮寄 进行运输,它们将属于不同的组
$group_shipping_methods = $brand_purchase->group_shipping_methods() foreach ($group_shipping_methods as $group) { foreach ($group->group_shipping_items() as $items) { // Get all the purchase items, shippable to this location by this method. $items->purchase_items; // Calculate the price of these items, provide a total price to remove ones that are discounted based on it. $items->total_price(); // Delivery $items->total_delivery_time(); } }
交货时间
此运输模块提供了广泛的计算交货时间的支持。
Model_Shipping_Group 有 "delivery_time" - 最小 - 最大工作日交付物品。Model_Shipping 有 process_time - 最小 - 最大工作日 "构建" 项。这两个都是 Jam_Ranges,共同表示特定位置的 total_delivery_time。
Model_Shipping 有此接口
$france = Jam::find('locaiton', 'France'); $shipping = $product->shipping(); // To get a Jam_Range object only for the delivery to that location $shipping->delivery_time_for($france); // To get a Jam_Range for delivery + processing for a specific country $shipping->total_delivery_time_for($france);
可运输的采购行为还为 Model_Brand_Purchase 添加了一些用于处理交货时间计算的方法
// Get the Jam_Range object for the delivery time for the brand_purchase $brand_purchase->total_delivery_time(); // Get the Jam_Range object if the dates that the purchase will arraive // This is calculate based on the time the payment was made. If its not yet payed purchase, the current time is used. $brand_purchase->delivery_time_dates();
运输地址
默认情况下,使用采购的账单地址作为运输地址。如果您想更改该地址,您必须更改 shipping_same_as_billing
字段并设置运输地址关联,该关联是相同的 Model_Address 对象。之后,所有计算都将使用 shipping_address 的国家,而不是账单地址。
$purchase = Jam::find('purchase', 1); $purchase->shipping_same_as_billing = FALSE; $purchase->build('shipping_address', array( 'country' => Jam::find('country', 'United Kingdom'), 'line1' => 'Street 1', // ... )); ## License Copyright (c) 2012-2013, OpenBuildings Ltd. Developed by Ivan Kerin as part of [clippings.com](http://clippings.com) Under BSD-3-Clause license, read LICENSE file.