Example #1
0
    def test_create_discount_coupon(self):
        """
        Test discount voucher creation with specified code
        """
        discount_vouchers = create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=25.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="XMASC0DE"
        )

        self.assertEqual(len(discount_vouchers), 1)
        self.assertEqual(discount_vouchers[0].code, "XMASC0DE")

        with self.assertRaises(IntegrityError):
            create_vouchers(
                benefit_type=Benefit.PERCENTAGE,
                benefit_value=35.00,
                catalog=self.catalog,
                coupon=self.coupon,
                end_datetime=datetime.date(2015, 10, 30),
                name="Discount name",
                quantity=1,
                start_datetime=datetime.date(2015, 10, 1),
                voucher_type=Voucher.SINGLE_USE,
                code="XMASC0DE"
            )
Example #2
0
    def setup_coupons_for_report(self):
        """ Create specific coupons to test report generation """
        create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=50.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2099, 10, 30),
            name='Enrollment',
            quantity=1,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.ONCE_PER_CUSTOMER,
            code=VOUCHER_CODE,
            max_uses=1
        )

        create_vouchers(
            benefit_type=Benefit.FIXED,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date.today() + datetime.timedelta(10),
            name='Discount',
            quantity=1,
            start_datetime=datetime.date.today() - datetime.timedelta(1),
            voucher_type=Voucher.SINGLE_USE
        )
Example #3
0
    def test_regenerate_voucher_code(self):
        """
        Test that voucher code will be regenerated if it already exists
        """
        for code in 'BCDFGHJKL':
            create_vouchers(
                benefit_type=Benefit.PERCENTAGE,
                benefit_value=100.00,
                catalog=self.catalog,
                coupon=self.coupon,
                end_datetime=datetime.date(2015, 10, 30),
                name="Test voucher",
                quantity=1,
                start_datetime=datetime.date(2015, 10, 1),
                voucher_type=Voucher.SINGLE_USE,
                code=code
            )

        for _ in range(20):
            voucher = create_vouchers(
                benefit_type=Benefit.PERCENTAGE,
                benefit_value=100.00,
                catalog=self.catalog,
                coupon=self.coupon,
                end_datetime=datetime.date(2015, 10, 30),
                name="Test voucher",
                quantity=1,
                start_datetime=datetime.date(2015, 10, 1),
                voucher_type=Voucher.SINGLE_USE
            )
            self.assertTrue(Voucher.objects.filter(code__iexact=voucher[0].code).exists())
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_create_vouchers(self):
        """
        Test voucher creation
        """
        vouchers = create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Test voucher",
            quantity=10,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.SINGLE_USE
        )

        self.assertEqual(len(vouchers), 10)

        voucher = vouchers[0]
        voucher_offer = voucher.offers.first()
        coupon_voucher = CouponVouchers.objects.get(coupon=self.coupon)

        self.assertEqual(voucher_offer.benefit.type, Benefit.PERCENTAGE)
        self.assertEqual(voucher_offer.benefit.value, 100.00)
        self.assertEqual(voucher_offer.benefit.range.catalog, self.catalog)
        self.assertEqual(len(coupon_voucher.vouchers.all()), 10)
        self.assertEqual(voucher.end_datetime, datetime.date(2015, 10, 30))
        self.assertEqual(voucher.start_datetime, datetime.date(2015, 10, 1))
        self.assertEqual(voucher.usage, Voucher.SINGLE_USE)
    def test_voucher_usage(self):
        """
        Test that using a voucher applies offer discount to reduce order price
        """
        catalog = Catalog.objects.create(partner=self.partner)

        coupon_product_class, _ = ProductClass.objects.get_or_create(name='coupon')
        coupon = factories.create_product(
            product_class=coupon_product_class,
            title='Test product'
        )

        stock_record = StockRecord.objects.filter(product=self.seat).first()
        catalog.stock_records.add(stock_record)

        vouchers = create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=100.00,
            catalog=catalog,
            coupon=coupon,
            end_datetime=datetime.datetime.now(),
            name="Test Voucher",
            quantity=10,
            start_datetime=datetime.datetime.now() + datetime.timedelta(days=30),
            voucher_type=Voucher.SINGLE_USE
        )
        voucher = vouchers[0]

        seat_basket = self.order.basket
        Applicator().apply_offers(seat_basket, voucher.offers.all())
        self.assertEqual(seat_basket.total_excl_tax, 0.00)
