Example #1
0
    def test_generate_coupon_report_for_query_coupons(self):
        """ Verify empty report fields for query coupons. """
        catalog_query = 'course:*'
        self.mock_dynamic_catalog_course_runs_api()
        query_coupon = self.create_catalog_coupon(catalog_query=catalog_query)
        query_coupon.history.all().update(history_user=self.user)
        field_names, rows = generate_coupon_report([query_coupon.attr.coupon_vouchers])

        empty_fields = (
            'Coupon Type',
            'Discount Amount',
            'Discount Percentage',
            'Invoiced Amount',
            'Price',
        )
        for field in empty_fields:
            self.assertIsNone(rows[0][field])

        self.assertNotIn('Course ID', field_names)
        self.assertNotIn('Organization', field_names)

        self.assertIn('Catalog Query', field_names)
        self.assertEqual(rows[0]['Catalog Query'], catalog_query)

        self.assertIn('Course Seat Types', field_names)
        self.assertEqual(rows[0]['Course Seat Types'], 'verified')

        self.assertIn('Redeemed For Course ID', field_names)
        self.assertNotIn('Redeemed For Course ID', rows[0])
Example #2
0
    def test_generate_coupon_report(self):
        """ Verify the coupon report is generated properly. """
        self.setup_coupons_for_report()
        client = UserFactory()
        basket = Basket.get_basket(client, self.site)
        basket.add_product(self.coupon)

        vouchers = self.coupon_vouchers.first().vouchers.all()
        self.use_voucher('TESTORDER1', vouchers[1], self.user)

        user2 = UserFactory()
        self.use_voucher('TESTORDER2', vouchers[2], self.user)
        self.use_voucher('TESTORDER3', vouchers[2], user2)

        self.mock_course_api_response(course=self.course)
        field_names, rows = generate_coupon_report(self.coupon_vouchers)

        self.assertEqual(field_names, [
            'Code',
            'Coupon Name',
            'Maximum Coupon Usage',
            'Redemption Count',
            'Coupon Type',
            'URL',
            'Course ID',
            'Organization',
            'Client',
            'Category',
            'Note',
            'Price',
            'Invoiced Amount',
            'Discount Percentage',
            'Discount Amount',
            'Status',
            'Order Number',
            'Redeemed By Username',
            'Created By',
            'Create Date',
            'Coupon Start Date',
            'Coupon Expiry Date',
        ])

        voucher = Voucher.objects.get(name=rows[0]['Coupon Name'])
        self.assert_report_first_row(rows.pop(0), self.coupon, voucher)

        for row in rows:
            voucher = Voucher.objects.get(code=row['Code'])
            self.assert_report_row(row, voucher)

        self.assertNotIn('Catalog Query', field_names)
        self.assertNotIn('Course Seat Types', field_names)
        self.assertNotIn('Redeemed For Course ID', field_names)
Example #3
0
    def test_generate_coupon_report_for_old_coupons(self):
        """ Verify that the client info is present for old coupons. """
        self.setup_coupons_for_report()

        Order.objects.get(basket=self.basket).delete()
        ProductCategory.objects.all().delete()

        self.mock_course_api_response(course=self.course)
        __, rows = generate_coupon_report(self.coupon_vouchers)

        for row in rows:
            self.assertEqual(row['Client'], self.basket.owner.username)
            self.assertEqual(row['Category'], '')
Example #4
0
    def test_generate_coupon_report(self):
        """
        Test generate coupon report
        """
        create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Discount code",
            quantity=1,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.SINGLE_USE,
            code=VOUCHER_CODE
        )

        create_vouchers(
            benefit_type=Benefit.FIXED,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Enrollment code",
            quantity=1,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.SINGLE_USE
        )

        coupon_vouchers = CouponVouchers.objects.filter(coupon=self.coupon)

        field_names, rows = generate_coupon_report(coupon_vouchers)

        self.assertEqual(field_names, ['Name', 'Code', 'Discount', 'URL'])
        self.assertEqual(
            rows[0],
            {
                'Name': 'Discount code',
                'Code': VOUCHER_CODE,
                'Discount': '100.00 %',
                'URL': settings.ECOMMERCE_URL_ROOT + REDEMPTION_URL.format(VOUCHER_CODE)
            }
        )
        enrollment_code_row = rows[1]
        self.assertEqual(enrollment_code_row['Name'], 'Enrollment code')
        self.assertEqual(len(enrollment_code_row['Code']), settings.VOUCHER_CODE_LENGTH)
        self.assertEqual(enrollment_code_row['Discount'], '100.00 USD')
        self.assertEqual(
            enrollment_code_row['URL'],
            settings.ECOMMERCE_URL_ROOT + REDEMPTION_URL.format(enrollment_code_row['Code'])
        )
