Beispiel #1
0
    def __init__(self, *args, **kw):
        self.request = kw.pop('request')
        self.addon = kw.pop('addon')
        self.user = kw.pop('user')

        is_packaged = self.addon.is_packaged

        kw['initial'] = {
            'allow_inapp': self.addon.premium_type in amo.ADDON_INAPPS
        }

        if self.addon.premium_type == amo.ADDON_FREE_INAPP:
            kw['initial']['price'] = 'free'
        elif self.addon.premium and self.addon.premium.price:
            # If the app has a premium object, set the initial price.
            kw['initial']['price'] = self.addon.premium.price.pk

        super(PremiumForm, self).__init__(*args, **kw)

        self.fields['paid_platforms'].choices = PAID_PLATFORMS(
            self.request, is_packaged)
        self.fields['free_platforms'].choices = FREE_PLATFORMS(
            self.request, is_packaged)

        if (self.is_paid() and not self.is_toggling()):
            # Require the price field if the app is premium and
            # we're not toggling from free <-> paid.
            self.fields['price'].required = True

        # Get the list of supported devices and put them in the data.
        self.device_data = {}
        supported_devices = [
            amo.REVERSE_DEVICE_LOOKUP[dev.id]
            for dev in self.addon.device_types
        ]
        self.initial.setdefault('free_platforms', [])
        self.initial.setdefault('paid_platforms', [])

        for platform in set(
                x[0].split('-', 1)[1]
                for x in (FREE_PLATFORMS(self.request, is_packaged) +
                          PAID_PLATFORMS(self.request, is_packaged))):
            supported = platform in supported_devices
            self.device_data['free-%s' % platform] = supported
            self.device_data['paid-%s' % platform] = supported

            if supported:
                self.initial['free_platforms'].append('free-%s' % platform)
                self.initial['paid_platforms'].append('paid-%s' % platform)

        if not self.initial.get('price'):
            self.initial['price'] = self._initial_price_id()

        self.fields['price'].choices = self.group_tier_choices()
Beispiel #2
0
def payments(request, addon_id, addon, webapp=False):
    premium_form = forms_payments.PremiumForm(
        request.POST or None, request=request, addon=addon,
        user=request.amo_user)

    region_form = forms.RegionForm(
        request.POST or None, product=addon, request=request)

    upsell_form = forms_payments.UpsellForm(
        request.POST or None, addon=addon, user=request.amo_user)

    account_list_form = forms_payments.AccountListForm(
        request.POST or None, addon=addon, user=request.amo_user)

    if request.method == 'POST':

        success = all(form.is_valid() for form in
                      [premium_form, region_form, upsell_form,
                       account_list_form])

        if success:
            region_form.save()

            try:
                premium_form.save()
            except client.Error as err:
                success = False
                log.error('Error setting payment information (%s)' % err)
                messages.error(
                    request, _(u'We encountered a problem connecting to the '
                               u'payment server.'))
                raise  # We want to see these exceptions!

            is_free_inapp = addon.premium_type == amo.ADDON_FREE_INAPP
            is_now_paid = (addon.premium_type in amo.ADDON_PREMIUMS
                           or is_free_inapp)

            # If we haven't changed to a free app, check the upsell.
            if is_now_paid and success:
                try:
                    if not is_free_inapp:
                        upsell_form.save()
                    account_list_form.save()
                except client.Error as err:
                    log.error('Error saving payment information (%s)' % err)
                    messages.error(
                        request, _(u'We encountered a problem connecting to '
                                   u'the payment server.'))
                    success = False
                    raise  # We want to see all the solitude errors now.

        # If everything happened successfully, give the user a pat on the back.
        if success:
            messages.success(request, _('Changes successfully saved.'))
            return redirect(addon.get_dev_url('payments'))

    # TODO: refactor this (bug 945267)
    is_packaged = addon.is_packaged
    android_payments_enabled = waffle.flag_is_active(request,
                                                     'android-payments')
    android_packaged_enabled = waffle.flag_is_active(request,
                                                     'android-packaged')
    desktop_packaged_enabled = waffle.flag_is_active(request,
                                                     'desktop-packaged')

    # If android payments is not allowed then firefox os must
    # be 'checked' and android-mobile and android-tablet should not be.
    invalid_paid_platform_state = []

    # If isn't packaged or it is packaged and the android-packaged flag is on
    # then we should check that desktop isn't set to True.
    if not is_packaged or (is_packaged and desktop_packaged_enabled):
        invalid_paid_platform_state.append(('desktop', True))

    if not android_payments_enabled:
        # When android-payments is off...
        # If isn't packaged or it is packaged and the android-packaged flag is on
        # then we should check for the state of android-mobile and android-tablet.
        if not is_packaged or (is_packaged and android_packaged_enabled):
            invalid_paid_platform_state += [('android-mobile', True),
                                            ('android-tablet', True)]
        invalid_paid_platform_state.append(('firefoxos', False))

    cannot_be_paid = (
        addon.premium_type == amo.ADDON_FREE and
        any(premium_form.device_data['free-%s' % x] == y
            for x, y in invalid_paid_platform_state))

    try:
        tier_zero = Price.objects.get(price='0.00', active=True)
        tier_zero_id = tier_zero.pk
    except Price.DoesNotExist:
        tier_zero = None
        tier_zero_id = ''

    # Get the regions based on tier zero. This should be all the
    # regions with payments enabled.
    paid_region_ids_by_slug = []
    if tier_zero:
        paid_region_ids_by_slug = tier_zero.region_ids_by_slug()

    provider = get_provider()
    paid_platform_names = [unicode(platform[1])
                           for platform in PAID_PLATFORMS(request, is_packaged)]

    return render(request, 'developers/payments/premium.html',
                  {'addon': addon, 'webapp': webapp, 'premium': addon.premium,
                   'form': premium_form, 'upsell_form': upsell_form,
                   'tier_zero_id': tier_zero_id, 'region_form': region_form,
                   'DEVICE_LOOKUP': DEVICE_LOOKUP,
                   'is_paid': (addon.premium_type in amo.ADDON_PREMIUMS
                               or addon.premium_type == amo.ADDON_FREE_INAPP),
                   'cannot_be_paid': cannot_be_paid,
                   'paid_platform_names': paid_platform_names,
                   'has_incomplete_status': addon.status == amo.STATUS_NULL,
                   'is_packaged': addon.is_packaged,
                   # Bango values
                   'account_form': provider.forms['account'](),
                   'account_list_form': account_list_form,
                   # Waffles
                   'api_pricelist_url': reverse('price-list'),
                   'payment_methods': {
                       PAYMENT_METHOD_ALL: _('All'),
                       PAYMENT_METHOD_CARD: _('Credit card'),
                       PAYMENT_METHOD_OPERATOR: _('Carrier'),
                   },
                   'all_paid_region_ids_by_slug': paid_region_ids_by_slug,
                   'provider': provider})