Example #7
0
 def test_nonpositive_voucher_code_length(self):
     """
     Test that setting a voucher code length to a nonpositive integer value
     raises a ValueError
     """
     with self.assertRaises(ValueError):
         create_vouchers(
             benefit_type=Benefit.PERCENTAGE,
             benefit_value=100.00,
             catalog=self.catalog,
             coupon=self.coupon,
             end_datetime=datetime.date(2015, 10, 30),
             name="Test voucher",
             quantity=1,
             start_datetime=datetime.date(2015, 10, 1),
             voucher_type=Voucher.SINGLE_USE
         )
Example #8
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 #9
0
    def fulfill_product(self, order, lines):
        """ Fulfills the purchase of an Enrollment code product.
        For each line creates number of vouchers equal to that line's quantity. Creates a new OrderLineVouchers
        object to tie the order with the created voucher and adds the vouchers to the coupon's total vouchers.

        Args:
            order (Order): The Order associated with the lines to be fulfilled.
            lines (List of Lines): Order Lines, associated with purchased products in an Order.

        Returns:
            The original set of lines, with new statuses set based on the success or failure of fulfillment.
        """
        msg = "Attempting to fulfill '{product_class}' product types for order [{order_number}]".format(
            product_class=ENROLLMENT_CODE_PRODUCT_CLASS_NAME,
            order_number=order.number
        )
        logger.info(msg)

        for line in lines:
            name = 'Enrollment Code Range for {}'.format(line.product.attr.course_key)
            seat = Product.objects.filter(
                attributes__name='course_key',
                attribute_values__value_text=line.product.attr.course_key
            ).get(
                attributes__name='certificate_type',
                attribute_values__value_text=line.product.attr.seat_type
            )
            _range, created = Range.objects.get_or_create(name=name)
            if created:
                _range.add_product(seat)

            vouchers = create_vouchers(
                name='Enrollment code voucher [{}]'.format(line.product.title),
                benefit_type=Benefit.PERCENTAGE,
                benefit_value=100,
                catalog=None,
                coupon=seat,
                end_datetime=settings.ENROLLMENT_CODE_EXIPRATION_DATE,
                enterprise_customer=None,
                quantity=line.quantity,
                start_datetime=datetime.datetime.now(),
                voucher_type=Voucher.SINGLE_USE,
                _range=_range
            )

            line_vouchers = OrderLineVouchers.objects.create(line=line)
            for voucher in vouchers:
                line_vouchers.vouchers.add(voucher)

            line.set_status(LINE.COMPLETE)

        self.send_email(order)
        logger.info("Finished fulfilling 'Enrollment code' product types for order [%s]", order.number)
        return order, lines
Example #10
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 #11
0
    def test_update_voucher_offer(self):
        vouchers = create_vouchers(
            benefit_type=Benefit.PERCENTAGE,
            benefit_value=100.00,
            catalog=self.catalog,
            coupon=self.coupon,
            end_datetime=datetime.date(2015, 10, 30),
            name="Test voucher",
            quantity=10,
            start_datetime=datetime.date(2015, 10, 1),
            voucher_type=Voucher.SINGLE_USE
        )

        voucher = vouchers[0]
        voucher_offer = voucher.offers.first()
        self.assertEqual(voucher_offer.benefit.type, Benefit.PERCENTAGE)
        self.assertEqual(voucher_offer.benefit.value, 100.00)
        self.assertEqual(voucher_offer.benefit.range.catalog, self.catalog)

        new_offer = update_voucher_offer(voucher_offer, 50.00, Benefit.PERCENTAGE)
        self.assertEqual(new_offer.benefit.type, Benefit.PERCENTAGE)
        self.assertEqual(new_offer.benefit.value, 50.00)
        self.assertEqual(new_offer.benefit.range.catalog, self.catalog)