Example #5
0
 def test_report_for_dynamic_coupon_with_fixed_benefit_type(self):
     """ Verify the coupon report contains correct data for coupon with fixed benefit type. """
     dynamic_coupon = self.create_coupon(benefit_type=Benefit.FIXED,
                                         benefit_value=50,
                                         catalog_query='*:*',
                                         course_seat_types='verified',
                                         max_uses=1,
                                         note='Tešt note',
                                         quantity=1,
                                         title='Tešt product',
                                         voucher_type=Voucher.MULTI_USE)
     coupon_voucher = CouponVouchers.objects.get(coupon=dynamic_coupon)
     __, rows = generate_coupon_report([coupon_voucher])
     voucher = coupon_voucher.vouchers.first()
     self.assert_report_first_row(rows[0], dynamic_coupon, voucher)
Example #6
0
    def test_report_with_no_coupon_history(self):
        self.setup_coupons_for_report()
        self.coupon.history.all().delete()
        client = UserFactory()
        basket = Basket.get_basket(client, self.site)
        basket.add_product(self.coupon)

        vouchers = self.coupon_vouchers.first().vouchers.all()
        self.use_voucher('TESTORDER1', vouchers[1], self.user)

        self.mock_course_api_response(course=self.course)
        _, rows = generate_coupon_report(self.coupon_vouchers)
        first_row = rows.pop(0)
        self.assertEqual(first_row.get('Created By'), 'N/A')
        self.assertEqual(first_row.get('Create Date'), 'N/A')
Example #7
0
    def test_generate_coupon_report_for_used_query_coupon(self):
        """Test that used query coupon voucher reports which course was it used for."""
        catalog_query = '*:*'
        self.mock_dynamic_catalog_course_runs_api(query=catalog_query, course_run=self.course)
        self.mock_dynamic_catalog_contains_api(course_run_ids=[self.verified_seat.course_id], query=catalog_query)
        query_coupon = self.create_catalog_coupon(catalog_query=catalog_query)
        query_coupon.history.all().update(history_user=self.user)
        voucher = query_coupon.attr.coupon_vouchers.vouchers.first()
        voucher.offers.first().condition.range.add_product(self.verified_seat)
        self.use_voucher('TESTORDER4', voucher, self.user)
        field_names, rows = generate_coupon_report([query_coupon.attr.coupon_vouchers])

        self.assertIn('Redeemed For Course ID', field_names)
        self.assertIn('Redeemed By Username', field_names)
        self.assertEqual(rows[-1]['Redeemed By Username'], self.user.username)
        self.assertEqual(rows[-1]['Redeemed For Course ID'], self.course.id)
Example #8
0
    def test_generate_coupon_report_for_used_query_coupon(self):
        """Test that used query coupon voucher reports which course was it used for."""
        catalog_query = '*:*'
        self.mock_dynamic_catalog_course_runs_api(query=catalog_query, course_run=self.course)
        self.mock_dynamic_catalog_contains_api(course_run_ids=[self.verified_seat.course_id], query=catalog_query)
        query_coupon = self.create_catalog_coupon(catalog_query=catalog_query)
        query_coupon.history.all().update(history_user=self.user)
        voucher = query_coupon.attr.coupon_vouchers.vouchers.first()
        voucher.offers.first().condition.range.add_product(self.verified_seat)
        self.use_voucher('TESTORDER4', voucher, self.user)
        field_names, rows = generate_coupon_report([query_coupon.attr.coupon_vouchers])

        self.assertIn('Redeemed For Course ID', field_names)
        self.assertIn('Redeemed By Username', field_names)
        self.assertEqual(rows[-1]['Redeemed By Username'], self.user.username)
        self.assertEqual(rows[-1]['Redeemed For Course ID'], self.course.id)
Example #9
0
    def test_single_use_redemption_count(self):
        """Verify redemption count does not increment for other, unused, single-use vouchers."""
        coupon = self.create_coupon(title='Test single use',
                                    catalog=self.catalog,
                                    quantity=2)
        vouchers = coupon.attr.coupon_vouchers.vouchers.all()
        self.use_voucher('TEST', vouchers[0], self.user)
        __, rows = generate_coupon_report([coupon.attr.coupon_vouchers])

        # rows[0] - This row is different from other rows
        # rows[1] - first voucher header row
        # rows[2] - first voucher row with usage information
        # rows[3] - second voucher header row
        self.assertEqual(len(rows), 4)
        self.assertEqual(rows[1]['Redemption Count'], 1)
        self.assertEqual(rows[2]['Redeemed By Username'], self.user.username)
        self.assertEqual(rows[3]['Redemption Count'], 0)
