Source code for shoop.campaigns.models.basket_line_effects

# This file is part of Shoop.
#
# Copyright (c) 2012-2016, Shoop Ltd. All rights reserved.
#
# This source code is licensed under the AGPLv3 license found in the
# LICENSE file in the root directory of this source tree.
import random

from django.db import models
from django.utils.translation import ugettext_lazy as _

from shoop.core.fields import MoneyValueField
from shoop.core.models import OrderLineType, PolymorphicShoopModel, Product
from shoop.core.order_creator._source import LineSource


[docs]class BasketLineEffect(PolymorphicShoopModel): identifier = None model = None admin_form_class = None campaign = models.ForeignKey("BasketCampaign", related_name='line_effects', verbose_name=_("campaign"))
[docs] def get_discount_lines(self, order_source, original_lines): """ Applies the effect based on given `order_source` :return: amount of discount to accumulate for the product :rtype: Iterable[shoop.core.order_creator.SourceLine] """ raise NotImplementedError("Not implemented!")
[docs]class FreeProductLine(BasketLineEffect): identifier = "free_product_line_effect" model = Product name = _("Free Product(s)") quantity = models.PositiveIntegerField(default=1, verbose_name=_("quantity")) products = models.ManyToManyField(Product, verbose_name=_("product")) @property def description(self): return _("Select product(s) to give free.") @property def values(self): return self.products @values.setter def values(self, values): self.products = values
[docs] def get_discount_lines(self, order_source, original_lines): lines = [] shop = order_source.shop for product in self.products.all(): shop_product = product.get_shop_instance(shop) supplier = shop_product.suppliers.first() if not shop_product.is_orderable( supplier=supplier, customer=order_source.customer, quantity=1): continue line_data = dict( line_id="free_product_%s" % str(random.randint(0, 0x7FFFFFFF)), type=OrderLineType.PRODUCT, quantity=self.quantity, shop=shop, text=("%s (%s)" % (product.name, self.campaign.public_name)), base_unit_price=shop.create_price(0), product=product, sku=product.sku, supplier=supplier, line_source=LineSource.DISCOUNT_MODULE ) lines.append(order_source.create_line(**line_data)) return lines
[docs]class DiscountFromProduct(BasketLineEffect): identifier = "discount_from_product_line_effect" model = Product name = _("Discount from Product") per_line_discount = models.BooleanField( default=True, verbose_name=_("per line discount"), help_text=_("Uncheck this if you want to give discount for each matched product.")) discount_amount = MoneyValueField( default=None, blank=True, null=True, verbose_name=_("discount amount"), help_text=_("Flat amount of discount.")) products = models.ManyToManyField(Product, verbose_name=_("product")) @property def description(self): return _("Select discount amount and products.")
[docs] def get_discount_lines(self, order_source, original_lines): product_ids = self.products.values_list("pk", flat=True) for line in original_lines: if not line.type == OrderLineType.PRODUCT: continue if line.product.pk not in product_ids: continue amnt = (self.discount_amount * line.quantity) if not self.per_line_discount else self.discount_amount line.discount_amount = order_source.create_price(amnt) return []