Example #12
0
def create_coupon_product(benefit_type, benefit_value, catalog, catalog_query,
                          category, code, course_seat_types, email_domains,
                          end_datetime, enterprise_customer,
                          enterprise_customer_catalog, max_uses, note, partner,
                          price, quantity, start_datetime, title, voucher_type,
                          course_catalog, program_uuid, site):
    """
    Creates a coupon product and a stock record for it.

    Arguments:
        benefit_type (str): Voucher Benefit type.
        benefit_value (int): Voucher Benefit value.
        catalog (Catalog): Catalog used to create a range of products.
        catalog_query (str): ElasticSearch query used by dynamic coupons.
        category (dict): Contains category ID and name.
        code (str): Voucher code.
        course_seat_types (str): Comma-separated list of course seat types.
        course_catalog (int): Course catalog id from Discovery Service
        email_domains (str): Comma-separated list of email domains.
        end_datetime (Datetime): Voucher end Datetime.
        enterprise_customer (str): UUID of an EnterpriseCustomer to attach to this voucher
        enterprise_customer_catalog (str): UUID of an EnterpriseCustomerCatalog to attach to this voucher
        max_uses (int): Number of Voucher max uses.
        note (str): Coupon note.
        partner (User): Partner associated with coupon Stock Record.
        price (int): The price of the coupon.
        quantity (int): Number of vouchers to be created and associated with the coupon.
        start_datetime (Datetime): Voucher start Datetime.
        title (str): The name of the coupon.
        voucher_type (str): Voucher type
        program_uuid (str): Program UUID for the Coupon
        site (site): Site for which the Coupon is created.

    Returns:
        A coupon Product object.

    Raises:
        IntegrityError: An error occurred when create_vouchers method returns
                        an IntegrityError exception
    """
    product_class = ProductClass.objects.get(name=COUPON_PRODUCT_CLASS_NAME)
    coupon_product = Product.objects.create(title=title,
                                            product_class=product_class)

    ProductCategory.objects.get_or_create(product=coupon_product,
                                          category=category)

    # Vouchers are created during order and not fulfillment like usual
    # because we want vouchers to be part of the line in the order.

    try:
        vouchers = create_vouchers(
            benefit_type=benefit_type,
            benefit_value=benefit_value,
            catalog=catalog,
            catalog_query=catalog_query,
            code=code or None,
            coupon=coupon_product,
            course_catalog=course_catalog,
            course_seat_types=course_seat_types,
            email_domains=email_domains,
            end_datetime=end_datetime,
            enterprise_customer=enterprise_customer,
            enterprise_customer_catalog=enterprise_customer_catalog,
            max_uses=max_uses,
            name=title,
            quantity=int(quantity),
            start_datetime=start_datetime,
            voucher_type=voucher_type,
            program_uuid=program_uuid,
            site=site)
    except IntegrityError:
        logger.exception('Failed to create vouchers for [%s] coupon.',
                         coupon_product.title)
        raise

    coupon_vouchers, __ = CouponVouchers.objects.get_or_create(
        coupon=coupon_product)
    coupon_vouchers.vouchers.add(*vouchers)
    coupon_product.attr.coupon_vouchers = coupon_vouchers
    coupon_product.attr.note = note
    coupon_product.save()

    sku = generate_sku(product=coupon_product, partner=partner)
    StockRecord.objects.update_or_create(defaults={
        'price_currency': settings.OSCAR_DEFAULT_CURRENCY,
        'price_excl_tax': price
    },
                                         partner=partner,
                                         partner_sku=sku,
                                         product=coupon_product)

    return coupon_product