Example #10
0
    def test_report_for_inactive_coupons(self):
        """ Verify the coupon report show correct status for inactive coupons. """
        self.data.update({
            'name': self.coupon.title,
            'end_datetime': datetime.datetime.now() - datetime.timedelta(days=1)
        })
        vouchers = create_vouchers(**self.data)
        self.coupon_vouchers.first().vouchers.add(*vouchers)

        __, rows = generate_coupon_report(self.coupon_vouchers)

        # The data that is the same for all vouchers like Coupon Name, Coupon Type, etc.
        # are only shown in row[0]
        # The data that is unique among vouchers like Code, Url, Status, etc.
        # starts from row[1]
        self.assertEqual(rows[0]['Coupon Name'], self.coupon.title)
        self.assertEqual(rows[2]['Status'], _('Inactive'))
Example #11
0
    def test_report_for_inactive_coupons(self):
        """ Verify the coupon report show correct status for inactive coupons. """
        create_vouchers(benefit_type=Benefit.FIXED,
                        benefit_value=100.00,
                        catalog=self.catalog,
                        coupon=self.coupon,
                        end_datetime=datetime.date(2015, 10, 30),
                        name="Inactive code",
                        quantity=1,
                        start_datetime=datetime.date(2015, 10, 30),
                        voucher_type=Voucher.SINGLE_USE)

        __, rows = generate_coupon_report(self.coupon_vouchers)

        inactive_coupon_row = rows[1]
        self.assertEqual(inactive_coupon_row['Coupon Name'], 'Inactive code')
        self.assertEqual(inactive_coupon_row['Status'], _('Inactive'))
Example #12
0
    def test_generate_coupon_report(self):
        """ Verify the coupon report is generated properly. """
        self.setup_coupons_for_report()
        client = UserFactory()
        basket = Basket.get_basket(client, self.site)
        basket.add_product(self.coupon)

        vouchers = self.coupon_vouchers.first().vouchers.all()
        self.use_voucher('TESTORDER1', vouchers[1], self.user)

        user2 = UserFactory()
        self.use_voucher('TESTORDER2', vouchers[2], self.user)
        self.use_voucher('TESTORDER3', vouchers[2], user2)

        self.mock_course_api_response(course=self.course)
        field_names, rows = generate_coupon_report(self.coupon_vouchers)

        self.assertEqual(field_names, [
            'Coupon Name',
            'Code',
            'Maximum Coupon Usage',
            'Redemption Count',
            'Coupon Type',
            'URL',
            'Course ID',
            'Organization',
            'Client',
            'Category',
            'Note',
            'Price',
            'Invoiced Amount',
            'Discount Percentage',
            'Discount Amount',
            'Status',
            'Order Number',
            'Redeemed By Username',
            'Created By',
            'Create Date',
            'Coupon Start Date',
            'Coupon Expiry Date',
        ])

        for row in rows:
            voucher = Voucher.objects.get(name=row['Coupon Name'])
            self.assert_report_row(row, self.coupon, voucher)
Example #13
0
    def test_generate_coupon_report_for_program_coupon(self):
        """ Only program coupon applicable fields should be shown. """
        program_uuid = uuid.uuid4()
        program_coupon = self.create_coupon(
            title='Program Coupon Report',
            program_uuid=program_uuid,
        )
        field_names, rows = generate_coupon_report([program_coupon.attr.coupon_vouchers])

        for field in ('Discount Amount', 'Price'):
            self.assertIsNone(rows[0][field])

        removed_fields = ('Catalog Query', 'Course ID', 'Course Seat Types', 'Organization', 'Redeemed For Course ID',)
        for field_name in removed_fields:
            self.assertNotIn(field_name, field_names)

        self.assertIn('Program UUID', field_names)
        self.assertEqual(rows[0]['Program UUID'], program_uuid)
