from decimal import Decimal as D
from django.core import exceptions
from django.test import TestCase
from oscar.test import factories
from oscar.test.basket import add_product, add_products
from django_redis import get_redis_connection
from oscarbluelight.offer.models import (
    Range,
    Benefit,
    BluelightCountCondition,
    BluelightValueCondition,
    BluelightPercentageDiscountBenefit,
)
from unittest import mock


class TestAPercentageDiscountAppliedWithCountCondition(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection("redis")
        conn.flushall()

        range = Range.objects.create(name="All products", includes_all_products=True)
        self.condition = BluelightCountCondition(
            range=range,
            proxy_class="oscarbluelight.offer.conditions.BluelightCountCondition",
            value=2,
        )
        self.benefit = BluelightPercentageDiscountBenefit(
            range=range,
            proxy_class="oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit",
            value=20,
        )
        self.offer = mock.Mock()
        self.basket = factories.create_basket(empty=True)

    def test_applies_correctly_to_empty_basket(self):
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(D("0.00"), result.discount)
        self.assertEqual(0, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_with_no_discountable_products(self):
        product = factories.create_product(is_discountable=False)
        add_product(self.basket, D("12.00"), 2, product=product)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(D("0.00"), result.discount)
        self.assertEqual(0, self.basket.num_items_with_discount)
        self.assertEqual(2, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_matches_condition(self):
        add_product(self.basket, D("12.00"), 2)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(2 * D("12.00") * D("0.2"), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_exceeds_condition(self):
        add_product(self.basket, D("12.00"), 3)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(3 * D("12.00") * D("0.2"), result.discount)
        self.assertEqual(3, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_obeys_max_discount_setting(self):
        self.benefit.max_discount = D("5.00")
        self.benefit.save()
        add_product(self.basket, D("12.00"), 3)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(D("5.00"), result.discount)
        self.assertEqual(3, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_records_reason_for_discount_no_voucher(self):
        self.offer.name = "My Offer Name"
        self.offer.description = "My Offer Description"
        self.offer.get_voucher = mock.Mock()
        self.offer.get_voucher.return_value = None

        add_product(self.basket, D("5.00"))
        # Apply benefit twice to simulate how Applicator will actually do it
        self.benefit.apply(self.basket, self.condition, self.offer)
        self.benefit.apply(self.basket, self.condition, self.offer)

        line = self.basket.all_lines()[0]
        descrs = line.get_discount_descriptions()
        self.assertEqual(len(descrs), 1)
        self.assertEqual(descrs[0].amount, D("1.00"))
        self.assertEqual(descrs[0].offer_name, "My Offer Name")
        self.assertEqual(descrs[0].offer_description, "My Offer Description")
        self.assertIsNone(descrs[0].voucher_name)
        self.assertIsNone(descrs[0].voucher_code)

    def test_records_reason_for_discount_with_voucher(self):
        voucher = mock.Mock()
        voucher.name = "My Voucher"
        voucher.code = "SWEETDEAL"
        self.offer.name = "Offer for Voucher"
        self.offer.description = ""
        self.offer.get_voucher = mock.Mock()
        self.offer.get_voucher.return_value = voucher

        add_product(self.basket, D("5.00"))
        # Apply benefit twice to simulate how Applicator will actually do it
        self.benefit.apply(self.basket, self.condition, self.offer)
        self.benefit.apply(self.basket, self.condition, self.offer)

        line = self.basket.all_lines()[0]
        descrs = line.get_discount_descriptions()
        self.assertEqual(len(descrs), 1)
        self.assertEqual(descrs[0].amount, D("1.00"))
        self.assertEqual(descrs[0].offer_name, "Offer for Voucher")
        self.assertEqual(descrs[0].offer_description, "")
        self.assertEqual(descrs[0].voucher_name, "My Voucher")
        self.assertEqual(descrs[0].voucher_code, "SWEETDEAL")


class TestAPercentageDiscountWithMaxItemsSetAppliedWithCountCondition(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection("redis")
        conn.flushall()

        range = Range.objects.create(name="All products", includes_all_products=True)
        self.condition = BluelightCountCondition(
            range=range,
            proxy_class="oscarbluelight.offer.conditions.BluelightCountCondition",
            value=2,
        )
        self.benefit = BluelightPercentageDiscountBenefit(
            range=range,
            proxy_class="oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit",
            value=20,
            max_affected_items=1,
        )
        self.offer = mock.Mock()
        self.basket = factories.create_basket(empty=True)

    def test_applies_correctly_to_empty_basket(self):
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(D("0.00"), result.discount)
        self.assertEqual(0, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_matches_condition(self):
        add_product(self.basket, D("12.00"), 2)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(1 * D("12.00") * D("0.2"), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_exceeds_condition(self):
        add_products(self.basket, [(D("12.00"), 2), (D("20.00"), 2)])
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(1 * D("12.00") * D("0.2"), result.discount)
        # Should only consume the condition products
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(2, self.basket.num_items_without_discount)


class TestAPercentageDiscountWithMultipleApplicationsWithCountCondition(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection("redis")
        conn.flushall()

        self.range_mattresses = Range.objects.create(name="Mattresses")
        self.range_slippers = Range.objects.create(name="Slippers")

        self.mattress = factories.create_product(title="Mattress", price=D("2999.00"))
        self.slipper1 = factories.create_product(title="Slipper", price=D("78.00"))
        self.slipper2 = factories.create_product(title="Slipper", price=D("79.00"))

        self.range_mattresses.add_product(self.mattress)
        self.range_slippers.add_product(self.slipper1)
        self.range_slippers.add_product(self.slipper2)

        self.condition = BluelightCountCondition.objects.create(
            range=self.range_mattresses,
            proxy_class="oscarbluelight.offer.conditions.BluelightCountCondition",
            value=1,
        )

        self.benefit = BluelightPercentageDiscountBenefit.objects.create(
            range=self.range_slippers,
            proxy_class="oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit",
            value=D("100.00"),
            max_affected_items=1,
        )

        self.offer = mock.Mock()
        self.basket = factories.create_basket(empty=True)

    def test_applies_correctly_to_basket_which_matches_multiple_lines_multiple_times(
        self,
    ):
        # Add two different lines to the basket
        self.basket.add_product(self.mattress, 2)
        self.basket.add_product(self.slipper1, 1)
        self.basket.add_product(self.slipper2, 1)
        # Apply once
        self.assertTrue(self.condition.proxy().is_satisfied(self.offer, self.basket))
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertTrue(result.is_successful)
        self.assertEqual(result.discount, D("78.00"))
        self.assertEqual(self.basket.num_items_with_discount, 2)
        self.assertEqual(self.basket.num_items_without_discount, 2)
        # Apply second time
        self.assertTrue(self.condition.proxy().is_satisfied(self.offer, self.basket))
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertTrue(result.is_successful)
        self.assertEqual(result.discount, D("79.00"))
        self.assertEqual(self.basket.num_items_with_discount, 4)
        self.assertEqual(self.basket.num_items_without_discount, 0)
        # Can't apply a third time because the condition is no longer satisfied
        self.assertFalse(self.condition.proxy().is_satisfied(self.offer, self.basket))


class TestAPercentageDiscountAppliedWithValueCondition(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection("redis")
        conn.flushall()

        range = Range.objects.create(name="All products", includes_all_products=True)
        self.condition = BluelightValueCondition.objects.create(
            range=range,
            proxy_class="oscarbluelight.offer.conditions.BluelightValueCondition",
            value=D("10.00"),
        )
        self.benefit = BluelightPercentageDiscountBenefit.objects.create(
            range=range,
            proxy_class="oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit",
            value=20,
        )
        self.offer = mock.Mock()
        self.basket = factories.create_basket(empty=True)

    def test_applies_correctly_to_empty_basket(self):
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(D("0.00"), result.discount)
        self.assertEqual(0, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_matches_condition(self):
        add_product(self.basket, D("5.00"), 2)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(2 * D("5.00") * D("0.2"), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_exceeds_condition_but_matches_on_boundary(
        self,
    ):
        add_product(self.basket, D("5.00"), 3)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(3 * D("5.00") * D("0.2"), result.discount)
        self.assertEqual(3, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_exceeds_condition(self):
        add_product(self.basket, D("4.00"), 3)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(3 * D("4.00") * D("0.2"), result.discount)
        self.assertEqual(3, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)


class TestAPercentageDiscountWithMaxItemsSetAppliedWithValueCondition(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection("redis")
        conn.flushall()

        range = Range.objects.create(name="All products", includes_all_products=True)
        self.condition = BluelightValueCondition.objects.create(
            range=range,
            proxy_class="oscarbluelight.offer.conditions.BluelightValueCondition",
            value=D("10.00"),
        )
        self.benefit = BluelightPercentageDiscountBenefit.objects.create(
            range=range,
            proxy_class="oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit",
            value=20,
            max_affected_items=1,
        )
        self.offer = mock.Mock()
        self.basket = factories.create_basket(empty=True)

    def test_applies_correctly_to_empty_basket(self):
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(D("0.00"), result.discount)
        self.assertEqual(0, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_matches_condition(self):
        add_product(self.basket, D("5.00"), 2)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(1 * D("5.00") * D("0.2"), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_exceeds_condition_but_matches_on_boundary(
        self,
    ):
        add_product(self.basket, D("5.00"), 3)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(1 * D("5.00") * D("0.2"), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(1, self.basket.num_items_without_discount)

    def test_applies_correctly_to_basket_which_exceeds_condition(self):
        add_product(self.basket, D("4.00"), 3)
        result = self.benefit.apply(self.basket, self.condition, self.offer)
        self.assertEqual(1 * D("4.00") * D("0.2"), result.discount)
        self.assertEqual(3, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)


class TestAPercentageDiscountBenefit(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection("redis")
        conn.flushall()

    def test_requires_a_benefit_value(self):
        rng = Range.objects.create(name="", includes_all_products=True)
        benefit = Benefit.objects.create(
            range=rng,
            proxy_class="oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit",
        )
        with self.assertRaises(exceptions.ValidationError):
            benefit.clean()

[((558, 587), 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), "('redis')\n", (578, 587), False, 'from django_redis import get_redis_connection\n'), ((629, 698), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), "(name='All products', includes_all_products=True)\n", (649, 698), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((724, 845), 'oscarbluelight.offer.models.BluelightCountCondition', 'BluelightCountCondition', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.conditions.BluelightCountCondition"""', 'value': '(2)'}), "(range=range, proxy_class=\n    'oscarbluelight.offer.conditions.BluelightCountCondition', value=2)\n", (747, 845), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((911, 1057), 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit', 'BluelightPercentageDiscountBenefit', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)'}), "(range=range, proxy_class=\n    'oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit',\n    value=20)\n", (945, 1057), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((1117, 1128), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (1126, 1128), False, 'from unittest import mock\n'), ((1151, 1186), 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), '(empty=True)\n', (1174, 1186), False, 'from oscar.test import factories\n'), ((1602, 1649), 'oscar.test.factories.create_product', 'factories.create_product', ([], {'is_discountable': '(False)'}), '(is_discountable=False)\n', (1626, 1649), False, 'from oscar.test import factories\n'), ((2862, 2871), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (2863, 2871), True, 'from decimal import Decimal as D\n'), ((3402, 3413), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (3411, 3413), False, 'from unittest import mock\n'), ((4233, 4244), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (4242, 4244), False, 'from unittest import mock\n'), ((4431, 4442), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (4440, 4442), False, 'from unittest import mock\n'), ((5339, 5368), 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), "('redis')\n", (5359, 5368), False, 'from django_redis import get_redis_connection\n'), ((5410, 5479), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), "(name='All products', includes_all_products=True)\n", (5430, 5479), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((5505, 5626), 'oscarbluelight.offer.models.BluelightCountCondition', 'BluelightCountCondition', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.conditions.BluelightCountCondition"""', 'value': '(2)'}), "(range=range, proxy_class=\n    'oscarbluelight.offer.conditions.BluelightCountCondition', value=2)\n", (5528, 5626), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((5692, 5860), 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit', 'BluelightPercentageDiscountBenefit', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)', 'max_affected_items': '(1)'}), "(range=range, proxy_class=\n    'oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit',\n    value=20, max_affected_items=1)\n", (5726, 5860), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((5932, 5943), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (5941, 5943), False, 'from unittest import mock\n'), ((5966, 6001), 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), '(empty=True)\n', (5989, 6001), False, 'from oscar.test import factories\n'), ((7342, 7371), 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), "('redis')\n", (7362, 7371), False, 'from django_redis import get_redis_connection\n'), ((7429, 7468), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""Mattresses"""'}), "(name='Mattresses')\n", (7449, 7468), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((7499, 7536), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""Slippers"""'}), "(name='Slippers')\n", (7519, 7536), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((7987, 8142), 'oscarbluelight.offer.models.BluelightCountCondition.objects.create', 'BluelightCountCondition.objects.create', ([], {'range': 'self.range_mattresses', 'proxy_class': '"""oscarbluelight.offer.conditions.BluelightCountCondition"""', 'value': '(1)'}), "(range=self.range_mattresses,\n    proxy_class='oscarbluelight.offer.conditions.BluelightCountCondition',\n    value=1)\n", (8025, 8142), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((8485, 8496), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (8494, 8496), False, 'from unittest import mock\n'), ((8519, 8554), 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), '(empty=True)\n', (8542, 8554), False, 'from oscar.test import factories\n'), ((9999, 10028), 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), "('redis')\n", (10019, 10028), False, 'from django_redis import get_redis_connection\n'), ((10070, 10139), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), "(name='All products', includes_all_products=True)\n", (10090, 10139), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((10376, 10537), 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit.objects.create', 'BluelightPercentageDiscountBenefit.objects.create', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)'}), "(range=range, proxy_class=\n    'oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit',\n    value=20)\n", (10425, 10537), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((10597, 10608), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (10606, 10608), False, 'from unittest import mock\n'), ((10631, 10666), 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), '(empty=True)\n', (10654, 10666), False, 'from oscar.test import factories\n'), ((12363, 12392), 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), "('redis')\n", (12383, 12392), False, 'from django_redis import get_redis_connection\n'), ((12434, 12503), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), "(name='All products', includes_all_products=True)\n", (12454, 12503), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((12740, 12923), 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit.objects.create', 'BluelightPercentageDiscountBenefit.objects.create', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)', 'max_affected_items': '(1)'}), "(range=range, proxy_class=\n    'oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit',\n    value=20, max_affected_items=1)\n", (12789, 12923), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((12995, 13006), 'unittest.mock.Mock', 'mock.Mock', ([], {}), '()\n', (13004, 13006), False, 'from unittest import mock\n'), ((13029, 13064), 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), '(empty=True)\n', (13052, 13064), False, 'from oscar.test import factories\n'), ((14728, 14757), 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), "('redis')\n", (14748, 14757), False, 'from django_redis import get_redis_connection\n'), ((14842, 14899), 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '""""""', 'includes_all_products': '(True)'}), "(name='', includes_all_products=True)\n", (14862, 14899), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((14918, 15036), 'oscarbluelight.offer.models.Benefit.objects.create', 'Benefit.objects.create', ([], {'range': 'rng', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""'}), "(range=rng, proxy_class=\n    'oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit')\n", (14940, 15036), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), ((1344, 1353), 'decimal.Decimal', 'D', (['"""0.00"""'], {}), "('0.00')\n", (1345, 1353), True, 'from decimal import Decimal as D\n'), ((1683, 1693), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (1684, 1693), True, 'from decimal import Decimal as D\n'), ((1817, 1826), 'decimal.Decimal', 'D', (['"""0.00"""'], {}), "('0.00')\n", (1818, 1826), True, 'from decimal import Decimal as D\n'), ((2084, 2094), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (2085, 2094), True, 'from decimal import Decimal as D\n'), ((2484, 2494), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (2485, 2494), True, 'from decimal import Decimal as D\n'), ((2933, 2943), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (2934, 2943), True, 'from decimal import Decimal as D\n'), ((3050, 3059), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (3051, 3059), True, 'from decimal import Decimal as D\n'), ((3499, 3508), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (3500, 3508), True, 'from decimal import Decimal as D\n'), ((3900, 3909), 'decimal.Decimal', 'D', (['"""1.00"""'], {}), "('1.00')\n", (3901, 3909), True, 'from decimal import Decimal as D\n'), ((4531, 4540), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (4532, 4540), True, 'from decimal import Decimal as D\n'), ((4932, 4941), 'decimal.Decimal', 'D', (['"""1.00"""'], {}), "('1.00')\n", (4933, 4941), True, 'from decimal import Decimal as D\n'), ((6159, 6168), 'decimal.Decimal', 'D', (['"""0.00"""'], {}), "('0.00')\n", (6160, 6168), True, 'from decimal import Decimal as D\n'), ((6426, 6436), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (6427, 6436), True, 'from decimal import Decimal as D\n'), ((9133, 9143), 'decimal.Decimal', 'D', (['"""78.00"""'], {}), "('78.00')\n", (9134, 9143), True, 'from decimal import Decimal as D\n'), ((9557, 9567), 'decimal.Decimal', 'D', (['"""79.00"""'], {}), "('79.00')\n", (9558, 9567), True, 'from decimal import Decimal as D\n'), ((10824, 10833), 'decimal.Decimal', 'D', (['"""0.00"""'], {}), "('0.00')\n", (10825, 10833), True, 'from decimal import Decimal as D\n'), ((11091, 11100), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (11092, 11100), True, 'from decimal import Decimal as D\n'), ((11528, 11537), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (11529, 11537), True, 'from decimal import Decimal as D\n'), ((11926, 11935), 'decimal.Decimal', 'D', (['"""4.00"""'], {}), "('4.00')\n", (11927, 11935), True, 'from decimal import Decimal as D\n'), ((13222, 13231), 'decimal.Decimal', 'D', (['"""0.00"""'], {}), "('0.00')\n", (13223, 13231), True, 'from decimal import Decimal as D\n'), ((13489, 13498), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (13490, 13498), True, 'from decimal import Decimal as D\n'), ((13926, 13935), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (13927, 13935), True, 'from decimal import Decimal as D\n'), ((14324, 14333), 'decimal.Decimal', 'D', (['"""4.00"""'], {}), "('4.00')\n", (14325, 14333), True, 'from decimal import Decimal as D\n'), ((2218, 2226), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (2219, 2226), True, 'from decimal import Decimal as D\n'), ((2618, 2626), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (2619, 2626), True, 'from decimal import Decimal as D\n'), ((6560, 6568), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (6561, 6568), True, 'from decimal import Decimal as D\n'), ((6982, 6990), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (6983, 6990), True, 'from decimal import Decimal as D\n'), ((7611, 7623), 'decimal.Decimal', 'D', (['"""2999.00"""'], {}), "('2999.00')\n", (7612, 7623), True, 'from decimal import Decimal as D\n'), ((7697, 7707), 'decimal.Decimal', 'D', (['"""78.00"""'], {}), "('78.00')\n", (7698, 7707), True, 'from decimal import Decimal as D\n'), ((7781, 7791), 'decimal.Decimal', 'D', (['"""79.00"""'], {}), "('79.00')\n", (7782, 7791), True, 'from decimal import Decimal as D\n'), ((8406, 8417), 'decimal.Decimal', 'D', (['"""100.00"""'], {}), "('100.00')\n", (8407, 8417), True, 'from decimal import Decimal as D\n'), ((10331, 10341), 'decimal.Decimal', 'D', (['"""10.00"""'], {}), "('10.00')\n", (10332, 10341), True, 'from decimal import Decimal as D\n'), ((11223, 11231), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (11224, 11231), True, 'from decimal import Decimal as D\n'), ((11660, 11668), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (11661, 11668), True, 'from decimal import Decimal as D\n'), ((12058, 12066), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (12059, 12066), True, 'from decimal import Decimal as D\n'), ((12695, 12705), 'decimal.Decimal', 'D', (['"""10.00"""'], {}), "('10.00')\n", (12696, 12705), True, 'from decimal import Decimal as D\n'), ((13621, 13629), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (13622, 13629), True, 'from decimal import Decimal as D\n'), ((14058, 14066), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (14059, 14066), True, 'from decimal import Decimal as D\n'), ((14456, 14464), 'decimal.Decimal', 'D', (['"""0.2"""'], {}), "('0.2')\n", (14457, 14464), True, 'from decimal import Decimal as D\n'), ((2205, 2215), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (2206, 2215), True, 'from decimal import Decimal as D\n'), ((2605, 2615), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (2606, 2615), True, 'from decimal import Decimal as D\n'), ((6547, 6557), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (6548, 6557), True, 'from decimal import Decimal as D\n'), ((6829, 6839), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (6830, 6839), True, 'from decimal import Decimal as D\n'), ((6846, 6856), 'decimal.Decimal', 'D', (['"""20.00"""'], {}), "('20.00')\n", (6847, 6856), True, 'from decimal import Decimal as D\n'), ((6969, 6979), 'decimal.Decimal', 'D', (['"""12.00"""'], {}), "('12.00')\n", (6970, 6979), True, 'from decimal import Decimal as D\n'), ((11211, 11220), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (11212, 11220), True, 'from decimal import Decimal as D\n'), ((11648, 11657), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (11649, 11657), True, 'from decimal import Decimal as D\n'), ((12046, 12055), 'decimal.Decimal', 'D', (['"""4.00"""'], {}), "('4.00')\n", (12047, 12055), True, 'from decimal import Decimal as D\n'), ((13609, 13618), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (13610, 13618), True, 'from decimal import Decimal as D\n'), ((14046, 14055), 'decimal.Decimal', 'D', (['"""5.00"""'], {}), "('5.00')\n", (14047, 14055), True, 'from decimal import Decimal as D\n'), ((14444, 14453), 'decimal.Decimal', 'D', (['"""4.00"""'], {}), "('4.00')\n", (14445, 14453), True, 'from decimal import Decimal as D\n')]