Example #13
0
    def create_coupon_product(self, title, price, data):
        """Creates a coupon product and a stock record for it.

        Arguments:
            title (str): The name of the coupon.
            price (int): The price of the coupon(s).
            data (dict): Contains data needed to create vouchers,SKU and UPC:
                - partner (User)
                - benefit_type (str)
                - benefit_value (int)
                - catalog (Catalog)
                - end_date (Datetime)
                - code (str)
                - quantity (int)
                - start_date (Datetime)
                - voucher_type (str)
                - categories (list of Category objects)

        Returns:
            A coupon product object.

        Raises:
            IntegrityError: An error occured when create_vouchers method returns
                            an IntegrityError exception
            ValidationError: An error occured clean() validation method returns
                             a ValidationError exception
        """
        coupon_slug = generate_coupon_slug(title=title, catalog=data['catalog'], partner=data['partner'])

        product_class = ProductClass.objects.get(slug='coupon')
        coupon_product, __ = Product.objects.get_or_create(
            title=title,
            product_class=product_class,
            slug=coupon_slug
        )

        for category in data['categories']:
            ProductCategory.objects.get_or_create(product=coupon_product, category=category)

        # Vouchers are created during order and not fulfillment like usual
        # because we want vouchers to be part of the line in the order.
        try:
            create_vouchers(
                name=title,
                benefit_type=data['benefit_type'],
                benefit_value=Decimal(data['benefit_value']),
                catalog=data['catalog'],
                coupon=coupon_product,
                end_datetime=data['end_date'],
                code=data['code'] or None,
                quantity=int(data['quantity']),
                start_datetime=data['start_date'],
                voucher_type=data['voucher_type']
            )
        except IntegrityError as ex:
            logger.exception('Failed to create vouchers for [%s] coupon.', coupon_product.title)
            raise IntegrityError(ex)  # pylint: disable=nonstandard-exception

        coupon_vouchers = CouponVouchers.objects.get(coupon=coupon_product)

        coupon_product.attr.coupon_vouchers = coupon_vouchers
        coupon_product.save()

        sku = generate_sku(
            product=coupon_product,
            partner=data['partner'],
            catalog=data['catalog'],
        )

        stock_record, __ = StockRecord.objects.get_or_create(
            product=coupon_product,
            partner=data['partner'],
            partner_sku=sku
        )
        stock_record.price_currency = 'USD'
        stock_record.price_excl_tax = price
        stock_record.save()

        return coupon_product
Example #14
0
    def create_coupon_product(self, title, price, data):
        """Creates a coupon product and a stock record for it.

        Arguments:
            title (str): The name of the coupon.
            price (int): The price of the coupon(s).
            data (dict): Contains data needed to create vouchers,SKU and UPC:
                - partner (User)
                - benefit_type (str)
                - benefit_value (int)
                - catalog (Catalog)
                - end_date (Datetime)
                - code (str)
                - quantity (int)
                - start_date (Datetime)
                - voucher_type (str)
                - categories (list of Category objects)
                - note (str)
                - max_uses (int)

        Returns:
            A coupon product object.

        Raises:
            IntegrityError: An error occured when create_vouchers method returns
                            an IntegrityError exception
        """
        coupon_slug = generate_coupon_slug(title=title, catalog=data['catalog'], partner=data['partner'])

        product_class = ProductClass.objects.get(slug='coupon')
        coupon_product, __ = Product.objects.get_or_create(
            title=title,
            product_class=product_class,
            slug=coupon_slug
        )

        self.assign_categories_to_coupon(coupon=coupon_product, categories=data['categories'])

        # Vouchers are created during order and not fulfillment like usual
        # because we want vouchers to be part of the line in the order.
        try:
            create_vouchers(
                name=title,
                benefit_type=data['benefit_type'],
                benefit_value=Decimal(data['benefit_value']),
                catalog=data['catalog'],
                coupon=coupon_product,
                end_datetime=data['end_date'],
                code=data['code'] or None,
                quantity=int(data['quantity']),
                start_datetime=data['start_date'],
                voucher_type=data['voucher_type'],
                max_uses=data['max_uses'],
                coupon_id=coupon_product.id
            )
        except IntegrityError as ex:
            logger.exception('Failed to create vouchers for [%s] coupon.', coupon_product.title)
            raise IntegrityError(ex)  # pylint: disable=nonstandard-exception

        coupon_vouchers = CouponVouchers.objects.get(coupon=coupon_product)

        coupon_product.attr.coupon_vouchers = coupon_vouchers
        coupon_product.attr.note = data['note']
        coupon_product.save()

        sku = generate_sku(
            product=coupon_product,
            partner=data['partner'],
            catalog=data['catalog'],
        )

        stock_record, __ = StockRecord.objects.get_or_create(
            product=coupon_product,
            partner=data['partner'],
            partner_sku=sku
        )
        stock_record.price_currency = 'USD'
        stock_record.price_excl_tax = price
        stock_record.save()

        return coupon_product
