Beispiel #1
0
class BaseOrderItem(models.Model):
    """
    A line Item for an order.
    """

    order = models.ForeignKey(get_model_string('Order'),
                              related_name='items',
                              verbose_name=_('Order'))
    product_reference = models.CharField(max_length=255,
                                         verbose_name=_('Product reference'))
    product_name = models.CharField(max_length=255,
                                    null=True,
                                    blank=True,
                                    verbose_name=_('Product name'))
    product = models.ForeignKey(get_model_string('Product'),
                                verbose_name=_('Product'),
                                null=True,
                                blank=True,
                                **f_kwargs)
    unit_price = CurrencyField(verbose_name=_('Unit price'))
    quantity = models.IntegerField(verbose_name=_('Quantity'))
    line_subtotal = CurrencyField(verbose_name=_('Line subtotal'))
    line_total = CurrencyField(verbose_name=_('Line total'))

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Order item')
        verbose_name_plural = _('Order items')

    def save(self, *args, **kwargs):
        if not self.product_name and self.product:
            self.product_name = self.product.get_name()
        super(BaseOrderItem, self).save(*args, **kwargs)
Beispiel #2
0
class BaseCartItem(models.Model):
    """
    This is a holder for the quantity of items in the cart and, obviously, a
    pointer to the actual Product being purchased :)
    """
    cart = models.ForeignKey(get_model_string('Cart'), related_name="items")

    quantity = models.IntegerField()

    product = models.ForeignKey(get_model_string('Product'))

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Cart item')
        verbose_name_plural = _('Cart items')

    def __init__(self, *args, **kwargs):
        # That will hold extra fields to display to the user
        # (ex. taxes, discount)
        super(BaseCartItem, self).__init__(*args, **kwargs)
        self.extra_price_fields = []  # list of tuples (label, value)
        # These must not be stored, since their components can be changed
        # between sessions / logins etc...
        self.line_subtotal = Decimal('0.0')
        self.line_total = Decimal('0.0')
        self.current_total = Decimal('0.0')  # Used by cart modifiers

    def get_base_unit_price(self, **kwargs):
        """
        Returns products price (provided for extensibility).
        """
        return self.product.get_price()

    def get_base_line_subtotal(self, request):
        """
        Returns base line subtotal (product_unit_price * self.quantity)
        """
        return self.get_base_unit_price(request=request) * self.quantity

    def update(self, request):
        self.extra_price_fields = []  # Reset the price fields
        self.line_subtotal = self.get_base_line_subtotal(request)
        self.current_total = self.line_subtotal

        for modifier in cart_modifiers_pool.get_modifiers_list():
            # We now loop over every registered price modifier,
            # most of them will simply add a field to extra_payment_fields
            modifier.process_cart_item(self, request)

        self.line_total = self.current_total
        return self.line_total
class CartDiscountCode(models.Model):
    """
    Model holds entered discount code for ``Cart``.
    """
    cart = models.ForeignKey(get_model_string('Cart'), editable=False)
    code = models.CharField(_('Discount code'), max_length=30)

    class Meta:
        verbose_name = _('Cart discount code')
        verbose_name_plural = _('Cart discount codes')
class ProductOptionGroupsMixin(models.Model):
    """
    A mixin for product definitions with grouped options
    """
    class Meta(object):
        abstract = True
        verbose_name = _('Product mixin with options from named groups')

    options_groups = models.ManyToManyField(get_model_string(
        'OptionGroup', namespace='shop_optiongroups'),
                                            blank=True,
                                            null=True)
Beispiel #5
0
class ProductTextOptionsMixin(models.Model):
    """
    A mixin for product definitions with text options
    """
    class Meta(object):
        abstract = True
        verbose_name = _('Product mixin with customizable text options')

    text_options = models.ManyToManyField(get_model_string(
        'TextOption', 'shop_textoptions'),
                                          blank=True,
                                          null=True)
Beispiel #6
0
class Price(models.Model):
    """
    A product price
    """

    product = models.ForeignKey(get_model_string('Product'))
    currency = models.ForeignKey(Currency)
    price = models.DecimalField(max_digits=12, decimal_places=4)

    def __unicode__(self):
        price = self.currency.format(self.price)
        return u' '.join([self.currency.before, price,
                          self.currency.after]).strip()
Beispiel #7
0
class CartDiscountCode(models.Model):
    """
    Model holds entered discount code for ``Cart``.
    """
    cart = models.ForeignKey(get_model_string('Cart'), editable=False)
    code = models.CharField(_('Discount code'), max_length=30)

    class Meta:
        verbose_name = _('Cart discount code')
        verbose_name_plural = _('Cart discount codes')

    def clean_fields(self, *args, **kwargs):
        super(CartDiscountCode, self).clean_fields(*args, **kwargs)
        if not DiscountBase.objects.active(code=self.code):
            msg = _('Discount code is invalid or expired.')
            raise ValidationError({'code': [msg]})