def payments(request, addon_id, addon, webapp=False):
    premium_form = forms_payments.PremiumForm(request.POST or None,
                                              request=request,
                                              addon=addon,
                                              user=request.user)

    region_form = forms.RegionForm(request.POST or None,
                                   product=addon,
                                   request=request)

    upsell_form = forms_payments.UpsellForm(request.POST or None,
                                            addon=addon,
                                            user=request.user)

    providers = get_providers()

    if 'form-TOTAL_FORMS' in request.POST:
        formset_data = request.POST
    else:
        formset_data = None
    account_list_formset = forms_payments.AccountListFormSet(
        data=formset_data,
        provider_data=[{
            'addon': addon,
            'user': request.user,
            'provider': provider
        } for provider in providers])

    if request.method == 'POST':

        active_forms = [premium_form, region_form, upsell_form]
        if formset_data is not None:
            active_forms.append(account_list_formset)

        success = all(form.is_valid() for form in active_forms)

        if success:
            region_form.save()

            try:
                premium_form.save()
            except client.Error as err:
                success = False
                log.error('Error setting payment information (%s)' % err)
                messages.error(
                    request,
                    _(u'We encountered a problem connecting to the '
                      u'payment server.'))
                raise  # We want to see these exceptions!

            is_free_inapp = addon.premium_type == mkt.ADDON_FREE_INAPP
            is_now_paid = (addon.premium_type in mkt.ADDON_PREMIUMS
                           or is_free_inapp)

            # If we haven't changed to a free app, check the upsell.
            if is_now_paid and success:
                try:
                    if not is_free_inapp:
                        upsell_form.save()
                    if formset_data is not None:
                        account_list_formset.save()
                except client.Error as err:
                    log.error('Error saving payment information (%s)' % err)
                    messages.error(
                        request,
                        _(u'We encountered a problem connecting to '
                          u'the payment server.'))
                    success = False
                    raise  # We want to see all the solitude errors now.

        # If everything happened successfully, give the user a pat on the back.
        if success:
            messages.success(request, _('Changes successfully saved.'))
            return redirect(addon.get_dev_url('payments'))

    # TODO: refactor this (bug 945267)
    android_pay = waffle.flag_is_active(request, 'android-payments')
    desktop_pay = waffle.flag_is_active(request, 'desktop-payments')

    # If android payments is not allowed then firefox os must
    # be 'checked' and android-mobile and android-tablet should not be.
    invalid_paid_platform_state = []

    if not android_pay:
        # When android-payments is off...
        invalid_paid_platform_state += [('android-mobile', True),
                                        ('android-tablet', True),
                                        ('firefoxos', False)]

    if not desktop_pay:
        # When desktop-payments is off...
        invalid_paid_platform_state += [('desktop', True)]

    cannot_be_paid = (addon.premium_type == mkt.ADDON_FREE
                      and any(premium_form.device_data['free-%s' % x] == y
                              for x, y in invalid_paid_platform_state))

    try:
        tier_zero = Price.objects.get(price='0.00', active=True)
        tier_zero_id = tier_zero.pk
    except Price.DoesNotExist:
        tier_zero = None
        tier_zero_id = ''

    # Get the regions based on tier zero. This should be all the
    # regions with payments enabled.
    paid_region_ids_by_name = []
    if tier_zero:
        paid_region_ids_by_name = tier_zero.region_ids_by_name()

    platforms = PAID_PLATFORMS(request)
    paid_platform_names = [unicode(platform[1]) for platform in platforms]

    provider_regions = {}
    if tier_zero:
        provider_regions = tier_zero.provider_regions()

    return render(
        request,
        'developers/payments/premium.html',
        {
            'addon':
            addon,
            'webapp':
            webapp,
            'premium':
            addon.premium,
            'form':
            premium_form,
            'upsell_form':
            upsell_form,
            'tier_zero_id':
            tier_zero_id,
            'region_form':
            region_form,
            'PLATFORMS_NAMES':
            PLATFORMS_NAMES,
            'is_paid': (addon.premium_type in mkt.ADDON_PREMIUMS
                        or addon.premium_type == mkt.ADDON_FREE_INAPP),
            'cannot_be_paid':
            cannot_be_paid,
            'paid_platform_names':
            paid_platform_names,
            'is_packaged':
            addon.is_packaged,
            # Bango values
            'account_list_forms':
            account_list_formset.forms,
            'account_list_formset':
            account_list_formset,
            # Waffles
            'api_pricelist_url':
            reverse('price-list'),
            'payment_methods': {
                PAYMENT_METHOD_ALL: _('All'),
                PAYMENT_METHOD_CARD: _('Credit card'),
                PAYMENT_METHOD_OPERATOR: _('Carrier'),
            },
            'provider_lookup':
            dict(PROVIDER_CHOICES),
            'all_paid_region_ids_by_name':
            paid_region_ids_by_name,
            'providers':
            providers,
            'provider_regions':
            provider_regions,
            'enabled_provider_ids': [
                acct.payment_account.provider
                for acct in addon.all_payment_accounts()
            ]
        })