Example #15
0
    def create_coupon_product(self, title, price, data):
        """Creates a coupon product and a stock record for it.

        Arguments:
            title (str): The name of the coupon.
            price (int): The price of the coupon(s).
            data (dict): Contains data needed to create vouchers,SKU and UPC:
                - partner (User)
                - benefit_type (str)
                - benefit_value (int)
                - catalog (Catalog)
                - end_date (Datetime)
                - code (str)
                - quantity (int)
                - start_date (Datetime)
                - voucher_type (str)
                - categories (list of Category objects)
                - note (str)
                - max_uses (int)
                - catalog_query (str)
                - course_seat_types (str)

        Returns:
            A coupon product object.
        """

        product_class = ProductClass.objects.get(slug='coupon')
        coupon_product = Product.objects.create(title=title, product_class=product_class)

        self.assign_categories_to_coupon(coupon=coupon_product, categories=data['categories'])

        # Vouchers are created during order and not fulfillment like usual
        # because we want vouchers to be part of the line in the order.
        create_vouchers(
            name=title,
            benefit_type=data['benefit_type'],
            benefit_value=Decimal(data['benefit_value']),
            catalog=data['catalog'],
            coupon=coupon_product,
            end_datetime=data['end_date'],
            code=data['code'] or None,
            quantity=int(data['quantity']),
            start_datetime=data['start_date'],
            voucher_type=data['voucher_type'],
            max_uses=data['max_uses'],
            catalog_query=data['catalog_query'],
            course_seat_types=data['course_seat_types']
        )

        coupon_vouchers = CouponVouchers.objects.get(coupon=coupon_product)

        coupon_product.attr.coupon_vouchers = coupon_vouchers
        coupon_product.attr.note = data['note']
        coupon_product.save()

        sku = generate_sku(product=coupon_product, partner=data['partner'])
        StockRecord.objects.update_or_create(
            product=coupon_product,
            partner=data['partner'],
            partner_sku=sku,
            defaults={
                'price_currency': 'USD',
                'price_excl_tax': price
            }
        )

        return coupon_product
