示例#1
0
    def test_get_enterprise_customer_from_enterprise_offer(self, discount_value):
        """
        Verify that "get_enterprise_customer_from_enterprise_offer" returns `None` if expected conditions are not met.
        """
        course = CourseFactory(name='EnterpriseConsentErrorTest', partner=PartnerFactory())
        product = course.create_or_update_seat('verified', False, 50)

        benefit = EnterprisePercentageDiscountBenefitFactory(value=discount_value)
        offer = EnterpriseOfferFactory(benefit=benefit)
        # set wrong priority to invalidate the condition in util
        offer.priority = 111

        self.mock_enterprise_learner_api(
            learner_id=self.learner.id,
            enterprise_customer_uuid=str(offer.condition.enterprise_customer_uuid),
            course_run_id=course.id,
        )

        self.mock_catalog_contains_course_runs(
            [course.id],
            str(offer.condition.enterprise_customer_uuid),
            enterprise_customer_catalog_uuid=str(offer.condition.enterprise_customer_catalog_uuid),
            contains_content=True,
        )

        basket = BasketFactory(site=self.site, owner=self.create_user())
        basket.add_product(product)
        basket.strategy = DefaultStrategy()
        Applicator().apply_offers(basket, [offer])

        self.assertIsNone(get_enterprise_customer_from_enterprise_offer(basket))
示例#2
0
    def test_create_offer_assignments_for_updated_max_uses(self, __):
        """
        Verify the `create_assignments_for_multi_use_per_customer` works as expected for
        `MULTI_USE_PER_CUSTOMER` when `max_global_applications` is updated for existing voucher.
        """
        coupon_max_global_applications = 1
        enterprise_offer = EnterpriseOfferFactory(
            max_global_applications=coupon_max_global_applications)
        voucher = VoucherFactory(usage=Voucher.MULTI_USE_PER_CUSTOMER)
        voucher.offers.add(enterprise_offer)
        basket = create_basket(owner=self.user, site=self.site)
        basket.vouchers.add(voucher)
        order = create_order(user=self.user, basket=basket)

        assert OfferAssignment.objects.all().count() == 0

        EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer(
            order)
        EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment(
            order)

        assert OfferAssignment.objects.all().count(
        ) == coupon_max_global_applications
        assert OfferAssignment.objects.filter(
            offer=enterprise_offer,
            code=voucher.code,
            user_email=basket.owner.email,
            status=OFFER_REDEEMED).count() == 1

        # update max_global_applications
        coupon_new_max_global_applications = 5
        enterprise_offer.max_global_applications = coupon_new_max_global_applications
        enterprise_offer.save()

        assert voucher.enterprise_offer.max_global_applications == coupon_new_max_global_applications

        EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer(
            order)

        assert OfferAssignment.objects.all().count(
        ) == coupon_new_max_global_applications
        assert OfferAssignment.objects.filter(
            offer=enterprise_offer,
            code=voucher.code,
            user_email=basket.owner.email,
            status=OFFER_ASSIGNED).count() == 4
        assert OfferAssignment.objects.filter(
            offer=enterprise_offer,
            code=voucher.code,
            user_email=basket.owner.email,
            status=OFFER_REDEEMED).count() == 1

        # call once again to verify nothing is created because all available slots are assigned
        EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer(
            order)
        assert OfferAssignment.objects.all().count(
        ) == coupon_new_max_global_applications
示例#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
示例#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
示例#5
0
 def prepare_enterprise_offer(self,
                              percentage_discount_value=100,
                              enterprise_customer_name=None):
     benefit = EnterprisePercentageDiscountBenefitFactory(
         value=percentage_discount_value)
     if enterprise_customer_name is not None:
         condition = EnterpriseCustomerConditionFactory(
             enterprise_customer_name=enterprise_customer_name)
     else:
         condition = EnterpriseCustomerConditionFactory()
     enterprise_offer = EnterpriseOfferFactory(partner=self.partner,
                                               benefit=benefit,
                                               condition=condition)
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         enterprise_customer_uuid=str(condition.enterprise_customer_uuid),
         course_run_id=self.course_run.id,
     )
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=condition.
         enterprise_customer_catalog_uuid,
     )
     return enterprise_offer
