Exemplo n.º 1
0
def test_customer_usage_limit(rf):
    default_price = 10
    request, product = _init_test_for_product_without_basket(rf, default_price)
    shop = request.shop
    customers = []
    for x in range(3):
        customers.append(factories.create_random_company(shop=shop))

    discount_percentage = 0.20
    coupon = CouponCode.objects.create(code="sUpErAle", active=True, usage_limit_customer=2)
    coupon.shops = [request.shop]
    discount = Discount.objects.create(
        active=True, product=product, coupon_code=coupon, discount_percentage=discount_percentage)
    discount.shops.add(request.shop)

    # Order product twice for each customer
    for customer in customers:
        for y in range(2):
            _create_order(request, customer, coupon, product, request.shop.create_price(8))

    assert coupon.usages.count() == 6  # Each customer 2 orders

    # Any of the customers created shouldn't be allowed to
    # order more with this coupon code.
    for customer in customers:
        assert not CouponCode.is_usable(shop, coupon, customer)

    # New customer should still be able to order some
    new_customer = factories.create_random_person()
    assert CouponCode.is_usable(shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(8))

    assert coupon.usages.count() == 7

    # Set usage limit and the new customer shouldn't be able to use the code
    coupon.usage_limit = 7
    coupon.save()
    assert not CouponCode.is_usable(request.shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(default_price))
    assert coupon.usages.count() == 7

    # One of the customer got refund
    refunded_customer = customers[0]
    order = refunded_customer.customer_orders.first()
    coupon_code_modifier = CouponCodeModule()
    coupon_code_modifier.clear_codes(order)

    assert coupon.usages.count() == 6

    # New customer still doesn't  able to create coupon
    new_customer = factories.create_random_person()
    assert CouponCode.is_usable(shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(8))
    assert coupon.usages.count() == 7
Exemplo n.º 2
0
def test_customer_usage_limit(rf):
    default_price = 10
    request, product = _init_test_for_product_without_basket(rf, default_price)
    shop = request.shop
    customers = []
    for x in range(3):
        customers.append(factories.create_random_company(shop=shop))

    discount_percentage = 0.20
    coupon = CouponCode.objects.create(code="sUpErAle", active=True, usage_limit_customer=2)
    coupon.shops = [request.shop]
    discount = Discount.objects.create(
        active=True, product=product, coupon_code=coupon, discount_percentage=discount_percentage)
    discount.shops.add(request.shop)

    # Order product twice for each customer
    for customer in customers:
        for y in range(2):
            _create_order(request, customer, coupon, product, request.shop.create_price(8))

    assert coupon.usages.count() == 6  # Each customer 2 orders

    # Any of the customers created shouldn't be allowed to
    # order more with this coupon code.
    for customer in customers:
        assert not CouponCode.is_usable(shop, coupon, customer)

    # New customer should still be able to order some
    new_customer = factories.create_random_person()
    assert CouponCode.is_usable(shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(8))

    assert coupon.usages.count() == 7

    # Set usage limit and the new customer shouldn't be able to use the code
    coupon.usage_limit = 7
    coupon.save()
    assert not CouponCode.is_usable(request.shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(default_price))
    assert coupon.usages.count() == 7

    # One of the customer got refund
    refunded_customer = customers[0]
    order = refunded_customer.customer_orders.first()
    coupon_code_modifier = CouponCodeModule()
    coupon_code_modifier.clear_codes(order)

    assert coupon.usages.count() == 6

    # New customer still doesn't  able to create coupon
    new_customer = factories.create_random_person()
    assert CouponCode.is_usable(shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(8))
    assert coupon.usages.count() == 7