Example #16
0
def create_coupon_product(benefit_type, benefit_value, catalog, catalog_query,
                          category, code, course_seat_types, email_domains,
                          end_datetime, enterprise_customer,
                          enterprise_customer_catalog, max_uses, note, partner,
                          price, quantity, start_datetime, title, voucher_type,
                          course_catalog, program_uuid, site, sales_force_id):
    """
    Creates a coupon product and a stock record for it.

    Arguments:
        benefit_type (str): Voucher Benefit type.
        benefit_value (int): Voucher Benefit value.
        catalog (Catalog): Catalog used to create a range of products.
        catalog_query (str): ElasticSearch query used by dynamic coupons.
        category (dict): Contains category ID and name.
        code (str): Voucher code.
        course_seat_types (str): Comma-separated list of course seat types.
        course_catalog (int): Course catalog id from Discovery Service
        email_domains (str): Comma-separated list of email domains.
        end_datetime (Datetime): Voucher end Datetime.
        enterprise_customer (str): UUID of an EnterpriseCustomer to attach to this voucher
        enterprise_customer_catalog (str): UUID of an EnterpriseCustomerCatalog to attach to this voucher
        max_uses (int): Number of Voucher max uses.
        note (str): Coupon note.
        partner (User): Partner associated with coupon Stock Record.
        price (int): The price of the coupon.
        quantity (int): Number of vouchers to be created and associated with the coupon.
        start_datetime (Datetime): Voucher start Datetime.
        title (str): The name of the coupon.
        voucher_type (str): Voucher type
        program_uuid (str): Program UUID for the Coupon
        site (site): Site for which the Coupon is created.
        sales_force_id (str): Sales Force Opprtunity ID

    Returns:
        A coupon Product object.

    Raises:
        IntegrityError: An error occurred when create_vouchers method returns
                        an IntegrityError exception
    """
    coupon_product = create_coupon_product_and_stockrecord(
        title, category, partner, price)

    # Vouchers are created during order and not fulfillment like usual
    # because we want vouchers to be part of the line in the order.

    try:
        vouchers = create_vouchers(
            benefit_type=benefit_type,
            benefit_value=benefit_value,
            catalog=catalog,
            catalog_query=catalog_query,
            code=code or None,
            coupon=coupon_product,
            course_catalog=course_catalog,
            course_seat_types=course_seat_types,
            email_domains=email_domains,
            end_datetime=end_datetime,
            enterprise_customer=enterprise_customer,
            enterprise_customer_catalog=enterprise_customer_catalog,
            max_uses=max_uses,
            name=title,
            quantity=int(quantity),
            start_datetime=start_datetime,
            voucher_type=voucher_type,
            program_uuid=program_uuid,
            site=site)
    except IntegrityError:
        logger.exception('Failed to create vouchers for [%s] coupon.',
                         coupon_product.title)
        raise

    attach_vouchers_to_coupon_product(coupon_product,
                                      vouchers,
                                      note,
                                      enterprise_id=enterprise_customer,
                                      sales_force_id=sales_force_id)

    return coupon_product
Example #17
0
 def test_create_vouchers_with_incorrect_datetime_value(self, data):
     """ Test calling create vouchers with incorrect start/end datetime value raises exception. """
     self.data.update(data)
     with self.assertRaises(ValidationError):
         create_vouchers(**self.data)
Example #18
0
def create_coupon_product(
        benefit_type,
        benefit_value,
        catalog,
        catalog_query,
        category,
        code,
        course_seat_types,
        email_domains,
        end_datetime,
        enterprise_customer,
        max_uses,
        note,
        partner,
        price,
        quantity,
        start_datetime,
        title,
        voucher_type,
        course_catalog,
):
    """
    Creates a coupon product and a stock record for it.

    Arguments:
        benefit_type (str): Voucher Benefit type.
        benefit_value (int): Voucher Benefit value.
        catalog (Catalog): Catalog used to create a range of products.
        catalog_query (str): ElasticSearch query used by dynamic coupons.
        category (dict): Contains category ID and name.
        code (str): Voucher code.
        course_seat_types (str): Comma-separated list of course seat types.
        course_catalog (int): Course catalog id from Catalog Service
        email_domains (str): Comma-separated list of email domains.
        end_datetime (Datetime): Voucher end Datetime.
        enterprise_customer (str): UUID of an EnterpriseCustomer to attach to this voucher
        max_uses (int): Number of Voucher max uses.
        note (str): Coupon note.
        partner (User): Partner associated with coupon Stock Record.
        price (int): The price of the coupon.
        quantity (int): Number of vouchers to be created and associated with the coupon.
        start_datetime (Datetime): Voucher start Datetime.
        title (str): The name of the coupon.
        voucher_type (str): Voucher type

    Returns:
        A coupon Product object.

    Raises:
        IntegrityError: An error occured when create_vouchers method returns
                        an IntegrityError exception
    """
    product_class = ProductClass.objects.get(slug='coupon')
    coupon_product = Product.objects.create(title=title, product_class=product_class)
    ProductCategory.objects.get_or_create(product=coupon_product, category=category)

    # Vouchers are created during order and not fulfillment like usual
    # because we want vouchers to be part of the line in the order.

    try:
        create_vouchers(
            benefit_type=benefit_type,
            benefit_value=benefit_value,
            catalog=catalog,
            catalog_query=catalog_query,
            code=code or None,
            coupon=coupon_product,
            course_catalog=course_catalog,
            course_seat_types=course_seat_types,
            email_domains=email_domains,
            end_datetime=end_datetime,
            enterprise_customer=enterprise_customer,
            max_uses=max_uses,
            name=title,
            quantity=int(quantity),
            start_datetime=start_datetime,
            voucher_type=voucher_type
        )
    except IntegrityError:
        logger.exception('Failed to create vouchers for [%s] coupon.', coupon_product.title)
        raise

    coupon_vouchers = CouponVouchers.objects.get(coupon=coupon_product)
    coupon_product.attr.coupon_vouchers = coupon_vouchers
    coupon_product.attr.note = note
    coupon_product.save()

    sku = generate_sku(product=coupon_product, partner=partner)
    StockRecord.objects.update_or_create(
        defaults={
            'price_currency': settings.OSCAR_DEFAULT_CURRENCY,
            'price_excl_tax': price
        },
        partner=partner,
        partner_sku=sku,
        product=coupon_product
    )

    return coupon_product
