Commit dc8665f7 by Vedran Karačić Committed by GitHub

Merge pull request #811 from edx/vkaracic/SOL-1819

[SOL-1819] Multi offer coupon.
parents 39ef7b72 b897debc
......@@ -134,6 +134,25 @@ class CouponViewSetTest(CouponMixin, CourseCatalogTestMixin, TestCase):
category = ProductCategory.objects.get(product=coupon).category
self.assertEqual(category, self.category)
def test_creating_multi_offer_coupon(self):
"""Test the creation of a multi-offer coupon."""
ordinary_max_uses = 1
ordinary_coupon = self.create_coupon(quantity=2, max_uses=ordinary_max_uses)
ordinary_coupon_vouchers = ordinary_coupon.attr.coupon_vouchers.vouchers.all()
self.assertEqual(
ordinary_coupon_vouchers[0].offers.first(),
ordinary_coupon_vouchers[1].offers.first()
)
self.assertEqual(ordinary_coupon_vouchers[0].offers.first().max_global_applications, ordinary_max_uses)
multi_offer_coupon = self.create_coupon(quantity=2, max_uses=2)
multi_offer_coupon_vouchers = multi_offer_coupon.attr.coupon_vouchers.vouchers.all()
first_offer = multi_offer_coupon_vouchers[0].offers.first()
second_offer = multi_offer_coupon_vouchers[1].offers.first()
self.assertNotEqual(first_offer, second_offer)
self.assertEqual(first_offer.max_global_applications, second_offer.max_global_applications)
def test_custom_code_string(self):
"""Test creating a coupon with custom voucher code."""
self.coupon_data.update({
......
......@@ -220,7 +220,9 @@ def generate_coupon_report(coupon_vouchers):
return field_names, rows
def _get_or_create_offer(product_range, benefit_type, benefit_value, coupon_id=None, max_uses=None):
def _get_or_create_offer(
product_range, benefit_type, benefit_value, coupon_id=None, max_uses=None, offer_number=None
):
"""
Return an offer for a catalog with condition and benefit.
......@@ -248,9 +250,8 @@ def _get_or_create_offer(product_range, benefit_type, benefit_value, coupon_id=N
)
offer_name = "Coupon [{}]-{}-{}".format(coupon_id, offer_benefit.type, offer_benefit.value)
if max_uses:
# Offer needs to be unique for each multi-use coupon.
offer_name = "{} (Coupon [{}] - max_uses:{})".format(offer_name, coupon_id, max_uses)
if offer_number:
offer_name = "{} [{}]".format(offer_name, offer_number)
offer, __ = ConditionalOffer.objects.get_or_create(
name=offer_name,
......@@ -359,6 +360,7 @@ def create_vouchers(
"""
logger.info("Creating [%d] vouchers product [%s]", quantity, coupon.id)
vouchers = []
offers = []
if _range:
# Enrollment codes use a custom range.
......@@ -374,18 +376,28 @@ def create_vouchers(
course_seat_types=course_seat_types
)
offer = _get_or_create_offer(
product_range=product_range,
benefit_type=benefit_type,
benefit_value=benefit_value,
max_uses=max_uses,
coupon_id=coupon.id
)
for __ in range(quantity):
# In case of more than 1 multi-usage coupon, each voucher needs to have an individual
# offer because the usage is tied to the offer so that a usage on one voucher would
# mean all vouchers will have their usage decreased by one, hence each voucher needs
# it's own offer to keep track of it's own usages without interfering with others.
multi_offer = True if quantity > 1 and max_uses > 1 else False
num_of_offers = quantity if multi_offer else 1
for num in range(num_of_offers):
offer = _get_or_create_offer(
product_range=product_range,
benefit_type=benefit_type,
benefit_value=benefit_value,
max_uses=max_uses,
coupon_id=coupon.id,
offer_number=num
)
offers.append(offer)
for i in range(quantity):
voucher = _create_new_voucher(
coupon=coupon,
end_datetime=end_datetime,
offer=offer,
offer=offers[i] if multi_offer else offers[0],
start_datetime=start_datetime,
voucher_type=voucher_type,
code=code,
......
......@@ -100,15 +100,6 @@ define([
expect(visible('[name=benefit_value]')).toBe(false);
expect(visible('[name=code]')).toBe(false);
});
it('should show the quantity field only for single-use vouchers', function () {
view.$el.find('[name=voucher_type]').val('Single use').trigger('change');
expect(visible('[name=quantity]')).toBe(true);
view.$el.find('[name=voucher_type]').val('Multi-use').trigger('change');
expect(visible('[name=quantity]')).toBe(false);
view.$el.find('[name=voucher_type]').val('Once per customer').trigger('change');
expect(visible('[name=quantity]')).toBe(false);
});
});
describe('discount code', function () {
......
......@@ -374,14 +374,6 @@ define([
} else {
this.hideField('[name=max_uses]', 1);
}
// The only time we allow for a generation of multiple codes is
// when they are of type single use.
if (voucherType === 'Single use') {
this.formGroup('[name=quantity]').removeClass(this.hiddenClass);
} else {
this.hideField('[name=quantity]', 1);
}
},
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment