You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

how_to_configure_shipping.rst 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. =========================
  2. How to configure shipping
  3. =========================
  4. Shipping can be very complicated. Depending on the domain, a wide variety of
  5. shipping scenarios are found in the wild. For instance, calculation of
  6. shipping costs can depend on:
  7. * Shipping method (e.g., standard, courier)
  8. * Shipping address
  9. * Time of day of order (e.g., if requesting next-day delivery)
  10. * Weight of items in basket
  11. * Customer type (e.g., business accounts get discounted shipping rates)
  12. * Offers and vouchers that give free or discounted shipping
  13. Further complications can arise such as:
  14. * Only making certain shipping methods available to certain customers
  15. * Tax is only applicable in certain situations
  16. Oscar can handle all of these shipping scenarios.
  17. Shipping in Oscar
  18. ~~~~~~~~~~~~~~~~~
  19. Configuring shipping charges requires overriding Oscar's core 'shipping' app
  20. and providing your own ``Repository`` class (see :doc:`/topics/customisation`) that
  21. returns your chosen shipping method instances.
  22. The primary responsibility of the
  23. ``Repository`` class is to provide the available shipping methods for a
  24. particular scenario. This is done via the
  25. :func:`~oscar.apps.shipping.repository.Repository.get_shipping_methods` method,
  26. which returns the shipping methods available to the customer.
  27. This method is called in several places:
  28. * To look up a "default" shipping method so that sample shipping charges can be
  29. shown on the basket detail page.
  30. * To list the available shipping methods on the checkout shipping method page.
  31. * To check the selected shipping method is still available when an order is
  32. submitted.
  33. The ``get_shipping_methods`` method takes the basket, user, shipping address
  34. and request as parameters. These can be used to provide different sets of
  35. shipping methods depending on the circumstances. For instance, you could use
  36. the shipping address to provide international shipping rates if the address is
  37. overseas.
  38. The default behaviour is to return a single free shipping method.
  39. .. note::
  40. Oscar's checkout process includes a page for choosing your shipping method.
  41. If there is only one method available for your basket (as is the default)
  42. then it will be chosen automatically and the user immediately redirected to
  43. the next step.
  44. Custom repositories
  45. -------------------
  46. If the available shipping methods are the same for all customers and shipping
  47. addresses, then override the ``methods`` property of the repository:
  48. .. code-block:: python
  49. from oscar.apps.shipping import repository
  50. from . import methods
  51. class Repository(repository.Repository):
  52. methods = (methods.Standard(), methods.Express())
  53. For more complex logic, override the ``get_available_shipping_methods`` method:
  54. .. code-block:: python
  55. from oscar.apps.shipping import repository
  56. from . import methods
  57. class Repository(repository.Repository):
  58. def get_available_shipping_methods(
  59. self, basket, user=None, shipping_addr=None,
  60. request=None, **kwargs):
  61. methods = (methods.Standard())
  62. if shipping_addr and shipping_addr.country.code == 'GB':
  63. # Express is only available in the UK
  64. methods = (methods.Standard(), methods.Express())
  65. return methods
  66. Note that the ``get_shipping_methods`` method wraps
  67. ``get_available_shipping_methods`` in order to handle baskets that don't
  68. require shipping and to apply shipping discounts.
  69. Shipping methods
  70. ----------------
  71. Shipping methods need to implement a certain API. They need to have the
  72. following properties which define the metadata about the shipping method:
  73. * ``code`` - This is used as an identifier for the shipping method and so should
  74. be unique amongst the shipping methods available in your shop.
  75. * ``name`` - The name of the shipping method. This will be visible to the
  76. customer during checkout.
  77. * ``description`` - An optional description of the shipping method. This can
  78. contain HTML.
  79. Further, each method must implement a ``calculate`` method which accepts the
  80. basket instance as a parameter and returns a ``Price`` instance. Most shipping
  81. methods subclass
  82. :class:`~oscar.apps.shipping.methods.Base`, which stubs this API.
  83. Here's an example:
  84. .. code-block:: python
  85. from oscar.apps.shipping import methods
  86. from oscar.core import prices
  87. class Standard(methods.Base):
  88. code = 'standard'
  89. name = 'Standard shipping (free)'
  90. def calculate(self, basket):
  91. return prices.Price(
  92. currency=basket.currency,
  93. excl_tax=D('0.00'), incl_tax=D('0.00'))
  94. Core shipping methods
  95. ~~~~~~~~~~~~~~~~~~~~~
  96. Oscar ships with several re-usable shipping methods which can be used as-is, or
  97. subclassed and customised:
  98. * :class:`~oscar.apps.shipping.methods.Free` - no shipping charges
  99. * :class:`~oscar.apps.shipping.methods.FixedPrice` - fixed-price shipping charges.
  100. Example usage:
  101. .. code-block:: python
  102. from oscar.apps.shipping import methods
  103. from oscar.core import prices
  104. class Standard(methods.Base):
  105. code = 'standard'
  106. name = 'Standard shipping'
  107. charge_excl_tax = D('5.00')
  108. class Express(methods.Base):
  109. code = 'express'
  110. name = 'Express shipping'
  111. charge_excl_tax = D('10.00')
  112. There is also a weight-based shipping method,
  113. :class:`~oscar.apps.shipping.abstract_models.AbstractWeightBased`
  114. which determines a shipping charge by calculating the weight of a basket's
  115. contents and looking this up in a model-based set of weight bands.