Example #19
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'])
        )
Example #20
0
    def fulfill_product(self, order, lines, email_opt_in=False):
        """ Fulfills the purchase of an Enrollment code product.
        For each line creates number of vouchers equal to that line's quantity. Creates a new OrderLineVouchers
        object to tie the order with the created voucher and adds the vouchers to the coupon's total vouchers.

        Args:
            order (Order): The Order associated with the lines to be fulfilled.
            lines (List of Lines): Order Lines, associated with purchased products in an Order.
            email_opt_in (bool): Whether the user should be opted in to emails
                as part of the fulfillment. Defaults to False.

        Returns:
            The original set of lines, with new statuses set based on the success or failure of fulfillment.
        """
        msg = "Attempting to fulfill '{product_class}' product types for order [{order_number}]".format(
            product_class=ENROLLMENT_CODE_PRODUCT_CLASS_NAME,
            order_number=order.number)
        logger.info(msg)

        for line in lines:
            name = 'Enrollment Code Range for {}'.format(
                line.product.attr.course_key)
            seat = Product.objects.filter(
                attributes__name='course_key',
                attribute_values__value_text=line.product.attr.course_key).get(
                    attributes__name='certificate_type',
                    attribute_values__value_text=line.product.attr.seat_type)
            _range, created = Range.objects.get_or_create(name=name)
            if created:
                _range.add_product(seat)

            stock_record = StockRecord.objects.get(product=seat,
                                                   partner=seat.course.partner)
            coupon_catalog = CouponViewSet.get_coupon_catalog(
                [stock_record.id], seat.course.partner)
            _range.catalog = coupon_catalog
            _range.save()

            vouchers = create_vouchers(
                name=str('Enrollment code voucher [{}]').format(
                    line.product.title),
                benefit_type=Benefit.PERCENTAGE,
                benefit_value=100,
                catalog=coupon_catalog,
                coupon=seat,
                end_datetime=settings.ENROLLMENT_CODE_EXIPRATION_DATE,
                enterprise_customer=None,
                enterprise_customer_catalog=None,
                quantity=line.quantity,
                start_datetime=datetime.datetime.now(),
                voucher_type=Voucher.SINGLE_USE,
                _range=_range)

            line_vouchers = OrderLineVouchers.objects.create(line=line)
            for voucher in vouchers:
                line_vouchers.vouchers.add(voucher)

            line.set_status(LINE.COMPLETE)

        # if the HubSpot integration is enabled and this is an Enterprise purchase then transmit information about the
        # order over to HubSpot
        if waffle.switch_is_active(HUBSPOT_FORMS_INTEGRATION_ENABLE
                                   ) and self.determine_if_enterprise_purchase(
                                       order):
            self.send_fulfillment_data_to_hubspot(order)

        self.send_email(order)
        logger.info(
            "Finished fulfilling 'Enrollment code' product types for order [%s]",
            order.number)
        return order, lines