| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- from django.utils.translation import ugettext_lazy as _
-
-
- class Base(object):
- """
- Base availability policy.
- """
-
- #: Availability code. This is used for HTML classes
- code = ''
-
- #: A description of the availability of a product. This is shown on the
- #: product detail page. Eg "In stock", "Out of stock" etc
- message = ''
-
- #: When this item should be dispatched
- dispatch_date = None
-
- @property
- def short_message(self):
- """
- A shorter version of the availability message, suitable for showing on
- browsing pages.
- """
- return self.message
-
- @property
- def is_available_to_buy(self):
- """
- Test if this product is available to be bought. This is used for
- validation when a product is added to a user's basket.
- """
- # We test a purchase of a single item
- return self.is_purchase_permitted(1)[0]
-
- def is_purchase_permitted(self, quantity):
- """
- Test whether a proposed purchase is allowed
-
- Should return a boolean and a reason
- """
- return False, _("Unavailable")
-
-
- # Common availability policies
-
-
- class Unavailable(Base):
- """
- Policy for when a product is unavailable
- """
- code = 'unavailable'
- message = _("Unavailable")
-
-
- class Available(Base):
- """
- For when a product is always available, irrespective of stock level.
-
- This might be appropriate for digital products where stock doesn't need to
- be tracked and the product is always available to buy.
- """
- code = 'available'
- message = _("Available")
-
- def is_purchase_permitted(self, quantity):
- return True, ""
-
-
- class StockRequired(Base):
- """
- Allow a product to be bought while there is stock. This policy is
- instantiated with a stock number (``num_available``). It ensures that the
- product is only available to buy while there is stock available.
-
- This is suitable for physical products where back orders (eg allowing
- purchases when there isn't stock available) are not permitted.
- """
- CODE_IN_STOCK = 'instock'
- CODE_OUT_OF_STOCK = 'outofstock'
-
- def __init__(self, num_available):
- self.num_available = num_available
-
- def is_purchase_permitted(self, quantity):
- if self.num_available == 0:
- return False, _("No stock available")
- if quantity > self.num_available:
- msg = _("A maximum of %(max)d can be bought") % {
- 'max': self.num_available}
- return False, msg
- return True, ""
-
- @property
- def code(self):
- if self.num_available > 0:
- return self.CODE_IN_STOCK
- return self.CODE_OUT_OF_STOCK
-
- @property
- def short_message(self):
- if self.num_available > 0:
- return _("In stock")
- return _("Unavailable")
-
- @property
- def message(self):
- if self.num_available > 0:
- return _("In stock (%d available)") % self.num_available
- return _("Unavailable")
-
-
- class DelegateToStockRecord(Base):
- """
- An availability class which delegates all calls to the
- stockrecord itself. This will exercise the deprecated methods on the
- stockrecord that call "partner wrapper" classes.
-
- This is backwards compatible with Oscar<0.6
- """
-
- def __init__(self, product, stockrecord=None, user=None):
- self.product = product
- self.stockrecord = stockrecord
- self.user = user
-
- @property
- def is_available_to_buy(self):
- if self.stockrecord is None:
- return False
- if not self.product.get_product_class().track_stock:
- return True
- return self.stockrecord.is_available_to_buy
-
- def is_purchase_permitted(self, quantity):
- return self.stockrecord.is_purchase_permitted(
- self.user, quantity, self.product)
-
- @property
- def code(self):
- return self.stockrecord.availability_code
-
- @property
- def message(self):
- return self.stockrecord.availability
-
- @property
- def dispatch_date(self):
- return self.stockrecord.dispatch_date
|