Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

strategy.py 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from collections import namedtuple
  2. from decimal import Decimal as D
  3. from . import availability, prices
  4. StockInfo = namedtuple('StockInfo', ['price', 'availability', 'stockrecord'])
  5. class Selector(object):
  6. """
  7. Responsible for returning the appropriate strategy class for a given
  8. user/session.
  9. This can be called in three ways:
  10. 1. Passing a request and user. This is for determining
  11. prices/availability for a normal user browsing the site.
  12. 2. Passing just the user. This is for offline processes that don't
  13. have a request instance but do know which user to determine prices for.
  14. 3. Passing nothing. This is for offline processes that don't
  15. correspond to a specific user. Eg, determining a price to store in
  16. Solr's index.
  17. """
  18. def strategy(self, request=None, user=None, **kwargs):
  19. # Default to the backwards-compatible strategry of picking the fist
  20. # stockrecord.
  21. return FirstStockRecord(request)
  22. class Base(object):
  23. """
  24. Responsible for picking the appropriate pricing and availability wrappers
  25. for a product
  26. """
  27. def __init__(self, request=None):
  28. self.request = request
  29. self.user = None
  30. if request and request.user.is_authenticated():
  31. self.user = request.user
  32. def fetch(self, product, stockrecord=None):
  33. raise NotImplementedError(
  34. "A strategy class must define a fetch method "
  35. "for returning the availability and pricing "
  36. "information."
  37. )
  38. class FirstStockRecord(Base):
  39. """
  40. Always use the first (normally only) stock record for a product
  41. """
  42. def fetch(self, product, stockrecord=None):
  43. """
  44. Return the appropriate product price and availability information for
  45. this session.
  46. """
  47. if stockrecord is None:
  48. try:
  49. stockrecord = product.stockrecords.all()[0]
  50. except IndexError:
  51. return StockInfo(
  52. price=prices.Unavailable(),
  53. availability=availability.Unavailable(),
  54. stockrecord=None)
  55. # If we track stock then back-orders aren't allowed
  56. if not product.get_product_class().track_stock:
  57. availability_policy = availability.Available()
  58. else:
  59. availability_policy = availability.StockRequired(
  60. stockrecord.net_stock_level)
  61. # Assume zero tax
  62. pricing_policy = prices.FixedPrice(
  63. excl_tax=stockrecord.price_excl_tax,
  64. tax=D('0.00'))
  65. return StockInfo(
  66. availability=availability_policy,
  67. price=pricing_policy,
  68. stockrecord=stockrecord)