def _get_or_create_discount_offer(self): """ Get or Create 100% discount offer for `Manual Enrollemnt Order`. """ condition, __ = Condition.objects.get_or_create(proxy_class=class_path(ManualEnrollmentOrderDiscountCondition)) benefit, _ = Benefit.objects.get_or_create( proxy_class=class_path(ManualEnrollmentOrderDiscountBenefit), value=100, max_affected_items=1, ) offer_kwargs = { 'offer_type': ConditionalOffer.USER, 'condition': condition, 'benefit': benefit, 'priority': OFFER_PRIORITY_MANUAL_ORDER, } offer, __ = ConditionalOffer.objects.get_or_create( name='Manual Course Enrollment Order Offer', defaults=offer_kwargs ) return offer
def test_create_ent_offers_switch_on(self): Switch.objects.update_or_create(name=ENTERPRISE_OFFERS_FOR_COUPONS_SWITCH, defaults={'active': True}) response = self.get_response('POST', ENTERPRISE_COUPONS_LINK, self.data) self.assertEqual(response.status_code, status.HTTP_200_OK) coupon = Product.objects.get(title=self.data['title']) enterprise_customer_id = self.data['enterprise_customer']['id'] enterprise_name = self.data['enterprise_customer']['name'] enterprise_catalog_id = self.data['enterprise_customer_catalog'] vouchers = coupon.attr.coupon_vouchers.vouchers.all() for voucher in vouchers: all_offers = voucher.offers.all() self.assertEqual(len(all_offers), 1) offer = all_offers[0] self.assertEqual(str(offer.condition.enterprise_customer_uuid), enterprise_customer_id) self.assertEqual(str(offer.condition.enterprise_customer_catalog_uuid), enterprise_catalog_id) self.assertEqual(offer.condition.proxy_class, class_path(AssignableEnterpriseCustomerCondition)) self.assertIsNone(offer.condition.range) self.assertEqual(offer.benefit.proxy_class, class_path(ENTERPRISE_BENEFIT_MAP[self.data['benefit_type']])) self.assertEqual(offer.benefit.value, self.data['benefit_value']) self.assertIsNone(offer.benefit.range) # Check that the enterprise name took precedence as the client name basket = Basket.objects.filter(lines__product_id=coupon.id).first() invoice = Invoice.objects.get(order__basket=basket) self.assertEqual(invoice.business_client.name, enterprise_name) self.assertEqual(str(invoice.business_client.enterprise_customer_uuid), enterprise_customer_id)
class OfferTests(TestCase): def test_benefit_discount(self): benefit = BenefitFactory(type=Benefit.PERCENTAGE, value=35.00) template = Template("{% load offer_tags %}" "{{ benefit|benefit_discount }}") self.assertEqual(template.render(Context({'benefit': benefit})), '35%') @ddt.data( ({ 'type': Benefit.PERCENTAGE }, Benefit.PERCENTAGE), ({ 'type': Benefit.FIXED }, Benefit.FIXED), ({ 'type': '', 'proxy_class': class_path(PercentageDiscountBenefitWithoutRange) }, Benefit.PERCENTAGE), ({ 'type': '', 'proxy_class': class_path(AbsoluteDiscountBenefitWithoutRange) }, Benefit.FIXED), ({ 'type': '', 'proxy_class': class_path(EnterprisePercentageDiscountBenefit) }, Benefit.PERCENTAGE), ({ 'type': '', 'proxy_class': class_path(EnterpriseAbsoluteDiscountBenefit) }, Benefit.FIXED), ) @ddt.unpack def test_benefit_type(self, factory_kwargs, expected): benefit = BenefitFactory(**factory_kwargs) self.assertEqual(benefit_type(benefit), expected)
def _get_or_create_discount_offer(self, enterprise_customer_name, enterprise_customer_uuid): """ Get or Create 100% discount offer for `Manual Enrollment Order`. """ condition, _ = Condition.objects.get_or_create( proxy_class=class_path(ManualEnrollmentOrderDiscountCondition), enterprise_customer_uuid=enterprise_customer_uuid) if condition.enterprise_customer_name != enterprise_customer_name: condition.enterprise_customer_name = enterprise_customer_name condition.save() benefit, _ = Benefit.objects.get_or_create( proxy_class=class_path(ManualEnrollmentOrderDiscountBenefit), value=100, max_affected_items=1, ) offer_kwargs = { 'offer_type': ConditionalOffer.USER, 'condition': condition, 'benefit': benefit, 'priority': OFFER_PRIORITY_MANUAL_ORDER, } offer, __ = ConditionalOffer.objects.get_or_create( name='Manual Course Enrollment Order Offer for enterprise {}'. format(enterprise_customer_uuid), defaults=offer_kwargs) return offer
def get_or_create_enterprise_offer(benefit_type, benefit_value, enterprise_customer, enterprise_customer_catalog, offer_name, site, max_uses=None, email_domains=None): enterprise_customer_object = get_enterprise_customer( site, enterprise_customer) if site else {} enterprise_customer_name = enterprise_customer_object.get('name', '') condition_kwargs = { 'proxy_class': class_path(AssignableEnterpriseCustomerCondition), 'enterprise_customer_uuid': enterprise_customer, 'enterprise_customer_name': enterprise_customer_name, 'enterprise_customer_catalog_uuid': enterprise_customer_catalog, 'type': Condition.COUNT, 'value': 1, } # Because there is a chance of duplicate Conditions, we are checking here for this case. # If duplicates are encountered, then grab the first matching Condition. try: condition, __ = Condition.objects.get_or_create(**condition_kwargs) except Condition.MultipleObjectsReturned: condition = Condition.objects.filter(**condition_kwargs).first() benefit, _ = Benefit.objects.get_or_create( proxy_class=class_path(ENTERPRISE_BENEFIT_MAP[benefit_type]), value=benefit_value, max_affected_items=1, ) offer_kwargs = { 'offer_type': ConditionalOffer.VOUCHER, 'condition': condition, 'benefit': benefit, 'max_global_applications': int(max_uses) if max_uses is not None else None, 'email_domains': email_domains, 'site': site, 'partner': site.siteconfiguration.partner if site else None, # For initial creation, we are setting the priority lower so that we don't want to use these # until we've done some other implementation work. We will update this to a higher value later. 'priority': 5, } offer, __ = ConditionalOffer.objects.update_or_create( name=offer_name, defaults=offer_kwargs) return offer
def _get_or_create_enterprise_offer(benefit_type, benefit_value, enterprise_customer, enterprise_customer_catalog, coupon_id=None, max_uses=None, offer_number=None, email_domains=None, site=None): enterprise_customer_object = get_enterprise_customer( site, enterprise_customer) if site else {} enterprise_customer_name = enterprise_customer_object.get('name', '') condition, __ = Condition.objects.get_or_create( proxy_class=class_path(EnterpriseCustomerCondition), enterprise_customer_uuid=enterprise_customer, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid=enterprise_customer_catalog, type=Condition.COUNT, value=1, ) benefit, _ = Benefit.objects.get_or_create( proxy_class=class_path(ENTERPRISE_BENEFIT_MAP[benefit_type]), value=benefit_value, max_affected_items=1, ) offer_name = "Coupon [{}]-{}-{} ENT Offer".format(coupon_id, benefit_type, benefit_value) if offer_number: offer_name = "{} [{}] ENT Offer".format(offer_name, offer_number) offer_kwargs = { 'offer_type': ConditionalOffer.VOUCHER, 'condition': condition, 'benefit': benefit, 'max_global_applications': max_uses, 'email_domains': email_domains, 'site': site, 'partner': site.siteconfiguration.partner if site else None, # For initial creation, we are setting the priority lower so that we don't want to use these # until we've done some other implementation work. We will update this to a higher value later. 'priority': 5, } offer, __ = ConditionalOffer.objects.update_or_create( name=offer_name, defaults=offer_kwargs) return offer
def save(self, commit=True): program_uuid = self.cleaned_data['program_uuid'] client = ProgramsApiClient(self.request.site.siteconfiguration.course_catalog_api_client) program = client.get_program(program_uuid) offer_name = _('Discount for the {program_title} {program_type} Program'.format( program_title=program['title'], program_type=program['type'] )) self.instance.name = offer_name self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 if commit: benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path(BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.program_uuid = program_uuid self.instance.condition.save() else: self.instance.condition = create_condition(ProgramCourseRunSeatsCondition, program_uuid=program_uuid) return super(ProgramOfferForm, self).save(commit)
def test_post(self): """ A new program offer should be created. """ expected_uuid = uuid.uuid4() self.mock_program_detail_endpoint( expected_uuid, self.site_configuration.discovery_api_url) expected_benefit_value = 10 data = { 'program_uuid': expected_uuid, 'benefit_type': Benefit.PERCENTAGE, 'benefit_value': expected_benefit_value, } existing_offer_ids = list(ConditionalOffer.objects.all().values_list( 'id', flat=True)) response = self.client.post(self.path, data, follow=False) conditional_offers = ConditionalOffer.objects.exclude( id__in=existing_offer_ids) program_offer = conditional_offers.first() self.assertEqual(conditional_offers.count(), 1) self.assertRedirects( response, reverse('programs:offers:edit', kwargs={'pk': program_offer.pk})) self.assertIsNone(program_offer.start_datetime) self.assertIsNone(program_offer.end_datetime) self.assertEqual(program_offer.condition.program_uuid, expected_uuid) self.assertEqual(program_offer.benefit.type, '') self.assertEqual(program_offer.benefit.value, expected_benefit_value) self.assertEqual(program_offer.benefit.proxy_class, class_path(PercentageDiscountBenefitWithoutRange))
def test_post(self): """ A new enterprise offer should be created. """ expected_ec_uuid = uuid.uuid4() expected_ec_catalog_uuid = uuid.uuid4() self.mock_specific_enterprise_customer_api(expected_ec_uuid) expected_benefit_value = 10 data = { 'enterprise_customer_uuid': expected_ec_uuid, 'enterprise_customer_catalog_uuid': expected_ec_catalog_uuid, 'benefit_type': Benefit.PERCENTAGE, 'benefit_value': expected_benefit_value, } response = self.client.post(self.path, data, follow=False) enterprise_offer = ConditionalOffer.objects.get() self.assertRedirects( response, reverse('enterprise:offers:edit', kwargs={'pk': enterprise_offer.pk})) self.assertIsNone(enterprise_offer.start_datetime) self.assertIsNone(enterprise_offer.end_datetime) self.assertEqual(enterprise_offer.condition.enterprise_customer_uuid, expected_ec_uuid) self.assertEqual( enterprise_offer.condition.enterprise_customer_catalog_uuid, expected_ec_catalog_uuid) self.assertEqual(enterprise_offer.benefit.type, '') self.assertEqual(enterprise_offer.benefit.value, expected_benefit_value) self.assertEqual(enterprise_offer.benefit.proxy_class, class_path(EnterprisePercentageDiscountBenefit))
def assert_enterprise_offer_conditions(self, offer, enterprise_customer_uuid, enterprise_customer_name, enterprise_customer_catalog_uuid, expected_benefit_value, expected_benefit_type, expected_name, expected_contract_discount_type, expected_contract_discount_value, expected_prepaid_invoice_amount, expected_sales_force_id, expected_max_global_applications, expected_max_discount): """ Assert the given offer's parameters match the expected values. """ self.assertEqual(str(offer.name), expected_name) self.assertEqual(offer.offer_type, ConditionalOffer.SITE) self.assertEqual(offer.sales_force_id, expected_sales_force_id) self.assertEqual(offer.status, ConditionalOffer.OPEN) self.assertEqual(offer.max_basket_applications, 1) self.assertEqual(offer.partner, self.partner) self.assertEqual(offer.priority, OFFER_PRIORITY_ENTERPRISE) self.assertEqual(offer.condition.enterprise_customer_uuid, enterprise_customer_uuid) self.assertEqual(offer.condition.enterprise_customer_name, enterprise_customer_name) self.assertEqual(offer.condition.enterprise_customer_catalog_uuid, enterprise_customer_catalog_uuid) self.assertEqual(offer.benefit.proxy_class, class_path(BENEFIT_MAP[expected_benefit_type])) self.assertEqual(offer.benefit.value, expected_benefit_value) self.assertEqual( offer.enterprise_contract_metadata.discount_type, expected_contract_discount_type ) self.assertEqual( offer.enterprise_contract_metadata.discount_value, expected_contract_discount_value ) self.assertEqual( offer.enterprise_contract_metadata.amount_paid, expected_prepaid_invoice_amount ) self.assertEqual(offer.max_global_applications, expected_max_global_applications) self.assertEqual(offer.max_discount, expected_max_discount)
def test_update_coupon_with_program_uuid(self): """Verify update coupon program uuid.""" program_uuid = str(uuid4()) proxy_class = class_path(BENEFIT_MAP[self.data['benefit_type']]) self.data.update({ 'program_uuid': program_uuid, 'title': 'Program Coupon', 'enterprise_customer': None, 'stock_record_ids': [] }) self.assertEqual(Benefit.objects.filter(proxy_class=proxy_class).count(), 0) self.assertEqual(Condition.objects.filter(program_uuid=self.data['program_uuid']).count(), 0) details = self._create_and_get_coupon_details() self.assertEqual(details['program_uuid'], program_uuid) self.assertEqual(details['title'], self.data['title']) self.assertEqual(Benefit.objects.filter(proxy_class=proxy_class).count(), 1) self.assertEqual(Condition.objects.filter(program_uuid=self.data['program_uuid']).count(), 1) edited_program_uuid = str(uuid4()) coupon = Product.objects.get(title=self.data['title']) response_data = self.get_response_json( 'PUT', reverse('api:v2:coupons-detail', kwargs={'pk': coupon.pk}), data={'program_uuid': edited_program_uuid} ) self.assertEqual(response_data['program_uuid'], edited_program_uuid) self.assertEqual(response_data['title'], self.data['title']) self.assertEqual(Benefit.objects.filter(proxy_class=proxy_class).count(), 1) self.assertEqual(Condition.objects.filter(program_uuid=edited_program_uuid).count(), 1)
class JournalConditionFactory(ConditionFactory): range = None type = '' value = None journal_bundle_uuid = factory.LazyFunction(uuid.uuid4) proxy_class = class_path(JournalBundleCondition) class Meta(object): model = JournalBundleCondition
class ProgramCourseRunSeatsConditionFactory(ConditionFactory): range = None type = '' value = None program_uuid = factory.LazyFunction(uuid.uuid4) proxy_class = class_path(ProgramCourseRunSeatsCondition) class Meta: model = ProgramCourseRunSeatsCondition
def test_post(self): """ A new enterprise offer should be created. """ expected_ec_uuid = uuid.uuid4() expected_ec_catalog_uuid = uuid.uuid4() self.mock_specific_enterprise_customer_api(expected_ec_uuid) expected_benefit_value = 10 expected_discount_value = 2000 expected_discount_type = 'Absolute' expected_prepaid_invoice_amount = 12345 sales_force_id = '006abcde0123456789' data = { 'enterprise_customer_uuid': expected_ec_uuid, 'enterprise_customer_catalog_uuid': expected_ec_catalog_uuid, 'benefit_type': Benefit.PERCENTAGE, 'benefit_value': expected_benefit_value, 'contract_discount_value': expected_discount_value, 'contract_discount_type': expected_discount_type, 'prepaid_invoice_amount': expected_prepaid_invoice_amount, 'sales_force_id': sales_force_id, 'usage_email_frequency': ConditionalOffer.DAILY } existing_offer_ids = list(ConditionalOffer.objects.all().values_list( 'id', flat=True)) response = self.client.post(self.path, data, follow=False) conditional_offers = ConditionalOffer.objects.exclude( id__in=existing_offer_ids) enterprise_offer = conditional_offers.first() self.assertEqual(conditional_offers.count(), 1) self.assertRedirects( response, reverse('enterprise:offers:edit', kwargs={'pk': enterprise_offer.pk})) self.assertIsNone(enterprise_offer.start_datetime) self.assertIsNone(enterprise_offer.end_datetime) self.assertEqual(enterprise_offer.sales_force_id, sales_force_id) self.assertEqual(enterprise_offer.condition.enterprise_customer_uuid, expected_ec_uuid) self.assertEqual( enterprise_offer.condition.enterprise_customer_catalog_uuid, expected_ec_catalog_uuid) self.assertEqual(enterprise_offer.benefit.type, '') self.assertEqual(enterprise_offer.benefit.value, expected_benefit_value) self.assertEqual(enterprise_offer.benefit.proxy_class, class_path(EnterprisePercentageDiscountBenefit)) self.assertEqual( enterprise_offer.enterprise_contract_metadata.discount_value, expected_discount_value) self.assertEqual( enterprise_offer.enterprise_contract_metadata.discount_type, expected_discount_type) self.assertEqual( enterprise_offer.enterprise_contract_metadata.amount_paid, expected_prepaid_invoice_amount)
def assert_program_offer_conditions(self, offer, program_uuid, expected_benefit_value, expected_benefit_type, expected_name): """ Assert the given offer's parameters match the expected values. """ self.assertEqual(str(offer.name), expected_name) self.assertEqual(offer.offer_type, ConditionalOffer.SITE) self.assertEqual(offer.status, ConditionalOffer.OPEN) self.assertEqual(offer.max_basket_applications, 1) self.assertEqual(offer.site, self.site) self.assertEqual(offer.condition.program_uuid, program_uuid) self.assertEqual(offer.benefit.proxy_class, class_path(BENEFIT_MAP[expected_benefit_type])) self.assertEqual(offer.benefit.value, expected_benefit_value)
class EnterpriseCustomerConditionFactory(ConditionFactory): range = None type = '' value = None enterprise_customer_uuid = factory.LazyFunction(uuid.uuid4) enterprise_customer_name = factory.Faker('word') enterprise_customer_catalog_uuid = factory.LazyFunction(uuid.uuid4) proxy_class = class_path(EnterpriseCustomerCondition) class Meta: model = EnterpriseCustomerCondition
def _migrate_voucher(self, voucher): offer = voucher.offers.order_by('date_created')[0] enterprise_customer_uuid = offer.condition.range.enterprise_customer site = offer.site or self._get_default_site() enterprise_customer = self._get_enterprise_customer( enterprise_customer_uuid, site) enterprise_customer_name = enterprise_customer['name'] new_condition, _ = Condition.objects.get_or_create( proxy_class=class_path(EnterpriseCustomerCondition), enterprise_customer_uuid=enterprise_customer_uuid, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid=offer.condition.range. enterprise_customer_catalog, type=Condition.COUNT, value=1, ) new_benefit, _ = Benefit.objects.get_or_create( proxy_class=class_path(BENEFIT_MAP[offer.benefit.type]), value=offer.benefit.value, max_affected_items=offer.benefit.max_affected_items, ) offer_name = offer.name + " ENT Offer" new_offer, _ = ConditionalOffer.objects.get_or_create( name=offer_name, offer_type=ConditionalOffer.VOUCHER, condition=new_condition, benefit=new_benefit, max_global_applications=offer.max_global_applications, email_domains=offer.email_domains, site=offer.site, partner=offer.partner, # For initial creation, we are setting the priority lower so that we don't want to use these # until we've done some other implementation work. We will update this to a higher value later. priority=5, ) voucher.offers.add(new_offer) voucher.save()
class ProgramOfferTemplateTagTests(TestCase): @ddt.data( ({ 'type': Benefit.PERCENTAGE }, Benefit.PERCENTAGE), ({ 'type': Benefit.FIXED }, Benefit.FIXED), ({ 'type': '', 'proxy_class': class_path(PercentageDiscountBenefitWithoutRange) }, Benefit.PERCENTAGE), ({ 'type': '', 'proxy_class': class_path(AbsoluteDiscountBenefitWithoutRange) }, Benefit.FIXED), ) @ddt.unpack def test_benefit_type(self, factory_kwargs, expected): benefit = BenefitFactory(**factory_kwargs) self.assertEqual(benefit_type(benefit), expected)
def _migrate_voucher(self, voucher): offer = voucher.offers.order_by('date_created')[0] enterprise_customer_uuid = offer.condition.range.enterprise_customer site = offer.site or self._get_default_site() enterprise_customer = self._get_enterprise_customer( enterprise_customer_uuid, site) enterprise_customer_name = enterprise_customer['name'] new_condition, _ = Condition.objects.get_or_create( proxy_class=class_path(EnterpriseCustomerCondition), enterprise_customer_uuid=enterprise_customer_uuid, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid=offer.condition.range. enterprise_customer_catalog, type=Condition.COUNT, value=1, ) new_benefit, _ = Benefit.objects.get_or_create( proxy_class=class_path(BENEFIT_MAP[offer.benefit.type]), value=offer.benefit.value, max_affected_items=offer.benefit.max_affected_items, ) offer_name = offer.name + " ENT Offer" new_offer, _ = ConditionalOffer.objects.get_or_create( name=offer_name, offer_type=ConditionalOffer.VOUCHER, condition=new_condition, benefit=new_benefit, max_global_applications=offer.max_global_applications, email_domains=offer.email_domains, site=offer.site, partner=offer.partner, priority=OFFER_PRIORITY_VOUCHER, ) voucher.offers.add(new_offer) voucher.save()
def save(self, commit=True): enterprise_customer_uuid = self.cleaned_data[ 'enterprise_customer_uuid'] enterprise_customer_catalog_uuid = self.cleaned_data[ 'enterprise_customer_catalog_uuid'] site = self.request.site enterprise_customer = get_enterprise_customer( site, enterprise_customer_uuid) enterprise_customer_name = enterprise_customer['name'] # Note: the actual name is not displayed like this in the template, so it's safe to use the UUID here. # And in fact we have to, because otherwise we face integrity errors since Oscar forces this name to be unique. # Truncate 'enterprise_customer_name' to 48 characters so that our complete name with # format 'Discount of type {site} provided by {enterprise_name} for {catalog_uuid}. does # not exceed the limit of 128 characters for Oscar's 'AbstractConditionalOffer' name. offer_name = _(u'Discount of type {} provided by {} for {}.'.format( ConditionalOffer.SITE, enterprise_customer_name[:48], # pylint: disable=unsubscriptable-object, enterprise_customer_catalog_uuid)) self.instance.name = offer_name self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 self.instance.partner = site.siteconfiguration.partner self.instance.priority = OFFER_PRIORITY_ENTERPRISE if commit: benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path( BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.enterprise_customer_uuid = enterprise_customer_uuid self.instance.condition.enterprise_customer_name = enterprise_customer_name self.instance.condition.enterprise_customer_catalog_uuid = enterprise_customer_catalog_uuid self.instance.condition.save() else: self.instance.condition = create_condition( EnterpriseCustomerCondition, enterprise_customer_uuid=enterprise_customer_uuid, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid= enterprise_customer_catalog_uuid, ) return super(EnterpriseOfferForm, self).save(commit)
def prepare_enterprise_voucher(code='COUPONTEST', start_datetime=None, end_datetime=None, benefit_value=100, benefit_type=Benefit.PERCENTAGE, usage=Voucher.SINGLE_USE, enterprise_customer=None, enterprise_customer_catalog=None): """ Helper function to create a voucher and add an enterprise conditional offer to it. """ if start_datetime is None: start_datetime = now() - timedelta(days=1) if end_datetime is None: end_datetime = now() + timedelta(days=10) voucher = VoucherFactory(code=code, start_datetime=start_datetime, end_datetime=end_datetime, usage=usage) benefit = BenefitFactory( proxy_class=class_path(ENTERPRISE_BENEFIT_MAP[benefit_type]), value=benefit_value, type='', range=None, ) condition = ConditionFactory( proxy_class=class_path(EnterpriseCustomerCondition), enterprise_customer_uuid=enterprise_customer, enterprise_customer_catalog_uuid=enterprise_customer_catalog, range=None, ) offer = ConditionalOfferFactory(offer_type=ConditionalOffer.VOUCHER, benefit=benefit, condition=condition, priority=OFFER_PRIORITY_VOUCHER) voucher.offers.add(offer) return voucher
def assert_enterprise_offer_conditions(self, offer, enterprise_customer_uuid, enterprise_customer_name, enterprise_customer_catalog_uuid, expected_benefit_value, expected_benefit_type, expected_name): """ Assert the given offer's parameters match the expected values. """ self.assertEqual(str(offer.name), expected_name) self.assertEqual(offer.offer_type, ConditionalOffer.SITE) self.assertEqual(offer.status, ConditionalOffer.OPEN) self.assertEqual(offer.max_basket_applications, 1) self.assertEqual(offer.partner, self.partner) self.assertEqual(offer.priority, OFFER_PRIORITY_ENTERPRISE) self.assertEqual(offer.condition.enterprise_customer_uuid, enterprise_customer_uuid) self.assertEqual(offer.condition.enterprise_customer_name, enterprise_customer_name) self.assertEqual(offer.condition.enterprise_customer_catalog_uuid, enterprise_customer_catalog_uuid) self.assertEqual(offer.benefit.proxy_class, class_path(BENEFIT_MAP[expected_benefit_type])) self.assertEqual(offer.benefit.value, expected_benefit_value)
def save(self, commit=True): enterprise_customer_uuid = self.cleaned_data[ 'enterprise_customer_uuid'] enterprise_customer_catalog_uuid = self.cleaned_data[ 'enterprise_customer_catalog_uuid'] site = self.request.site enterprise_customer = get_enterprise_customer( site, enterprise_customer_uuid) enterprise_customer_name = enterprise_customer['name'] # Note: the actual name is not displayed like this in the template, so it's safe to use the UUID here. # And in fact we have to, because otherwise we face integrity errors since Oscar forces this name to be unique. self.instance.name = _( u'Discount of type {} provided by {} for {}.'.format( ConditionalOffer.SITE, enterprise_customer_name, enterprise_customer_catalog_uuid, )) self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 self.instance.site = site self.instance.priority = OFFER_PRIORITY_ENTERPRISE if commit: benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path( BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.enterprise_customer_uuid = enterprise_customer_uuid self.instance.condition.enterprise_customer_name = enterprise_customer_name self.instance.condition.enterprise_customer_catalog_uuid = enterprise_customer_catalog_uuid self.instance.condition.save() else: self.instance.condition = create_condition( EnterpriseCustomerCondition, enterprise_customer_uuid=enterprise_customer_uuid, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid= enterprise_customer_catalog_uuid, ) return super(EnterpriseOfferForm, self).save(commit)
def test_create_coupon_with_program_uuid(self): """Verify create coupon with program uuid.""" proxy_class = class_path(BENEFIT_MAP[self.data['benefit_type']]) self.data.update({ 'program_uuid': str(uuid4()), 'title': 'Program Coupon', 'enterprise_customer': None, 'stock_record_ids': [] }) self.assertEqual(Benefit.objects.filter(proxy_class=proxy_class).count(), 0) self.assertEqual(Condition.objects.filter(program_uuid=self.data['program_uuid']).count(), 0) details = self._create_and_get_coupon_details() self.assertEqual(details['program_uuid'], self.data['program_uuid']) self.assertEqual(details['title'], self.data['title']) self.assertEqual(Benefit.objects.filter(proxy_class=proxy_class).count(), 1) self.assertEqual(Condition.objects.filter(program_uuid=self.data['program_uuid']).count(), 1)
def _assert_journal_bundle_offer_conditions(self, offer, journal_bundle_uuid, expected_benefit_value, expected_benefit_type, expected_name): """ Assert the given offer's parameters with the expected values. """ self.assertEqual(str(offer.name), expected_name) self.assertEqual(offer.offer_type, ConditionalOffer.SITE) self.assertEqual(offer.status, ConditionalOffer.OPEN) self.assertEqual(offer.max_basket_applications, 1) self.assertEqual(offer.partner, self.partner) self.assertEqual(offer.condition.journal_bundle_uuid, journal_bundle_uuid) self.assertEqual(offer.benefit.proxy_class, class_path(BENEFIT_MAP[expected_benefit_type])) self.assertEqual(offer.benefit.value, expected_benefit_value)
def save(self, commit=True): enterprise_customer_uuid = self.cleaned_data[ 'enterprise_customer_uuid'] enterprise_customer_catalog_uuid = self.cleaned_data[ 'enterprise_customer_catalog_uuid'] site = self.request.site enterprise_customer = get_enterprise_customer( site, enterprise_customer_uuid) enterprise_customer_name = enterprise_customer['name'] self.instance.name = _( u'Discount provided by {enterprise_customer_name}.'.format( enterprise_customer_name=enterprise_customer_name)) self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 self.instance.site = site self.instance.priority = OFFER_PRIORITY_ENTERPRISE if commit: benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path( BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.enterprise_customer_uuid = enterprise_customer_uuid self.instance.condition.enterprise_customer_name = enterprise_customer_name self.instance.condition.enterprise_customer_catalog_uuid = enterprise_customer_catalog_uuid self.instance.condition.save() else: self.instance.condition = create_condition( EnterpriseCustomerCondition, enterprise_customer_uuid=enterprise_customer_uuid, enterprise_customer_name=enterprise_customer_name, enterprise_customer_catalog_uuid= enterprise_customer_catalog_uuid, ) return super(EnterpriseOfferForm, self).save(commit)
def test_post(self): """ A new program offer should be created. """ expected_uuid = uuid.uuid4() self.mock_program_detail_endpoint(expected_uuid) expected_benefit_value = 10 data = { 'program_uuid': expected_uuid, 'benefit_type': Benefit.PERCENTAGE, 'benefit_value': expected_benefit_value, } response = self.client.post(self.path, data, follow=False) program_offer = ConditionalOffer.objects.get() self.assertRedirects(response, reverse('programs:offers:edit', kwargs={'pk': program_offer.pk})) self.assertIsNone(program_offer.start_datetime) self.assertIsNone(program_offer.end_datetime) self.assertEqual(program_offer.condition.program_uuid, expected_uuid) self.assertEqual(program_offer.benefit.type, '') self.assertEqual(program_offer.benefit.value, expected_benefit_value) self.assertEqual(program_offer.benefit.proxy_class, class_path(PercentageDiscountBenefitWithoutRange))
def handle(self, *args, **options): enterprise_customer = options['enterprise_customer'] discount_percentage = options['discount_percentage'] start_date = options['start_date'] logger.info( 'Updating all Manual Orders for Enterprise [%s] to have a discount of [%f].', enterprise_customer, discount_percentage) # An enterprise should only have a single ManualEnrollmentOrderDiscountCondition used for # API enrollment orders try: condition = Condition.objects.get( proxy_class=class_path(ManualEnrollmentOrderDiscountCondition), enterprise_customer_uuid=enterprise_customer) except Condition.DoesNotExist: logger.exception( 'Unable to find ManualEnrollmentOrderDiscountCondition for enterprise [%s]', enterprise_customer) return # Using the ConditionalOffer we can then get back to a list of OrderDiscounts and Orders try: offer = ConditionalOffer.objects.get(condition=condition) except ConditionalOffer.DoesNotExist: logger.exception('Unable to find ConditionalOffer for [%s]', condition) return discounts = OrderDiscount.objects.filter( offer_id=offer.id).select_related('order') if start_date: discounts = discounts.filter(order__date_placed__gte=start_date) for discount in discounts: order = discount.order # ManualEnrollment orders only have one order_line per order, so no need to loop over lines here self.update_orderline_with_enterprise_discount_metadata( order=order, line=order.lines.first(), discount_percentage=Decimal(discount_percentage), is_manual_order=True)
def save(self, commit=True): program_uuid = self.cleaned_data['program_uuid'] site = self.request.site current_date = str(datetime.today().strftime('%Y-%m-%d')) client = ProgramsApiClient(site.siteconfiguration.discovery_api_client, site.domain) program = client.get_program(program_uuid) offer_name = _( u'{current_date} Discount for the {program_title} {program_type} Program' .format(current_date=current_date, program_title=program['title'], program_type=program['type'])) # Truncate offer_names down to 128 characters, as Oscar's AbstractConditionalOffer name is max_length 128 offer_name = (offer_name[:125] + '...') if len(offer_name) > 128 else offer_name # pylint: disable=unsubscriptable-object self.instance.name = offer_name self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 self.instance.partner = site.siteconfiguration.partner if commit: benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path( BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.program_uuid = program_uuid self.instance.condition.save() else: self.instance.condition = create_condition( ProgramCourseRunSeatsCondition, program_uuid=program_uuid) return super(ProgramOfferForm, self).save(commit)
def save(self, commit=True): journal_bundle_uuid = self.cleaned_data['journal_bundle_uuid'] site = self.request.site journal_bundle = fetch_journal_bundle( site=site, journal_bundle_uuid=journal_bundle_uuid ) offer_name = 'Journal Bundle Offer: {title}'.format( title=journal_bundle['title'] ) # Truncate offer_names down to 128 characters, as Oscar's AbstractConditionalOffer name is max_length 128 offer_name = (offer_name[:125] + '...') if len(offer_name) > 128 else offer_name # pylint: disable=unsubscriptable-object self.instance.name = offer_name self.instance.status = ConditionalOffer.OPEN self.instance.offer_type = ConditionalOffer.SITE self.instance.max_basket_applications = 1 self.instance.site = site if commit: benefit = getattr(self.instance, 'benefit', Benefit()) benefit.proxy_class = class_path(BENEFIT_MAP[self.cleaned_data['benefit_type']]) benefit.value = self.cleaned_data['benefit_value'] benefit.save() self.instance.benefit = benefit if hasattr(self.instance, 'condition'): self.instance.condition.journal_bundle_uuid = journal_bundle_uuid self.instance.condition.save() else: self.instance.condition = create_condition( JournalBundleCondition, journal_bundle_uuid=journal_bundle_uuid ) return super(JournalBundleOfferForm, self).save(commit)