Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
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
Esempio n. 8
0
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