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" )
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 )
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())
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']) )
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)
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 )
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'))
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
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'))
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)
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
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
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
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
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
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)
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
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']) )
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