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 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 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 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 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)
def _get_or_create_offer(product_range, benefit_type, benefit_value, offer_name, max_uses, site, email_domains=None, program_uuid=None): """ Return an offer for a catalog with condition and benefit. If offer doesn't exist, new offer will be created and associated with provided Offer condition and benefit. Args: product_range (Range): Range of products associated with condition benefit_type (str): Type of benefit associated with the offer benefit_value (Decimal): Value of benefit associated with the offer Kwargs: coupon_id (int): ID of the coupon max_uses (int): number of maximum global application number an offer can have offer_number (int): number of the consecutive offer - used in case of a multiple multi-use coupon email_domains (str): a comma-separated string of email domains allowed to apply this offer program_uuid (str): the Program UUID site (site): Site for which the Coupon is created. Defaults to None. Returns: Offer """ if program_uuid: try: offer_condition = ProgramCourseRunSeatsCondition.objects.get( program_uuid=program_uuid) except ProgramCourseRunSeatsCondition.DoesNotExist: offer_condition = create_condition(ProgramCourseRunSeatsCondition, program_uuid=program_uuid) else: offer_condition, __ = Condition.objects.get_or_create( proxy_class=None, range=product_range, type=Condition.COUNT, value=1, ) try: if program_uuid: proxy_class = class_path(BENEFIT_MAP[benefit_type]) offer_benefit = Benefit.objects.filter( proxy_class=proxy_class, value=benefit_value).first() if not offer_benefit: offer_benefit = Benefit() offer_benefit.proxy_class = proxy_class offer_benefit.value = benefit_value offer_benefit.save() offer_name = "{}-{}".format(offer_name, offer_benefit.name) else: offer_benefit, __ = Benefit.objects.get_or_create( range=product_range, type=benefit_type, value=Decimal(benefit_value), max_affected_items=1, ) except ( TypeError, DecimalException ): # If the benefit_value parameter is not sent TypeError will be raised log_message_and_raise_validation_error( 'Failed to create Benefit. Benefit value must be a positive number or 0.' ) offer_kwargs = { 'offer_type': ConditionalOffer.VOUCHER, 'condition': offer_condition, 'benefit': offer_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, 'priority': OFFER_PRIORITY_VOUCHER, } offer, __ = ConditionalOffer.objects.update_or_create( name=offer_name, defaults=offer_kwargs) return offer
def _get_or_create_offer(product_range, benefit_type, benefit_value, coupon_id=None, max_uses=None, offer_number=None, email_domains=None, program_uuid=None): """ Return an offer for a catalog with condition and benefit. If offer doesn't exist, new offer will be created and associated with provided Offer condition and benefit. Args: product_range (Range): Range of products associated with condition benefit_type (str): Type of benefit associated with the offer benefit_value (Decimal): Value of benefit associated with the offer Kwargs: coupon_id (int): ID of the coupon max_uses (int): number of maximum global application number an offer can have offer_number (int): number of the consecutive offer - used in case of a multiple multi-use coupon email_domains (str): a comma-separated string of email domains allowed to apply this offer program_uuid (str): the Program UUID Returns: Offer """ if program_uuid: try: offer_condition = ProgramCourseRunSeatsCondition.objects.get( program_uuid=program_uuid) except ProgramCourseRunSeatsCondition.DoesNotExist: offer_condition = create_condition(ProgramCourseRunSeatsCondition, program_uuid=program_uuid) else: offer_condition, __ = Condition.objects.get_or_create( range=product_range, type=Condition.COUNT, value=1, ) try: if program_uuid: proxy_class = class_path(BENEFIT_MAP[benefit_type]) offer_benefit = Benefit.objects.filter( proxy_class=proxy_class, value=benefit_value).first() if not offer_benefit: offer_benefit = Benefit() offer_benefit.proxy_class = proxy_class offer_benefit.value = benefit_value offer_benefit.save() offer_name = "Coupon [{}]-{}".format(coupon_id, offer_benefit.name) else: offer_benefit, __ = Benefit.objects.get_or_create( range=product_range, type=benefit_type, value=Decimal(benefit_value), max_affected_items=1, ) offer_name = "Coupon [{}]-{}-{}".format(coupon_id, offer_benefit.type, offer_benefit.value) except ( TypeError, DecimalException ): # If the benefit_value parameter is not sent TypeError will be raised log_message_and_raise_validation_error( 'Failed to create Benefit. Benefit value must be a positive number or 0.' ) if offer_number: offer_name = "{} [{}]".format(offer_name, offer_number) offer, __ = ConditionalOffer.objects.get_or_create( name=offer_name, offer_type=ConditionalOffer.VOUCHER, condition=offer_condition, benefit=offer_benefit, max_global_applications=max_uses, email_domains=email_domains) return offer