Example #14
0
    def test_report_for_inactive_coupons(self):
        """ Verify the coupon report show correct status for inactive coupons. """
        create_vouchers(
            benefit_type=Benefit.FIXED,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Inactive code",
            quantity=1,
            start_datetime=datetime.date(2015, 10, 30),
            voucher_type=Voucher.SINGLE_USE
        )

        __, rows = generate_coupon_report(self.coupon_vouchers)

        inactive_coupon_row = rows[1]
        self.assertEqual(inactive_coupon_row['Coupon Name'], 'Inactive code')
        self.assertEqual(inactive_coupon_row['Status'], _('Inactive'))
Example #15
0
    def test_single_use_redemption_count(self):
        """Verify redemption count does not increment for other, unused, single-use vouchers."""
        coupon = self.create_coupon(
            title='Test single use',
            catalog=self.catalog,
            quantity=2
        )
        coupon.history.all().update(history_user=self.user)
        vouchers = coupon.attr.coupon_vouchers.vouchers.all()
        self.use_voucher('TEST', vouchers[0], self.user)
        __, rows = generate_coupon_report([coupon.attr.coupon_vouchers])

        # rows[0] - first voucher header row
        # rows[1] - first voucher row with usage information
        # rows[2] - second voucher header row
        self.assertEqual(len(rows), 3)
        self.assertEqual(rows[0]['Redemption Count'], 1)
        self.assertEqual(rows[1]['Redeemed By Username'], self.user.username)
        self.assertEqual(rows[2]['Redemption Count'], 0)
Example #16
0
    def test_generate_coupon_report_with_deleted_product(self):
        """ Verify the coupon report contains correct data for coupon with fixed benefit type. """
        course = CourseFactory(id='course-v1:del-org+course+run',
                               partner=self.partner)
        professional_seat = course.create_or_update_seat(
            'professional', False, 100)
        query_coupon = self.create_catalog_coupon(catalog_query='course:*')

        vouchers = query_coupon.attr.coupon_vouchers.vouchers.all()
        first_voucher = vouchers.first()
        self.use_voucher('TESTORDER1',
                         first_voucher,
                         self.user,
                         product=professional_seat)
        professional_seat.delete()

        __, rows = generate_coupon_report([query_coupon.attr.coupon_vouchers])
        self.assert_report_first_row(rows[0], query_coupon, first_voucher)
        self.assertDictContainsSubset({'Redeemed For Course ID': 'Unknown'},
                                      rows[2])
Example #17
0
    def test_report_for_inactive_coupons(self):
        """ Verify the coupon report show correct status for inactive coupons. """
        coupon_title = self.coupon.title
        create_vouchers(benefit_type=Benefit.FIXED,
                        benefit_value=100.00,
                        catalog=self.catalog,
                        coupon=self.coupon,
                        end_datetime=datetime.date(2015, 10, 30),
                        name=coupon_title,
                        quantity=1,
                        start_datetime=datetime.date(2015, 10, 30),
                        voucher_type=Voucher.SINGLE_USE)

        __, rows = generate_coupon_report(self.coupon_vouchers)

        # The data that is the same for all vouchers like Coupon Name, Coupon Type, etc.
        # are only shown in row[0]
        # The data that is unique among vouchers like Code, Url, Status, etc.
        # starts from row[1]
        self.assertEqual(rows[0]['Coupon Name'], coupon_title)
        self.assertEqual(rows[2]['Status'], _('Inactive'))
Example #18
0
    def get(self, request, coupon_id):  # pylint: disable=unused-argument
        """
        Generate coupon report for vouchers associated with the coupon.
        """

        coupon = Product.objects.get(id=coupon_id)
        filename = _("Coupon Report for {coupon_name}").format(coupon_name=unicode(coupon))
        coupons_vouchers = CouponVouchers.objects.filter(coupon=coupon)

        filename = "{}.csv".format(slugify(filename))

        field_names, rows = generate_coupon_report(coupons_vouchers)

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}'.format(filename)

        writer = csv.DictWriter(response, fieldnames=field_names)
        writer.writeheader()

        for row in rows:
            writer.writerow(row)

        return response
Example #19
0
    def test_report_for_inactive_coupons(self):
        """ Verify the coupon report show correct status for inactive coupons. """
        coupon_title = self.coupon.title
        create_vouchers(
            benefit_type=Benefit.FIXED,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name=coupon_title,
            quantity=1,
            start_datetime=datetime.date(2015, 10, 30),
            voucher_type=Voucher.SINGLE_USE
        )

        __, rows = generate_coupon_report(self.coupon_vouchers)

        # The data that is the same for all vouchers like Coupon Name, Coupon Type, etc.
        # are only shown in row[0]
        # The data that is unique among vouchers like Code, Url, Status, etc.
        # starts from row[1]
        self.assertEqual(rows[0]['Coupon Name'], coupon_title)
        self.assertEqual(rows[2]['Status'], _('Inactive'))
