def test_offer_availability_with_max_user_discount(self, discount_type,
                                                    num_prev_orders,
                                                    is_satisfied):
     """
     Verify that enterprise offer with discount type percentage and absolute, condition returns correct result
     based on user limits in the offer.
     """
     benefits = {
         Benefit.PERCENTAGE:
         factories.EnterprisePercentageDiscountBenefitFactory(value=50),
         Benefit.FIXED:
         factories.EnterpriseAbsoluteDiscountBenefitFactory(value=50),
     }
     offer = factories.EnterpriseOfferFactory(
         partner=self.partner,
         benefit=benefits[discount_type],
         max_user_discount=100)
     for _ in range(num_prev_orders):
         order = OrderFactory(user=self.user, status=ORDER.COMPLETE)
         OrderDiscountFactory(order=order, offer_id=offer.id, amount=10)
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         self.condition.enterprise_customer_uuid,
         self.site.siteconfiguration.enterprise_api_url,
         enterprise_customer_catalog_uuid=self.condition.
         enterprise_customer_catalog_uuid,
     )
     self.assertEqual(self.condition.is_satisfied(offer, basket),
                      is_satisfied)
Beispiel #2
0
 def test_max_user_discount_clean_with_refunded_enrollments(self):
     """
     Verify that `clean` for `max_user_discount` and `max_user_applications` does not raise error when total consumed
      discount and total max user applications after refund is still less than the value, and the existing offer
      updates with new per user limit and max user application values.
     """
     current_refund_count = 0
     data = self.generate_data(max_user_applications=3,
                               max_user_discount=300)
     self.mock_specific_enterprise_customer_api(
         data['enterprise_customer_uuid'])
     # create an enterprise offer that can provide max $500 discount and consume $400
     offer = factories.EnterpriseOfferFactory(max_user_applications=5,
                                              max_user_discount=500)
     for _ in range(4):
         order = OrderFactory(user=self.user, status=ORDER.COMPLETE)
         OrderDiscountFactory(order=order, offer_id=offer.id, amount=100)
         # create a refund of $200 so the total consumed discount becomes $200
         if current_refund_count < 2:
             RefundFactory(order=order,
                           user=self.user,
                           status=REFUND.COMPLETE)
             current_refund_count += 1
     # now try to update the offer with max_user_discount set to $300
     # which is still greater than the consumed discount after refund $200
     form = EnterpriseOfferForm(request=self.request,
                                data=data,
                                instance=offer)
     self.assertTrue(form.is_valid())
     offer = form.save()
     self.assertEqual(offer.max_user_applications,
                      data['max_user_applications'])
     self.assertEqual(offer.max_user_discount, data['max_user_discount'])
Beispiel #3
0
    def test_issue_credit_for_enterprise_offer_no_partial_credit(self):
        """
        Test that credit is not issued if not all of the lines in an order are refunded.
        """
        order = self.create_order(user=UserFactory(), multiple_lines=True)

        offer = EnterpriseOfferFactory(partner=PartnerFactory(),
                                       max_discount=150)

        discount = OrderDiscountFactory(order=order,
                                        offer_id=offer.id,
                                        frequency=1,
                                        amount=150)

        offer.record_usage({
            'freq': discount.frequency,
            'discount': discount.amount
        })
        offer.refresh_from_db()
        assert offer.status == ConditionalOffer.CONSUMED
        assert offer.total_discount == 150

        refund = RefundFactory(order=order, user=UserFactory())
        refund.lines.first().delete()

        with mock.patch.object(models,
                               'revoke_fulfillment_for_refund') as mock_revoke:
            mock_revoke.return_value = True
            self.assertTrue(refund.approve())

        offer.refresh_from_db()

        assert offer.status == ConditionalOffer.CONSUMED
        assert offer.total_discount == 150
Beispiel #4
0
    def test_issue_credit_for_enterprise_offer(self):
        """
        Test that enterprise offers are credited for the discounted amount.
        """
        order = self.create_order(user=UserFactory())

        offer = EnterpriseOfferFactory(partner=PartnerFactory(),
                                       max_discount=150)

        discount = OrderDiscountFactory(order=order,
                                        offer_id=offer.id,
                                        frequency=1,
                                        amount=150)

        offer.record_usage({
            'freq': discount.frequency,
            'discount': discount.amount
        })
        offer.refresh_from_db()
        assert offer.status == ConditionalOffer.CONSUMED
        assert offer.total_discount == 150

        refund = RefundFactory(order=order, user=UserFactory())

        with mock.patch.object(models,
                               'revoke_fulfillment_for_refund') as mock_revoke:
            mock_revoke.return_value = True
            self.assertTrue(refund.approve())

        offer.refresh_from_db()

        assert offer.status == ConditionalOffer.OPEN
        assert offer.total_discount == 0