Exemplo n.º 3
0
    def discount_price(self, context, product, price_info):
        shop = context.shop
        basket = getattr(context, "basket", None)
        potential_discounts = get_potential_discounts_for_product(
            context,
            product).values_list("discounted_price_value",
                                 "discount_amount_value",
                                 "discount_percentage", "coupon_code__code")

        discounted_prices = []
        for discounted_price_value, discount_amount_value, discount_percentage, coupon_code in potential_discounts:
            if basket and coupon_code and not CouponCode.is_usable(
                    shop, coupon_code, customer=basket.customer):
                # TODO: Revise! This will cause some queries. Are do we want those? Maybe some cache for this check?
                # Maybe somewhere we should just remove coupon codes that is not usable from basket all together?
                continue

            if discounted_price_value:  # Applies the new product price per item
                discounted_prices.append(
                    min(
                        price_info.price,
                        max(
                            shop.create_price(discounted_price_value) *
                            price_info.quantity, shop.create_price(0))))

            if discount_amount_value:  # Discount amount value per item
                discounted_prices.append(
                    max(
                        price_info.price -
                        shop.create_price(discount_amount_value) *
                        price_info.quantity, shop.create_price(0)))

            if discount_percentage:  # Discount percentage per item
                discounted_prices.append(
                    max(
                        price_info.price -
                        price_info.price * discount_percentage,
                        shop.create_price(0)))

        if discounted_prices:
            minimum_price_values = list(
                ShopProduct.objects.filter(product_id=product.pk,
                                           shop=shop).values_list(
                                               "minimum_price_value",
                                               flat=True))

            minimum_price_value = minimum_price_values[
                0] if minimum_price_values else 0

            price_info.price = max(
                min(discounted_prices),
                shop.create_price(minimum_price_value or 0)
                or shop.create_price(0))

        price_expiration = get_price_expiration(context, product)
        if price_expiration and (not price_info.expires_on
                                 or price_expiration < price_info.expires_on):
            price_info.expires_on = price_expiration

        return price_info
Exemplo n.º 4
0
    def discount_price(self, context, product, price_info):
        shop = context.shop
        basket = getattr(context, "basket", None)
        potential_discounts = get_potential_discounts_for_product(context, product).values_list(
            "discounted_price_value", "discount_amount_value", "discount_percentage", "coupon_code__code"
        )

        discounted_prices = []
        for discounted_price_value, discount_amount_value, discount_percentage, coupon_code in potential_discounts:
            if basket and coupon_code and not CouponCode.is_usable(shop, coupon_code, customer=basket.customer):
                # TODO: Revise! This will cause some queries. Are do we want those? Maybe some cache for this check?
                # Maybe somewhere we should just remove coupon codes that is not usable from basket all together?
                continue

            if discounted_price_value:  # Applies the new product price per item
                discounted_prices.append(
                    min(
                        price_info.price,
                        max(
                            shop.create_price(discounted_price_value) * price_info.quantity,
                            shop.create_price(0)
                        )
                    )
                )

            if discount_amount_value:  # Discount amount value per item
                discounted_prices.append(
                    max(
                        price_info.price - shop.create_price(discount_amount_value) * price_info.quantity,
                        shop.create_price(0)
                    )
                )

            if discount_percentage:  # Discount percentage per item
                discounted_prices.append(
                    max(
                        price_info.price - price_info.price * discount_percentage,
                        shop.create_price(0)
                    )
                )

        if discounted_prices:
            product_id = (product if isinstance(product, six.integer_types) else product.pk)
            minimum_price_values = list(ShopProduct.objects.filter(
                product_id=product_id, shop=shop).values_list("minimum_price_value", flat=True))

            minimum_price_value = minimum_price_values[0] if minimum_price_values else 0

            price_info.price = max(
                min(discounted_prices),
                shop.create_price(minimum_price_value or 0) or shop.create_price(0)
            )

        price_expiration = get_price_expiration(context, product)
        if price_expiration and (not price_info.expires_on or price_expiration < price_info.expires_on):
            price_info.expires_on = price_expiration

        return price_info