Example #20
0
    def test_generate_coupon_report_for_query_coupons(self):
        """ Verify empty report fields for query coupons. """
        query_coupon = self.create_coupon(
            title='Query coupon',
            quantity=1,
            catalog_query='course:*',
            course_seat_types='verified'
        )
        query_coupon.history.all().update(history_user=self.user)
        self.mock_course_api_response(course=self.course)
        __, rows = generate_coupon_report([query_coupon.attr.coupon_vouchers])

        empty_fields = (
            'Invoiced Amount',
            'Course ID',
            'Organization',
            'Price',
            'Coupon Type',
            'Discount Percentage',
            'Discount Amount'
        )
        for field in empty_fields:
            self.assertIsNone(rows[0][field])
Example #21
0
    def test_generate_coupon_report_for_query_coupon_with_multi_line_order(self):
        """
        Test that coupon report for a query coupon that was used on multi-line order
        contains ids from all courses in that order.
        """
        course1 = CourseFactory()
        course2 = CourseFactory()
        order = OrderFactory(number='TESTORDER')
        order.lines.add(
            OrderLineFactory(product=course1.create_or_update_seat('verified', False, 101))
        )
        order.lines.add(
            OrderLineFactory(product=course2.create_or_update_seat('verified', False, 110))
        )
        query_coupon = self.create_catalog_coupon(catalog_query='*:*')
        voucher = query_coupon.attr.coupon_vouchers.vouchers.first()
        voucher.record_usage(order, self.user)
        field_names, rows = generate_coupon_report([query_coupon.attr.coupon_vouchers])

        expected_redemed_course_ids = '{}, {}'.format(course1, course2)
        self.assertEqual(rows[-1]['Redeemed For Course IDs'], expected_redemed_course_ids)
        self.assertEqual(rows[-1].get('Redeemed For Course ID'), None)
        self.assertIn('Redeemed For Course ID', field_names)
        self.assertIn('Redeemed For Course IDs', field_names)
Example #22
0
    def test_generate_coupon_report(self):
        """
        Test generate coupon report
        """
        create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Discount code",
            quantity=1,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.SINGLE_USE,
            code=VOUCHER_CODE
        )

        create_vouchers(
            benefit_type=Benefit.FIXED,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Enrollment code",
            quantity=1,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.SINGLE_USE
        )

        self.coupon.history.all().update(history_user=self.user)
        coupon_vouchers = CouponVouchers.objects.filter(coupon=self.coupon)

        field_names, rows = generate_coupon_report(coupon_vouchers)

        self.assertEqual(field_names, [
            'Name',
            'Code',
            'URL',
            'CourseID',
            'Price',
            'Invoiced Amount',
            'Discount',
            'Status',
            'Created By',
            'Create Date',
            'Expiry Date',
        ])
        enrollment_code_row = rows[-2]
        self.assertEqual(enrollment_code_row['Name'], 'Discount code')
        self.assertEqual(enrollment_code_row['Code'], VOUCHER_CODE)
        self.assertEqual(enrollment_code_row['URL'], settings.ECOMMERCE_URL_ROOT + REDEMPTION_URL.format(VOUCHER_CODE))
        self.assertEqual(enrollment_code_row['CourseID'], self.course.id)
        self.assertEqual(enrollment_code_row['Price'], currency(0.00))
        self.assertEqual(enrollment_code_row['Invoiced Amount'], currency(100.00))
        self.assertEqual(enrollment_code_row['Discount'], '100.00 %')
        self.assertEqual(enrollment_code_row['Status'], 'Inactive')
        self.assertEqual(enrollment_code_row['Created By'], self.user.full_name)
        self.assertEqual(enrollment_code_row['Create Date'], 'Oct 01,15')
        self.assertEqual(enrollment_code_row['Expiry Date'], 'Oct 30,15')

        enrollment_code_row = rows[-1]
        self.assertEqual(enrollment_code_row['Name'], 'Enrollment code')
        self.assertEqual(len(enrollment_code_row['Code']), settings.VOUCHER_CODE_LENGTH)
        self.assertEqual(enrollment_code_row['Discount'], '$100.00')
        self.assertEqual(
            enrollment_code_row['URL'],
            settings.ECOMMERCE_URL_ROOT + REDEMPTION_URL.format(enrollment_code_row['Code'])
        )