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()

[(20, 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), False, 'from django_redis import get_redis_connection\n'), (23, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (24, 'oscarbluelight.offer.models.BluelightCountCondition', 'BluelightCountCondition', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.conditions.BluelightCountCondition"""', 'value': '(2)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (29, 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit', 'BluelightPercentageDiscountBenefit', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (34, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (35, 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), False, 'from oscar.test import factories\n'), (44, 'oscar.test.factories.create_product', 'factories.create_product', ([], {'is_discountable': '(False)'}), False, 'from oscar.test import factories\n'), (66, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (77, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (95, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (100, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (121, 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), False, 'from django_redis import get_redis_connection\n'), (124, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (125, 'oscarbluelight.offer.models.BluelightCountCondition', 'BluelightCountCondition', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.conditions.BluelightCountCondition"""', 'value': '(2)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (130, 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit', 'BluelightPercentageDiscountBenefit', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)', 'max_affected_items': '(1)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (136, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (137, 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), False, 'from oscar.test import factories\n'), (164, 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), False, 'from django_redis import get_redis_connection\n'), (167, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""Mattresses"""'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (168, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""Slippers"""'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (178, 'oscarbluelight.offer.models.BluelightCountCondition.objects.create', 'BluelightCountCondition.objects.create', ([], {'range': 'self.range_mattresses', 'proxy_class': '"""oscarbluelight.offer.conditions.BluelightCountCondition"""', 'value': '(1)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (191, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (192, 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), False, 'from oscar.test import factories\n'), (222, 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), False, 'from django_redis import get_redis_connection\n'), (225, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (231, 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit.objects.create', 'BluelightPercentageDiscountBenefit.objects.create', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (236, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (237, 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), False, 'from oscar.test import factories\n'), (272, 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), False, 'from django_redis import get_redis_connection\n'), (275, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '"""All products"""', 'includes_all_products': '(True)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (281, 'oscarbluelight.offer.models.BluelightPercentageDiscountBenefit.objects.create', 'BluelightPercentageDiscountBenefit.objects.create', ([], {'range': 'range', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""', 'value': '(20)', 'max_affected_items': '(1)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (287, 'unittest.mock.Mock', 'mock.Mock', ([], {}), False, 'from unittest import mock\n'), (288, 'oscar.test.factories.create_basket', 'factories.create_basket', ([], {'empty': '(True)'}), False, 'from oscar.test import factories\n'), (323, 'django_redis.get_redis_connection', 'get_redis_connection', (['"""redis"""'], {}), False, 'from django_redis import get_redis_connection\n'), (327, 'oscarbluelight.offer.models.Range.objects.create', 'Range.objects.create', ([], {'name': '""""""', 'includes_all_products': '(True)'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (328, 'oscarbluelight.offer.models.Benefit.objects.create', 'Benefit.objects.create', ([], {'range': 'rng', 'proxy_class': '"""oscarbluelight.offer.benefits.BluelightPercentageDiscountBenefit"""'}), False, 'from oscarbluelight.offer.models import Range, Benefit, BluelightCountCondition, BluelightValueCondition, BluelightPercentageDiscountBenefit\n'), (39, 'decimal.Decimal', 'D', (['"""0.00"""'], {}), True, 'from decimal import Decimal as D\n'), (45, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (47, 'decimal.Decimal', 'D', (['"""0.00"""'], {}), True, 'from decimal import Decimal as D\n'), (52, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (59, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (68, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (70, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (80, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (88, 'decimal.Decimal', 'D', (['"""1.00"""'], {}), True, 'from decimal import Decimal as D\n'), (103, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (111, 'decimal.Decimal', 'D', (['"""1.00"""'], {}), True, 'from decimal import Decimal as D\n'), (141, 'decimal.Decimal', 'D', (['"""0.00"""'], {}), True, 'from decimal import Decimal as D\n'), (146, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (205, 'decimal.Decimal', 'D', (['"""78.00"""'], {}), True, 'from decimal import Decimal as D\n'), (212, 'decimal.Decimal', 'D', (['"""79.00"""'], {}), True, 'from decimal import Decimal as D\n'), (241, 'decimal.Decimal', 'D', (['"""0.00"""'], {}), True, 'from decimal import Decimal as D\n'), (246, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (255, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (262, 'decimal.Decimal', 'D', (['"""4.00"""'], {}), True, 'from decimal import Decimal as D\n'), (292, 'decimal.Decimal', 'D', (['"""0.00"""'], {}), True, 'from decimal import Decimal as D\n'), (297, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (306, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (313, 'decimal.Decimal', 'D', (['"""4.00"""'], {}), True, 'from decimal import Decimal as D\n'), (54, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (61, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (148, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (155, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (170, 'decimal.Decimal', 'D', (['"""2999.00"""'], {}), True, 'from decimal import Decimal as D\n'), (171, 'decimal.Decimal', 'D', (['"""78.00"""'], {}), True, 'from decimal import Decimal as D\n'), (172, 'decimal.Decimal', 'D', (['"""79.00"""'], {}), True, 'from decimal import Decimal as D\n'), (187, 'decimal.Decimal', 'D', (['"""100.00"""'], {}), True, 'from decimal import Decimal as D\n'), (229, 'decimal.Decimal', 'D', (['"""10.00"""'], {}), True, 'from decimal import Decimal as D\n'), (248, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (257, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (264, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (279, 'decimal.Decimal', 'D', (['"""10.00"""'], {}), True, 'from decimal import Decimal as D\n'), (299, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (308, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (315, 'decimal.Decimal', 'D', (['"""0.2"""'], {}), True, 'from decimal import Decimal as D\n'), (54, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (61, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (148, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (153, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (153, 'decimal.Decimal', 'D', (['"""20.00"""'], {}), True, 'from decimal import Decimal as D\n'), (155, 'decimal.Decimal', 'D', (['"""12.00"""'], {}), True, 'from decimal import Decimal as D\n'), (248, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (257, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (264, 'decimal.Decimal', 'D', (['"""4.00"""'], {}), True, 'from decimal import Decimal as D\n'), (299, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (308, 'decimal.Decimal', 'D', (['"""5.00"""'], {}), True, 'from decimal import Decimal as D\n'), (315, 'decimal.Decimal', 'D', (['"""4.00"""'], {}), True, 'from decimal import Decimal as D\n')]