Beispiel #5
0
    def test_generator_queryset_and_annotation(self):
        offer = ConditionalOfferFactory(pk=2)
        OrderDiscountFactory(offer_id=offer.pk, offer_name=offer.name, amount=2, order=create_order())
        OrderDiscountFactory(offer_id=offer.pk, offer_name=offer.name, amount=3, order=create_order())
        # Discount on a deleted offer
        OrderDiscountFactory(offer_id=1, offer_name="Deleted offer", amount=4, order=create_order())
        queryset = OfferReportGenerator().generate()

        self.assertEqual(queryset.count(), 2)
        self.assertEqual(queryset[0]["offer_id"], 2)
        self.assertEqual(queryset[0]["display_offer_name"], offer.name)
        self.assertEqual(queryset[0]["total_discount"], 5)
        self.assertEqual(queryset[0]["offer"], offer.pk)
        self.assertEqual(queryset[1]["offer_id"], 1)
        self.assertEqual(queryset[1]["display_offer_name"], "Deleted offer")
        self.assertEqual(queryset[1]["total_discount"], 4)
        self.assertEqual(queryset[1]["offer"], None)
    def setUp(self):
        """
        Create test data.
        """
        super(UpdateEffectiveContractDiscountTests, self).setUp()

        # Set up orders with a enterprise_customer
        self.enterprise_customer_uuid = '123e4567-e89b-12d3-a456-426655440000'
        self.unit_price = 100
        self.condition = ManualEnrollmentOrderDiscountConditionFactory(
            enterprise_customer_uuid=self.enterprise_customer_uuid
        )
        self.offer = ConditionalOfferFactory(condition=self.condition, id=9999)
        self.order = OrderFactory()
        self.order_discount = OrderDiscountFactory(offer_id=self.offer.id, order=self.order)
        self.line = OrderLineFactory(order=self.order, unit_price_excl_tax=self.unit_price)
        self.line.save()
        self.order_discount = OrderDiscountFactory(offer_id=self.offer.id, order=self.order)
        self.order.save()
        self.offer.save()
        self.condition.save()
Beispiel #7
0
 def test_max_user_discount_clean_with_incorrect_value(self):
     """
     Verify that `clean` for `max_user_discount` field raises correct error for values less than consumed discount.
     """
     expected_errors = {
         'max_user_discount': [
             'Ensure new value must be greater than or equal to consumed(400.00) value.'
         ]
     }
     # create an enterprise offer that can provide max $500 discount and has already consumed $400
     offer = factories.EnterpriseOfferFactory(max_user_applications=50, max_user_discount=500)
     for _ in range(4):
         order = OrderFactory(user=self.user, status=ORDER.COMPLETE)
         OrderDiscountFactory(order=order, offer_id=offer.id, amount=100)
     # now try to update the offer with max_discount set to 300 which is less than the already consumed discount
     data = self.generate_data(max_user_applications=50, max_user_discount=300)
     self.assert_form_errors(data, expected_errors, instance=offer)
Beispiel #8
0
 def test_max_user_applications_clean(self):
     """
     Verify that `clean` for `max_user_applications` field is working as expected.
     """
     num_applications = 3
     expected_errors = {
         'max_user_applications': [
             'Ensure new value must be greater than or equal to consumed({}) value.'.format(num_applications)
         ]
     }
     # create an enterprise offer that can be used upto 5 times and has already been used 3 times
     offer = factories.EnterpriseOfferFactory(max_user_applications=5, max_user_discount=500)
     for _ in range(num_applications):
         order = OrderFactory(user=self.user, status=ORDER.COMPLETE)
         OrderDiscountFactory(order=order, offer_id=offer.id, amount=10)
     # now try to update the offer with max_user_applications set to 2
     # which is less than the number of times this offer has already been used
     data = self.generate_data(max_user_applications=2)
     self.assert_form_errors(data, expected_errors, instance=offer)
    def test_offer_availability_with_max_user_discount_including_refunds(
            self, discount_type, num_prev_orders, benefit_value, refund_count,
            is_satisfied):
        """
        Verify that enterprise offer with discount type percentage and absolute, condition returns correct result
        based on user limits in the offer, even when user has refund history.
        """
        current_refund_count = 0
        benefits = {
            Benefit.PERCENTAGE:
            factories.EnterprisePercentageDiscountBenefitFactory(
                value=benefit_value),
            Benefit.FIXED:
            factories.EnterpriseAbsoluteDiscountBenefitFactory(
                value=benefit_value),
        }
        offer = factories.EnterpriseOfferFactory(
            partner=self.partner,
            benefit=benefits[discount_type],
            max_user_discount=150)
        for _ in range(num_prev_orders):
            order = OrderFactory(user=self.user, status=ORDER.COMPLETE)
            OrderDiscountFactory(order=order, offer_id=offer.id, amount=10)
            if current_refund_count < refund_count:
                RefundFactory(order=order,
                              user=self.user,
                              status=REFUND.COMPLETE)
                current_refund_count += 1

        basket = BasketFactory(site=self.site, owner=self.user)
        basket.add_product(self.course_run.seat_products[0])
        basket.add_product(self.entitlement)
        self.mock_course_detail_endpoint(
            discovery_api_url=self.site_configuration.discovery_api_url,
            course=self.entitlement)
        self.mock_catalog_contains_course_runs(
            [self.course_run.id],
            self.condition.enterprise_customer_uuid,
            enterprise_customer_catalog_uuid=self.condition.
            enterprise_customer_catalog_uuid,
        )
        self.assertEqual(self.condition.is_satisfied(offer, basket),
                         is_satisfied)
 def test_absolute_benefit_offer_availability_with_max_user_discount(self):
     """
     Verify that enterprise offer condition returns correct result for an absolute benefit with
     discount value greater than course price.
     """
     offer = factories.EnterpriseOfferFactory(
         partner=self.partner,
         benefit=factories.EnterpriseAbsoluteDiscountBenefitFactory(value=150),
         max_user_discount=150
     )
     for _ in range(5):
         order = OrderFactory(user=self.user, status=ORDER.COMPLETE)
         OrderDiscountFactory(order=order, offer_id=offer.id, amount=10)
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         self.condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=self.condition.enterprise_customer_catalog_uuid,
     )
     self.assertTrue(self.condition.is_satisfied(offer, basket))
Beispiel #11
0
 def test_max_applications_is_correct_when_more_applications(self):
     order = create_order(user=self.user)
     OrderDiscountFactory(order=order, offer_id=self.offer.id, frequency=5)
     self.assertEqual(0, self.offer.get_max_applications(self.user))