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.

availability.py 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. from django.utils.translation import ugettext_lazy as _
  2. class Base(object):
  3. """
  4. Simple based availability class which defaults to everything being
  5. unavailable.
  6. """
  7. # Standard properties
  8. code = ''
  9. message = ''
  10. lead_time = None
  11. dispatch_date = None
  12. @property
  13. def is_available_to_buy(self):
  14. """
  15. Test if this product is available to be bought.
  16. """
  17. # We test a purchase of a single item
  18. return self.is_purchase_permitted(1)[0]
  19. def is_purchase_permitted(self, quantity):
  20. """
  21. Test whether a proposed purchase is allowed
  22. Should return a boolean and a reason
  23. """
  24. return False, _("Unavailable")
  25. # Common availability policies
  26. class Unavailable(Base):
  27. """
  28. Policy for when a product is unavailable
  29. """
  30. code = 'unavailable'
  31. message = _("Unavailable")
  32. class Available(Base):
  33. """
  34. For when a product is always available, irrespective of stocklevel.
  35. This might be appropriate for a digital product.
  36. """
  37. code = 'available'
  38. message = _("Available")
  39. def is_purchase_permitted(self, quantity):
  40. return True, ""
  41. class StockRequired(Base):
  42. """
  43. Enforce a given stock number
  44. """
  45. CODE_IN_STOCK = 'instock'
  46. CODE_OUT_OF_STOCK = 'outofstock'
  47. def __init__(self, num_available):
  48. self.num_available = num_available
  49. def is_purchase_permitted(self, quantity):
  50. if self.num_available == 0:
  51. return False, _("No stock available")
  52. if quantity > self.num_available:
  53. msg = _("A maximum of %(max)d can be bought") % {
  54. 'max': self.num_available}
  55. return False, msg
  56. return True, ""
  57. @property
  58. def code(self):
  59. if self.num_available > 0:
  60. return self.CODE_IN_STOCK
  61. return self.CODE_OUT_OF_STOCK
  62. @property
  63. def message(self):
  64. if self.num_available > 0:
  65. return _("In stock (%d available)") % self.num_available
  66. return _("Not available")
  67. class DelegateToStockRecord(Base):
  68. """
  69. An availability class which delegates all calls to the
  70. stockrecord itself. This will exercise the deprecate methods on the
  71. stockrecord that call "partner wrapper" classes.
  72. """
  73. def __init__(self, product, stockrecord=None, user=None):
  74. self.product = product
  75. self.stockrecord = stockrecord
  76. self.user = user
  77. @property
  78. def is_available_to_buy(self):
  79. if self.stockrecord is None:
  80. return False
  81. if not self.product.get_product_class().track_stock:
  82. return True
  83. return self.stockrecord.is_available_to_buy
  84. def is_purchase_permitted(self, quantity):
  85. return self.stockrecord.is_purchase_permitted(
  86. self.user, quantity, self.product)
  87. @property
  88. def code(self):
  89. return self.stockrecord.availability_code
  90. @property
  91. def message(self):
  92. return self.stockrecord.availability
  93. @property
  94. def lead_time(self):
  95. return self.stockrecord.lead_time
  96. @property
  97. def dispatch_date(self):
  98. return self.stockrecord.dispatch_date