示例#6
0
    def test_create_assignments_for_multi_use_per_customer(self, __):
        """
        Verify the `create_assignments_for_multi_use_per_customer` works as expected for `MULTI_USE_PER_CUSTOMER`.
        """
        coupon_max_global_applications = 10
        enterprise_offer = EnterpriseOfferFactory(
            max_global_applications=coupon_max_global_applications)
        voucher = VoucherFactory(usage=Voucher.MULTI_USE_PER_CUSTOMER)
        voucher.offers.add(enterprise_offer)
        basket = create_basket(owner=self.user, site=self.site)
        basket.vouchers.add(voucher)
        order = create_order(user=self.user, basket=basket)

        assert OfferAssignment.objects.all().count() == 0

        EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer(
            order)
        EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment(
            order)

        assert OfferAssignment.objects.all().count(
        ) == coupon_max_global_applications
        assert OfferAssignment.objects.filter(
            offer=enterprise_offer,
            code=voucher.code,
            user_email=basket.owner.email,
            status=OFFER_ASSIGNED).count() == 9
        assert OfferAssignment.objects.filter(
            offer=enterprise_offer,
            code=voucher.code,
            user_email=basket.owner.email,
            status=OFFER_REDEEMED).count() == 1
示例#7
0
 def test_is_satisfied_with_wrong_offer(self):
     """
     Test `ManualEnrollmentOrderDiscountCondition.is_satisfied` works as expected for wrong offer.
     """
     offer = EnterpriseOfferFactory(partner=self.partner, condition=self.condition)
     status = self.condition.is_satisfied(offer, self.basket)
     assert not status
示例#8
0
 def prepare_enterprise_offer(self, percentage_discount_value=100):
     Switch.objects.update_or_create(name=ENTERPRISE_OFFERS_SWITCH, defaults={'active': True})
     benefit = EnterprisePercentageDiscountBenefitFactory(value=percentage_discount_value)
     condition = EnterpriseCustomerConditionFactory()
     EnterpriseOfferFactory(partner=self.partner, benefit=benefit, condition=condition)
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         enterprise_customer_uuid=str(condition.enterprise_customer_uuid),
         course_run_id=self.course_run.id,
     )
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=condition.enterprise_customer_catalog_uuid,
     )
示例#9
0
    def test_update_assigned_voucher_offer_assignment(self, __):
        """
        Verify the "update_assigned_voucher_offer_assignment" works as expected.
        """
        enterprise_offer = EnterpriseOfferFactory()
        voucher = VoucherFactory()
        voucher.offers.add(enterprise_offer)
        basket = create_basket(owner=self.user, site=self.site)
        basket.vouchers.add(voucher)
        order = create_order(user=self.user, basket=basket)
        voucher_application = VoucherApplication.objects.create(voucher=voucher, user=self.user, order=order)
        offer_assignment = OfferAssignmentFactory(offer=enterprise_offer, code=voucher.code, user_email=self.user.email)

        EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment(order)

        offer_assignment = OfferAssignment.objects.get(id=offer_assignment.id)
        assert offer_assignment.status == OFFER_REDEEMED
        assert offer_assignment.voucher_application == voucher_application