Beispiel #4
0
class DeviceTypeForm(happyforms.Form):
    ERRORS = {
        'both': _lazy(u'Cannot be free and paid.'),
        'none': _lazy(u'Please select a device.'),
    }

    free_platforms = forms.MultipleChoiceField(choices=FREE_PLATFORMS(),
                                               required=False)
    paid_platforms = forms.MultipleChoiceField(choices=PAID_PLATFORMS(),
                                               required=False)

    def save(self, addon, is_paid):
        data = self.cleaned_data[
            'paid_platforms' if is_paid else 'free_platforms']
        submitted_data = self.get_devices(t.split('-', 1)[1] for t in data)

        new_types = set(dev.id for dev in submitted_data)
        old_types = set(amo.DEVICE_TYPES[x.id].id for x in addon.device_types)

        added_devices = new_types - old_types
        removed_devices = old_types - new_types

        for d in added_devices:
            addon.addondevicetype_set.create(device_type=d)
        for d in removed_devices:
            addon.addondevicetype_set.filter(device_type=d).delete()

        # Send app to re-review queue if public and new devices are added.
        if added_devices and addon.status in amo.WEBAPPS_APPROVED_STATUSES:
            mark_for_rereview(addon, added_devices, removed_devices)

    def _add_error(self, msg):
        self._errors['free_platforms'] = self._errors['paid_platforms'] = (
            self.ERRORS[msg])

    def _get_combined(self):
        devices = (self.cleaned_data.get('free_platforms', []) +
                   self.cleaned_data.get('paid_platforms', []))
        return set(d.split('-', 1)[1] for d in devices)

    def clean(self):
        data = self.cleaned_data
        paid = data.get('paid_platforms', [])
        free = data.get('free_platforms', [])

        # Check that they didn't select both.
        if free and paid:
            self._add_error('both')
            return data

        # Check that they selected one.
        if not free and not paid:
            self._add_error('none')
            return data

        return super(DeviceTypeForm, self).clean()

    def get_devices(self, source=None):
        """Returns a device based on the requested free or paid."""
        if source is None:
            source = self._get_combined()

        platforms = {
            'firefoxos': amo.DEVICE_GAIA,
            'desktop': amo.DEVICE_DESKTOP,
            'android-mobile': amo.DEVICE_MOBILE,
            'android-tablet': amo.DEVICE_TABLET
        }
        return map(platforms.get, source)

    def is_paid(self):
        return bool(self.cleaned_data.get('paid_platforms', False))

    def get_paid(self):
        """Returns the premium type. Should not be used if the form is used to
        modify an existing app.

        """

        return amo.ADDON_PREMIUM if self.is_paid() else amo.ADDON_FREE
Beispiel #5
0
 def __init__(self, *args, **kwargs):
     self.request = kwargs.pop('request', None)
     super(NewWebappForm, self).__init__(*args, **kwargs)
     if 'paid_platforms' in self.fields:
         self.fields['paid_platforms'].choices = PAID_PLATFORMS(
             self.request)