Exemplo n.º 5
0
def test_usage_limit(rf):
    default_price = 10
    request, product, basket = _init_test_for_product_with_basket(rf, default_price)

    discounted_price = 4
    coupon_code = "TEST!2"
    shop = request.shop
    coupon = CouponCode.objects.create(code=coupon_code, active=True)
    coupon.shops = [shop]
    discount = Discount.objects.create(
        active=True, product=product, coupon_code=coupon, discounted_price_value=discounted_price)
    discount.shops.add(request.shop)

    # Can not use coupon code that does not exist
    assert not CouponCode.is_usable(shop, "SIMO", basket.customer)

    # The coupon code should be usable
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Can not add coupon code that is not active
    coupon.active = False
    coupon.save()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert not coupon.can_use_code(shop, basket.customer)

    # Re-activate coupon code
    coupon.active = True
    coupon.save()
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Can not use coupon code that is not attached
    discount.coupon_code = None
    discount.save()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)

    # Re-attach discount
    discount.coupon_code = coupon
    discount.save()
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)

    # Coupon code needs to be attached to current shop
    shop2 = factories.get_shop(prices_include_tax=True)
    assert not CouponCode.is_usable(shop2, coupon_code, basket.customer)
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)

    coupon.shops.clear()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert not coupon.can_use_code(shop, basket.customer)
    coupon.shops = [shop]
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Coupon code not yet added to basket even if it is usable
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    basket.add_code(coupon)
    assert product.get_price_info(request).price == request.shop.create_price(discounted_price)

    order = factories.create_random_order()

    for x in range(50):
        coupon.use(order)

    assert coupon.usage_limit is None
    assert coupon.usages.count() == 50
    assert product.get_price_info(request).price == request.shop.create_price(discounted_price)

    # Set coupon usage limit 50
    coupon.usage_limit = 50
    coupon.save()

    assert not CouponCode.is_usable(shop, coupon.code, order.customer)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    # Increase limit by 5
    coupon.usage_limit = 55
    coupon.save()

    for x in range(5):
        assert product.get_price_info(request).price == request.shop.create_price(discounted_price)
        coupon.use(order)

    assert coupon.usages.count() == 55
    assert not CouponCode.is_usable(shop, coupon.code, order.customer)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
Exemplo n.º 6
0
def test_usage_limit(rf):
    default_price = 10
    request, product, basket = _init_test_for_product_with_basket(rf, default_price)

    discounted_price = 4
    coupon_code = "TEST!2"
    shop = request.shop
    coupon = CouponCode.objects.create(code=coupon_code, active=True)
    coupon.shops = [shop]
    discount = Discount.objects.create(
        active=True, product=product, coupon_code=coupon, discounted_price_value=discounted_price)
    discount.shops.add(request.shop)

    # Can not use coupon code that does not exist
    assert not CouponCode.is_usable(shop, "SIMO", basket.customer)

    # The coupon code should be usable
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Can not add coupon code that is not active
    coupon.active = False
    coupon.save()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert not coupon.can_use_code(shop, basket.customer)

    # Re-activate coupon code
    coupon.active = True
    coupon.save()
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Can not use coupon code that is not attached
    discount.coupon_code = None
    discount.save()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)

    # Re-attach discount
    discount.coupon_code = coupon
    discount.save()
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)

    # Coupon code needs to be attached to current shop
    shop2 = factories.get_shop(prices_include_tax=True)
    assert not CouponCode.is_usable(shop2, coupon_code, basket.customer)
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)

    coupon.shops.clear()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert not coupon.can_use_code(shop, basket.customer)
    coupon.shops = [shop]
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Coupon code not yet added to basket even if it is usable
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    basket.add_code(coupon)
    assert product.get_price_info(request).price == request.shop.create_price(discounted_price)

    order = factories.create_random_order()

    for x in range(50):
        coupon.use(order)

    assert coupon.usage_limit is None
    assert coupon.usages.count() == 50
    assert product.get_price_info(request).price == request.shop.create_price(discounted_price)

    # Set coupon usage limit 50
    coupon.usage_limit = 50
    coupon.save()

    assert not CouponCode.is_usable(shop, coupon.code, order.customer)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    # Increase limit by 5
    coupon.usage_limit = 55
    coupon.save()

    for x in range(5):
        assert product.get_price_info(request).price == request.shop.create_price(discounted_price)
        coupon.use(order)

    assert coupon.usages.count() == 55
    assert not CouponCode.is_usable(shop, coupon.code, order.customer)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)