示例#10
0
    def test_update_assigned_voucher_offer_assignment(self, __):
        """
        Verify the "update_assigned_voucher_offer_assignment" works as expected.
        """
        enterprise_offer = EnterpriseOfferFactory()
        voucher = VoucherFactory()
        voucher.offers.add(enterprise_offer)
        basket = create_basket(owner=self.user, site=self.site)
        basket.vouchers.add(voucher)
        order = create_order(user=self.user, basket=basket)
        voucher_application = VoucherApplication.objects.create(
            voucher=voucher, user=self.user, order=order)
        offer_assignment = OfferAssignmentFactory(offer=enterprise_offer,
                                                  code=voucher.code,
                                                  user_email=self.user.email)

        # create nudge email templates and subscription records
        for email_type in (DAY3, DAY10, DAY19):
            nudge_email_template = CodeAssignmentNudgeEmailTemplatesFactory(
                email_type=email_type)
            nudge_email = CodeAssignmentNudgeEmailsFactory(
                email_template=nudge_email_template,
                user_email=self.user.email,
                code=voucher.code)

            # verify subscription is active
            assert nudge_email.is_subscribed

        EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment(
            order)

        offer_assignment = OfferAssignment.objects.get(id=offer_assignment.id)
        assert offer_assignment.status == OFFER_REDEEMED
        assert offer_assignment.voucher_application == voucher_application

        # verify that nudge emails subscriptions are inactive
        assert CodeAssignmentNudgeEmails.objects.filter(
            is_subscribed=True).count() == 0
        assert CodeAssignmentNudgeEmails.objects.filter(
            code__in=[voucher.code],
            user_email__in=[self.user.email],
            is_subscribed=False).count() == 3
示例#11
0
    def setUp(self):
        """
        Setup the test data
        """
        super(SendCodeAssignmentNudgeEmailsTests, self).setUp()
        # Create a voucher with valid offer so we can get
        voucher = VoucherFactory()
        voucher.offers.add(EnterpriseOfferFactory(max_global_applications=98))

        self.total_nudge_emails_for_today = 5
        self.nudge_emails = CodeAssignmentNudgeEmailsFactory.create_batch(
            self.total_nudge_emails_for_today, code=voucher.code)
        CodeAssignmentNudgeEmailsFactory(email_date=datetime.datetime.now() +
                                         relativedelta(days=1))
        CodeAssignmentNudgeEmailsFactory(email_date=datetime.datetime.now() +
                                         relativedelta(days=2))

        for nudge_email in self.nudge_emails:
            OfferAssignmentFactory(code=nudge_email.code,
                                   user_email=nudge_email.user_email)
    def setUp(self):
        """
        Create test data.
        """
        super(SendEnterpriseOfferLimitEmailsTests, self).setUp()

        EnterpriseOfferFactory(max_global_applications=10)
        EnterpriseOfferFactory(max_discount=100)
        EnterpriseOfferFactory(max_global_applications=0)
        EnterpriseOfferFactory(max_discount=0)

        # Creating conditionaloffer with daily frequency and adding corresponding offer_usage object.
        offer_with_daily_frequency = EnterpriseOfferFactory(
            max_global_applications=10)
        offer_usage = OfferUsageEmail.create_record(offer_with_daily_frequency)
        offer_usage.created = datetime.datetime.fromordinal(
            datetime.datetime.now().toordinal() - 2)
        offer_usage.save()

        # Creating conditionaloffer with weekly frequency and adding corresponding offer_usage object.
        offer_with_weekly_frequency = EnterpriseOfferFactory(
            max_global_applications=10,
            usage_email_frequency=ConditionalOffer.WEEKLY)
        offer_usage = OfferUsageEmail.create_record(
            offer_with_weekly_frequency)
        offer_usage.created = datetime.datetime.fromordinal(
            datetime.datetime.now().toordinal() - 8)
        offer_usage.save()

        # Creating conditionaloffer with monthly frequency and adding corresponding offer_usage object.
        offer_with_monthly_frequency = EnterpriseOfferFactory(
            max_global_applications=10,
            usage_email_frequency=ConditionalOffer.MONTHLY)
        offer_usage = OfferUsageEmail.create_record(
            offer_with_monthly_frequency)
        offer_usage.created = datetime.datetime.fromordinal(
            datetime.datetime.now().toordinal() - 31)
        offer_usage.save()