def _link_domains(domain, other_domain):
     plan_version = Subscription.get_active_subscription_by_domain(
         domain).plan_version
     plan = plan_version.plan
     plan.is_customer_software_plan = True
     plan.save()
     other_subscription = Subscription.get_active_subscription_by_domain(
         other_domain)
     other_subscription.plan_version = plan_version
     other_subscription.save()
Ejemplo n.º 2
0
 def _change_to_probono(self, domain_name, pro_bono_status):
     subscription = Subscription.get_active_subscription_by_domain(
         domain_name)
     subscription.update_subscription(
         pro_bono_status=pro_bono_status,
         date_start=datetime.date.today() - datetime.timedelta(days=1),
         date_end=datetime.date.today() + datetime.timedelta(days=5))
Ejemplo n.º 3
0
def _get_users_included_in_subscription(domain):
    from corehq.apps.accounting.models import Subscription
    subscription = Subscription.get_active_subscription_by_domain(domain)
    if subscription:
        plan_version = subscription.plan_version

        n_included_users = (plan_version.feature_rates.get(
            feature__feature_type='User').monthly_limit)

        if plan_version.plan.is_customer_software_plan:
            # For now just give each domain that's part of an enterprise account
            # access to nearly all of the throughput allocation.
            # Really what we want is to limit enterprise accounts' submissions accross all
            # their domains together, but right now what we care about
            # is not unfairly limiting high-paying enterprise accounts.
            n_domains = len(
                plan_version.subscription_set.filter(is_active=True))
            # Heavily bias towards allowing high throughput
            # 80% minimum, plus a fraction of 20% inversely proportional
            # to the number of domains that share the throughput allocation.
            return n_included_users * (.8 + .2 / n_domains)
        else:
            return n_included_users
    else:
        return 0
    def log_module_info(self, module, path, domains, in_module_map):
        domains_exist = []
        plans = []
        last_form_submissions = []
        all_community = True
        for domain in domains:
            domain_obj = Domain.get_by_name(domain)
            plan = "Not Found"
            domains_exist.append(domain_obj is not None)
            if domain_obj:
                subscription = Subscription.get_active_subscription_by_domain(domain)
                if subscription:
                    plan = subscription.plan_version.plan.name
                    if subscription.plan_version.plan.edition != SoftwarePlanEdition.COMMUNITY:
                        all_community = False
                last_form_submissions.append("{}".format(get_last_form_submission_received(domain)))
            else:
                last_form_submissions.append("None")
            plans.append(plan)

        return [
            module,
            path[len(settings.FILEPATH) + 1:],
            " | ".join(domains),
            " | ".join(map(str, domains_exist)),
            " | ".join(plans),
            " | ".join(last_form_submissions),
            in_module_map,
            all(domains_exist) and all_community,
        ]
Ejemplo n.º 5
0
def _terminate_subscriptions(domain_name):
    today = date.today()

    with transaction.atomic():
        current_subscription = Subscription.get_active_subscription_by_domain(domain_name)

        if current_subscription:
            current_subscription.date_end = today
            current_subscription.is_active = False
            current_subscription.save()

            current_subscription.transfer_credits()

            _, downgraded_privs, upgraded_privs = get_change_status(current_subscription.plan_version, None)
            current_subscription.subscriber.deactivate_subscription(
                downgraded_privileges=downgraded_privs,
                upgraded_privileges=upgraded_privs,
                old_subscription=current_subscription,
                new_subscription=None,
            )

        Subscription.visible_objects.filter(
            Q(date_start__gt=today) | Q(date_start=today, is_active=False),
            subscriber__domain=domain_name,
        ).update(is_hidden_to_ops=True)
Ejemplo n.º 6
0
def _update_subscriptions_to_new_plans(domains_by_plan_version,
                                       privilege_slug,
                                       dry_run=False):
    """
    :param domains_by_plan_version: {'<plan_version_id>': [domains_for_version]}
    :param privilege_slug: slug for Role obj representing privilege to add
    """
    dry_run_tag = '[DRY_RUN]' if dry_run else ''
    for version_id, domains in domains_by_plan_version.items():
        current_version = SoftwarePlanVersion.objects.get(id=version_id)
        current_plan = current_version.plan

        new_role = _get_or_create_role_with_privilege(
            current_version.role.slug, privilege_slug, dry_run=dry_run)
        new_plan = _get_or_create_new_software_plan(current_plan,
                                                    dry_run=dry_run)
        new_version = _get_or_create_new_software_plan_version(new_plan,
                                                               current_version,
                                                               new_role,
                                                               dry_run=dry_run)

        if new_role and new_plan and new_version:
            for domain in domains:
                subscription = Subscription.get_active_subscription_by_domain(
                    domain)
                subscription.plan_version = new_plan.get_version()
                if not dry_run:
                    subscription.save()
                logger.info(
                    f'{dry_run_tag}Updated subscription\'s software plan to {new_plan.name} for {domain}.'
                )
 def _change_to_extended_trial(self, domain_name):
     subscription = Subscription.get_active_subscription_by_domain(domain_name)
     subscription.update_subscription(
         service_type=SubscriptionType.EXTENDED_TRIAL,
         date_start=datetime.date.today() - datetime.timedelta(days=1),
         date_end=datetime.date.today() + datetime.timedelta(days=5)
     )
Ejemplo n.º 8
0
def run_downgrade_process(today=None):
    today = today or datetime.date.today()

    for domain, oldest_unpaid_invoice, total in _get_domains_with_invoices_over_threshold(today):
        current_subscription = Subscription.get_active_subscription_by_domain(domain)
        if _is_subscription_eligible_for_downgrade_process(current_subscription):
            _apply_downgrade_process(current_subscription, oldest_unpaid_invoice, total, today)
 def _change_to_probono(self, domain_name, pro_bono_status):
     subscription = Subscription.get_active_subscription_by_domain(domain_name)
     subscription.update_subscription(
         pro_bono_status=pro_bono_status,
         date_start=datetime.date.today() - datetime.timedelta(days=1),
         date_end=datetime.date.today() + datetime.timedelta(days=5)
     )
Ejemplo n.º 10
0
def run_downgrade_process(today=None):
    today = today or datetime.date.today()

    for domain, oldest_unpaid_invoice, total in _get_domains_with_invoices_over_threshold(today):
        current_subscription = Subscription.get_active_subscription_by_domain(domain)
        if _is_subscription_eligible_for_downgrade_process(current_subscription):
            _apply_downgrade_process(current_subscription, oldest_unpaid_invoice, total, today)
Ejemplo n.º 11
0
def downgrade_eligible_domains(only_downgrade_domain=None):
    today = datetime.date.today()

    for domain, oldest_unpaid_invoice, total in get_domains_with_subscription_invoices_over_threshold(today):
        try:
            if only_downgrade_domain and domain != only_downgrade_domain:
                continue
            current_subscription = Subscription.get_active_subscription_by_domain(domain)
            if current_subscription and is_subscription_eligible_for_downgrade_process(current_subscription):
                _apply_downgrade_process(
                    oldest_unpaid_invoice, total, today, current_subscription
                )
        except Exception:
            log_accounting_error(
                f"There was an issue applying the downgrade process "
                f"to {domain}.",
                show_stack_trace=True
            )

    for oldest_unpaid_invoice, total in get_accounts_with_customer_invoices_over_threshold(today):
        try:
            subscription_on_invoice = oldest_unpaid_invoice.subscriptions.first()
            if only_downgrade_domain and subscription_on_invoice.subscriber.domain != only_downgrade_domain:
                continue
            if is_subscription_eligible_for_downgrade_process(subscription_on_invoice):
                _apply_downgrade_process(oldest_unpaid_invoice, total, today, subscription_on_invoice)
        except Exception:
            log_accounting_error(
                f"There was an issue applying the downgrade process "
                f"to customer invoice {oldest_unpaid_invoice.id}.",
                show_stack_trace=True
            )
Ejemplo n.º 12
0
def _terminate_subscriptions(domain_name):
    today = date.today()

    with transaction.atomic():
        current_subscription = Subscription.get_active_subscription_by_domain(domain_name)

        if current_subscription:
            current_subscription.date_end = today
            current_subscription.is_active = False
            current_subscription.save()

            current_subscription.transfer_credits()

            _, downgraded_privs, upgraded_privs = get_change_status(current_subscription.plan_version, None)
            current_subscription.subscriber.deactivate_subscription(
                downgraded_privileges=downgraded_privs,
                upgraded_privileges=upgraded_privs,
                old_subscription=current_subscription,
                new_subscription=None,
            )

        Subscription.visible_objects.filter(
            Q(date_start__gt=today) | Q(date_start=today, is_active=False),
            subscriber__domain=domain_name,
        ).update(is_hidden_to_ops=True)
Ejemplo n.º 13
0
 def _low_credits_context(self):
     context = {}
     current_subscription = Subscription.get_active_subscription_by_domain(
         self.domain)
     if current_subscription:
         monthly_fee = current_subscription.plan_version.product_rate.monthly_fee
         if monthly_fee:
             prepaid_credits = get_total_credits_available_for_product(
                 current_subscription)
             num_months_remaining = prepaid_credits / monthly_fee
             prepaid_remaining_date = months_from_date(
                 date.today(), num_months_remaining)
             partial_month_remaining = num_months_remaining % 1
             num_days_in_month = 30  # Approximate
             prepaid_remaining_date += timedelta(
                 days=int(partial_month_remaining * num_days_in_month))
             prepaid_days_remaining = (prepaid_remaining_date -
                                       date.today()).days
             if 0 < prepaid_days_remaining < 63:
                 context['show_prepaid_modal'] = True
                 context['prepaid_days_remaining'] = prepaid_days_remaining
                 context['prepaid_weeks_remaining'] = max(
                     prepaid_days_remaining // 7, 1)
                 context['monthly_fee'] = monthly_fee
                 context[
                     'edition'] = current_subscription.plan_version.plan.edition
                 context['prepaid_remaining_date'] = prepaid_remaining_date
     return context
Ejemplo n.º 14
0
 def _change_to_extended_trial(self, domain_name):
     subscription = Subscription.get_active_subscription_by_domain(
         domain_name)
     subscription.update_subscription(
         service_type=SubscriptionType.EXTENDED_TRIAL,
         date_start=datetime.date.today() - datetime.timedelta(days=1),
         date_end=datetime.date.today() + datetime.timedelta(days=5))
Ejemplo n.º 15
0
def get_overdue_invoice(domain_name):
    current_subscription = Subscription.get_active_subscription_by_domain(
        domain_name)
    if current_subscription and is_subscription_eligible_for_downgrade_process(
            current_subscription):
        overdue_invoice, _ = get_unpaid_invoices_over_threshold_by_domain(
            date.today(), domain_name)
        return overdue_invoice
Ejemplo n.º 16
0
def get_n_users_in_subscription(domain):
    from corehq.apps.accounting.models import Subscription
    subscription = Subscription.get_active_subscription_by_domain(domain)
    if subscription:
        plan_version = subscription.plan_version
        return plan_version.feature_rates.get(
            feature__feature_type='User').monthly_limit
    else:
        return 0
Ejemplo n.º 17
0
 def should_hide_feature_notifs(domain, plan):
     groups = Group.get_case_sharing_groups(domain, wrap=False)
     subscription_type = Subscription.get_active_subscription_by_domain(
         domain).service_type
     if plan == 'pro' and groups != []:
         return True
     if subscription_type == 'IMPLEMENTATION' or subscription_type == 'SANDBOX':
         return True
     return False
Ejemplo n.º 18
0
def _get_service_type(toggle):
    """Returns subscription service type for each toggle
    """
    service_type = {}
    for enabled in toggle.enabled_users:
        name = _enabled_item_name(enabled)
        if _namespace_domain(enabled):
            subscription = Subscription.get_active_subscription_by_domain(name)
            if subscription:
                service_type[name] = subscription.service_type
    return service_type
Ejemplo n.º 19
0
 def dehydrate_billing_properties(self, bundle):
     domain = _get_domain(bundle)
     subscription = Subscription.get_active_subscription_by_domain(domain.name)
     return {
         "date_start": (subscription.date_start
                        if subscription is not None else None),
         "date_end": (subscription.date_end
                      if subscription is not None else None),
         "plan_version": (subscription.plan_version
                          if subscription is not None else None),
     }
Ejemplo n.º 20
0
def _get_service_type(toggle):
    """Returns subscription service type for each toggle
    """
    service_type = {}
    for enabled in toggle.enabled_users:
        name = _enabled_item_name(enabled)
        if _namespace_domain(enabled):
            subscription = Subscription.get_active_subscription_by_domain(name)
            if subscription:
                service_type[name] = subscription.service_type
    return service_type
Ejemplo n.º 21
0
 def dehydrate_billing_properties(self, bundle):
     domain_obj = _get_domain(bundle)
     subscription = Subscription.get_active_subscription_by_domain(domain_obj.name)
     return {
         "date_start": (subscription.date_start
                        if subscription is not None else None),
         "date_end": (subscription.date_end
                      if subscription is not None else None),
         "plan_version": (subscription.plan_version
                          if subscription is not None else None),
     }
Ejemplo n.º 22
0
def send_overdue_reminders(today=None):
    from corehq.apps.domain.views import DomainSubscriptionView
    from corehq.apps.domain.views import DomainBillingStatementsView

    today = today or datetime.date.today()
    invoices = Invoice.objects.filter(is_hidden=False,
                                      subscription__service_type=SubscriptionType.PRODUCT,
                                      date_paid__isnull=True,
                                      date_due__lt=today)\
        .exclude(subscription__plan_version__plan__edition=SoftwarePlanEdition.ENTERPRISE)\
        .order_by('date_due')\
        .select_related('subscription__subscriber')

    domains = set()
    for invoice in invoices:
        if invoice.get_domain() not in domains:
            domains.add(invoice.get_domain())
            total = Invoice.objects.filter(is_hidden=False,
                                           subscription__subscriber__domain=invoice.get_domain())\
                .aggregate(Sum('balance'))['balance__sum']
            if total >= 100:
                domain = Domain.get_by_name(invoice.get_domain())
                current_subscription = Subscription.get_active_subscription_by_domain(
                    domain.name)
                if (current_subscription.plan_version.plan.edition !=
                        SoftwarePlanEdition.COMMUNITY
                        and not current_subscription.skip_auto_downgrade):
                    days_ago = (today - invoice.date_due).days
                    context = {
                        'domain':
                        invoice.get_domain(),
                        'total':
                        total,
                        'subscription_url':
                        absolute_reverse(DomainSubscriptionView.urlname,
                                         args=[invoice.get_domain()]),
                        'statements_url':
                        absolute_reverse(DomainBillingStatementsView.urlname,
                                         args=[invoice.get_domain()]),
                        'date_60':
                        invoice.date_due + datetime.timedelta(days=60),
                        'contact_email':
                        settings.INVOICING_CONTACT_EMAIL
                    }
                    if days_ago == 61:
                        _downgrade_domain(current_subscription)
                        _send_downgrade_notice(invoice, context)
                    elif days_ago == 58:
                        _send_downgrade_warning(invoice, context)
                    elif days_ago == 30:
                        _send_overdue_notice(invoice, context)
                    elif days_ago == 1:
                        _create_overdue_notification(invoice, context)
Ejemplo n.º 23
0
def run_downgrade_process():
    today = datetime.date.today()

    for domain, oldest_unpaid_invoice, total in _get_domains_with_subscription_invoices_over_threshold(today):
        current_subscription = Subscription.get_active_subscription_by_domain(domain)
        if is_subscription_eligible_for_downgrade_process(current_subscription):
            _apply_downgrade_process(oldest_unpaid_invoice, total, today, current_subscription)

    for oldest_unpaid_invoice, total in get_accounts_with_customer_invoices_over_threshold(today):
        subscription_on_invoice = oldest_unpaid_invoice.subscriptions.first()
        if is_subscription_eligible_for_downgrade_process(subscription_on_invoice):
            _apply_downgrade_process(oldest_unpaid_invoice, total, today)
Ejemplo n.º 24
0
 def apply_prbac(cls, request):
     subscription = (Subscription.get_active_subscription_by_domain(
         request.domain) if hasattr(request, 'domain') else None)
     if subscription:
         plan_version = subscription.plan_version
         request.role = plan_version.role
         request.plan = plan_version
         request.subscription = subscription
     else:
         plan_version = DefaultProductPlan.get_default_plan_version()
         request.role = plan_version.role
         request.plan = plan_version
Ejemplo n.º 25
0
 def rows_for_domain(self, domain):
     subscription = Subscription.get_active_subscription_by_domain(
         domain.name)
     plan_version = subscription.plan_version if subscription else DefaultProductPlan.get_default_plan_version(
     )
     return [[
         plan_version.plan.name,
         self.format_date(domain.date_created),
         get_mobile_user_count(domain.name, include_inactive=False),
         get_web_user_count(domain.name, include_inactive=False),
         self.format_date(get_last_form_submission_received(domain.name)),
     ] + self.domain_properties(domain)]
Ejemplo n.º 26
0
def can_add_extra_mobile_workers(request):
    from corehq.apps.users.models import CommCareUser
    from corehq.apps.accounting.models import Subscription
    num_web_users = CommCareUser.total_by_domain(request.domain)
    user_limit = request.plan.user_limit
    if user_limit == -1 or num_web_users < user_limit:
        return True
    if not has_privilege(request, privileges.ALLOW_EXCESS_USERS):
        current_subscription = Subscription.get_active_subscription_by_domain(request.domain)
        if current_subscription is None or current_subscription.account.date_confirmed_extra_charges is None:
            return False
    return True
Ejemplo n.º 27
0
def run_downgrade_process():
    today = datetime.date.today()

    for domain, oldest_unpaid_invoice, total in _get_domains_with_subscription_invoices_over_threshold(today):
        current_subscription = Subscription.get_active_subscription_by_domain(domain)
        if is_subscription_eligible_for_downgrade_process(current_subscription):
            _apply_downgrade_process(oldest_unpaid_invoice, total, today, current_subscription)

    for oldest_unpaid_invoice, total in get_accounts_with_customer_invoices_over_threshold(today):
        subscription_on_invoice = oldest_unpaid_invoice.subscriptions.first()
        if is_subscription_eligible_for_downgrade_process(subscription_on_invoice):
            _apply_downgrade_process(oldest_unpaid_invoice, total, today)
    def _subscribe_to_pro_with_rb(self):
        subscription = Subscription.get_active_subscription_by_domain(self.project.name)

        new_subscription = subscription.change_plan(
            self.pro_rb_version,
            date_end=None,
            web_user=self.admin_username,
            service_type=SubscriptionType.IMPLEMENTATION,
            pro_bono_status=ProBonoStatus.NO,
            internal_change=True,
        )
        return new_subscription
    def _subscribe_to_pro_with_rb(self):
        subscription = Subscription.get_active_subscription_by_domain(
            self.project.name)

        new_subscription = subscription.change_plan(
            self.pro_rb_version,
            date_end=None,
            web_user=self.admin_username,
            service_type=SubscriptionType.IMPLEMENTATION,
            pro_bono_status=ProBonoStatus.NO,
            internal_change=True,
        )
        return new_subscription
 def _domain_rows(self, domain):
     subscription = Subscription.get_active_subscription_by_domain(
         domain.name)
     plan_version = subscription.plan_version if subscription else DefaultProductPlan.get_default_plan_version(
     )
     return [
         self._domain_properties(domain) + [
             plan_version.plan.name,
             str(get_mobile_user_count(domain.name,
                                       include_inactive=False)),
             str(get_web_user_count(domain.name, include_inactive=False)),
         ]
     ]
Ejemplo n.º 31
0
    def test_downgrade(self):
        domain, latest_invoice = self._simulate_downgrade(
            DAYS_PAST_DUE_TO_TRIGGER_DOWNGRADE
        )

        # confirm a downgrade wasn't actually initiated because a warning
        # email has not been sent
        subscription = Subscription.get_active_subscription_by_domain(domain)
        self.assertNotEqual(subscription.plan_version.plan.edition, SoftwarePlanEdition.PAUSED)

        # fake the warning to have been triggered a few days ago
        warning_days_ago = DAYS_PAST_DUE_TO_TRIGGER_DOWNGRADE - DAYS_PAST_DUE_TO_TRIGGER_DOWNGRADE_WARNING
        history = InvoiceCommunicationHistory.objects.filter(
            invoice=latest_invoice
        ).latest('date_created')
        history.date_created = datetime.date.today() - datetime.timedelta(days=warning_days_ago)
        history.save()

        # now trigger a successful downgrade
        downgrade_eligible_domains(only_downgrade_domain=domain.name)
        subscription = Subscription.get_active_subscription_by_domain(domain)
        self.assertEqual(subscription.plan_version.plan.edition, SoftwarePlanEdition.PAUSED)
Ejemplo n.º 32
0
def get_default_export_settings_if_available(domain):
    """
    Only creates settings if the domain has the DEFAULT_EXPORT_SETTINGS privilege
    """
    settings = None
    current_subscription = Subscription.get_active_subscription_by_domain(
        domain)
    if current_subscription and domain_has_privilege(domain,
                                                     DEFAULT_EXPORT_SETTINGS):
        from corehq.apps.export.models import DefaultExportSettings
        settings = DefaultExportSettings.objects.get_or_create(
            account=current_subscription.account)[0]

    return settings
Ejemplo n.º 33
0
def appcues_template_app_test(request):
    # See if user is in test
    test = ABTest(APPCUES_TEMPLATE_APP, request)
    if test.version(assign_if_blank=False) != APPCUES_TEMPLATE_APP_OPTION_ON:
        return False

    # If the user's trial has run out, they may no longer have access to web apps
    domain = getattr(request, 'domain', None)
    if domain:
        subscription = Subscription.get_active_subscription_by_domain(domain)
        if not subscription or not subscription.is_trial:
            return False

    return True
Ejemplo n.º 34
0
 def apply_prbac(cls, request):
     subscription = (
         Subscription.get_active_subscription_by_domain(request.domain)
         if hasattr(request, 'domain') else None
     )
     if subscription:
         plan_version = subscription.plan_version
         request.role = plan_version.role
         request.plan = plan_version
         request.subscription = subscription
     else:
         plan_version = DefaultProductPlan.get_default_plan_version()
         request.role = plan_version.role
         request.plan = plan_version
Ejemplo n.º 35
0
def notify_repeater_admins(repeater):
    msg = (f'Forwarding data to {repeater} has consistently failed, '
           'and has been paused.')
    send_mail_async.delay(
        f'Repeater threshold exceeded on domain {repeater.domain}', msg,
        from_email=settings.DEFAULT_FROM_EMAIL,
        recipient_list=[MOTECH_DEV],
    )
    if repeater.notify_addresses:
        recipient_list = repeater.notify_addresses
    else:
        subs = Subscription.get_active_subscription_by_domain(repeater.domain)
        recipient_list = subs.account.billingcontactinfo.email_list
    send_mail_async.delay(
        'Data forwarding paused', msg,
        from_email=settings.DEFAULT_FROM_EMAIL,
        recipient_list=recipient_list,
    )
Ejemplo n.º 36
0
def get_paused_plan_context(request, domain):
    from corehq.apps.accounting.models import Subscription
    from corehq.apps.domain.views import SelectPlanView

    current_sub = Subscription.get_active_subscription_by_domain(domain)
    if (not current_sub or not current_sub.plan_version.is_paused
            or not current_sub.previous_subscription):
        return {}

    previous_edition = (
        current_sub.previous_subscription.plan_version.plan.edition
        if current_sub.previous_subscription else "")
    return {
        'is_paused': True,
        'previous_edition': previous_edition,
        'paused_date': current_sub.date_start.strftime(USER_DATE_FORMAT),
        'change_plan_url': reverse(SelectPlanView.urlname, args=[domain]),
        'can_edit_billing_info': request.couch_user.is_domain_admin(domain),
    }
Ejemplo n.º 37
0
def get_default_export_settings_for_domain(domain):
    """
    Only creates settings if the the subscription level supports it
    Currently only available to Enterprise accounts with the DEFAULT_EXPORT_SETTINGS FF enabled
    """
    if not toggles.DEFAULT_EXPORT_SETTINGS.enabled(domain):
        return None

    settings = None
    current_subscription = Subscription.get_active_subscription_by_domain(
        domain)
    # currently only available for enterprise customers
    supported_editions = [SoftwarePlanEdition.ENTERPRISE]
    if current_subscription.plan_version.plan.edition in supported_editions:
        from corehq.apps.export.models import DefaultExportSettings
        settings = DefaultExportSettings.objects.get_or_create(
            account=current_subscription.account)[0]

    return settings
Ejemplo n.º 38
0
 def _low_credits_context(self):
     context = {}
     current_subscription = Subscription.get_active_subscription_by_domain(self.domain)
     if current_subscription:
         monthly_fee = current_subscription.plan_version.product_rate.monthly_fee
         if monthly_fee:
             prepaid_credits = get_total_credits_available_for_product(current_subscription)
             num_months_remaining = prepaid_credits / monthly_fee
             prepaid_remaining_date = months_from_date(date.today(), num_months_remaining)
             partial_month_remaining = num_months_remaining % 1
             num_days_in_month = 30  # Approximate
             prepaid_remaining_date += timedelta(days=int(partial_month_remaining * num_days_in_month))
             prepaid_days_remaining = (prepaid_remaining_date - date.today()).days
             if 0 < prepaid_days_remaining < 63:
                 context['show_prepaid_modal'] = True
                 context['prepaid_days_remaining'] = prepaid_days_remaining
                 context['prepaid_weeks_remaining'] = max(prepaid_days_remaining // 7, 1)
                 context['monthly_fee'] = monthly_fee
                 context['edition'] = current_subscription.plan_version.plan.edition
                 context['prepaid_remaining_date'] = prepaid_remaining_date
     return context
Ejemplo n.º 39
0
def get_subscription_properties_by_user(couch_user):
    def _is_paying_subscription(subscription, plan_version):
        NON_PAYING_SERVICE_TYPES = [
            SubscriptionType.TRIAL,
            SubscriptionType.EXTENDED_TRIAL,
            SubscriptionType.SANDBOX,
            SubscriptionType.INTERNAL,
        ]

        NON_PAYING_PRO_BONO_STATUSES = [
            ProBonoStatus.YES,
            ProBonoStatus.DISCOUNTED,
        ]
        return (plan_version.plan.visibility != SoftwarePlanVisibility.TRIAL
                and subscription.service_type not in NON_PAYING_SERVICE_TYPES
                and subscription.pro_bono_status
                not in NON_PAYING_PRO_BONO_STATUSES
                and plan_version.plan.edition != SoftwarePlanEdition.COMMUNITY)

    # Note: using "yes" and "no" instead of True and False because spec calls
    # for using these values. (True is just converted to "True" in KISSmetrics)
    all_subscriptions = []
    paying_subscribed_editions = []
    subscribed_editions = []
    for domain_name in couch_user.domains:
        subscription = Subscription.get_active_subscription_by_domain(
            domain_name)
        plan_version = (subscription.plan_version if subscription is not None
                        else DefaultProductPlan.get_default_plan_version())
        subscribed_editions.append(plan_version.plan.edition)
        if subscription is not None:
            all_subscriptions.append(subscription)
        if subscription is not None and _is_paying_subscription(
                subscription, plan_version):
            paying_subscribed_editions.append(plan_version.plan.edition)

    def _is_one_of_editions(edition):
        return 'yes' if edition in subscribed_editions else 'no'

    def _is_a_pro_bono_status(status):
        return 'yes' if status in [
            s.pro_bono_status for s in all_subscriptions
        ] else 'no'

    def _is_on_extended_trial():
        service_types = [s.service_type for s in all_subscriptions]
        return 'yes' if SubscriptionType.EXTENDED_TRIAL in service_types else 'no'

    def _max_edition():
        for edition in paying_subscribed_editions:
            assert edition in [e[0] for e in SoftwarePlanEdition.CHOICES]

        return max(
            paying_subscribed_editions) if paying_subscribed_editions else ''

    env = get_instance_string()

    return {
        '{}is_on_community_plan'.format(env):
        _is_one_of_editions(SoftwarePlanEdition.COMMUNITY),
        '{}is_on_standard_plan'.format(env):
        _is_one_of_editions(SoftwarePlanEdition.STANDARD),
        '{}is_on_pro_plan'.format(env):
        _is_one_of_editions(SoftwarePlanEdition.PRO),
        '{}is_on_pro_bono_plan'.format(env):
        _is_a_pro_bono_status(ProBonoStatus.YES),
        '{}is_on_discounted_plan'.format(env):
        _is_a_pro_bono_status(ProBonoStatus.DISCOUNTED),
        '{}is_on_extended_trial_plan'.format(env):
        _is_on_extended_trial(),
        '{}max_edition_of_paying_plan'.format(env):
        _max_edition()
    }
Ejemplo n.º 40
0
def get_overdue_invoice(domain_name):
    current_subscription = Subscription.get_active_subscription_by_domain(domain_name)
    if current_subscription and is_subscription_eligible_for_downgrade_process(current_subscription):
        overdue_invoice, _ = get_unpaid_invoices_over_threshold_by_domain(date.today(), domain_name)
        return overdue_invoice
Ejemplo n.º 41
0
def domain_is_on_trial(domain_name):
    from corehq.apps.accounting.models import Subscription
    subscription = Subscription.get_active_subscription_by_domain(domain_name)
    return subscription and subscription.is_trial
Ejemplo n.º 42
0
def get_subscription_properties_by_user(couch_user):

    def _is_paying_subscription(subscription, plan_version):
        NON_PAYING_SERVICE_TYPES = [
            SubscriptionType.TRIAL,
            SubscriptionType.EXTENDED_TRIAL,
            SubscriptionType.SANDBOX,
            SubscriptionType.INTERNAL,
        ]

        NON_PAYING_PRO_BONO_STATUSES = [
            ProBonoStatus.YES,
            ProBonoStatus.DISCOUNTED,
        ]
        return (plan_version.plan.visibility != SoftwarePlanVisibility.TRIAL and
                subscription.service_type not in NON_PAYING_SERVICE_TYPES and
                subscription.pro_bono_status not in NON_PAYING_PRO_BONO_STATUSES and
                plan_version.plan.edition != SoftwarePlanEdition.COMMUNITY)

    # Note: using "yes" and "no" instead of True and False because spec calls
    # for using these values. (True is just converted to "True" in KISSmetrics)
    all_subscriptions = []
    paying_subscribed_editions = []
    subscribed_editions = []
    for domain_name in couch_user.domains:
        subscription = Subscription.get_active_subscription_by_domain(domain_name)
        plan_version = (
            subscription.plan_version
            if subscription is not None
            else DefaultProductPlan.get_default_plan_version()
        )
        subscribed_editions.append(plan_version.plan.edition)
        if subscription is not None:
            all_subscriptions.append(subscription)
            if _is_paying_subscription(subscription, plan_version):
                paying_subscribed_editions.append(plan_version.plan.edition)

    def _is_one_of_editions(edition):
        return 'yes' if edition in subscribed_editions else 'no'

    def _is_a_pro_bono_status(status):
        return 'yes' if status in [s.pro_bono_status for s in all_subscriptions] else 'no'

    def _is_on_extended_trial():
        service_types = [s.service_type for s in all_subscriptions]
        return 'yes' if SubscriptionType.EXTENDED_TRIAL in service_types else 'no'

    def _max_edition():
        for edition in paying_subscribed_editions:
            assert edition in [e[0] for e in SoftwarePlanEdition.CHOICES]

        return max(paying_subscribed_editions) if paying_subscribed_editions else ''

    env = get_instance_string()

    return {
        '{}is_on_community_plan'.format(env): _is_one_of_editions(SoftwarePlanEdition.COMMUNITY),
        '{}is_on_standard_plan'.format(env): _is_one_of_editions(SoftwarePlanEdition.STANDARD),
        '{}is_on_pro_plan'.format(env): _is_one_of_editions(SoftwarePlanEdition.PRO),
        '{}is_on_pro_bono_plan'.format(env): _is_a_pro_bono_status(ProBonoStatus.YES),
        '{}is_on_discounted_plan'.format(env): _is_a_pro_bono_status(ProBonoStatus.DISCOUNTED),
        '{}is_on_extended_trial_plan'.format(env): _is_on_extended_trial(),
        '{}max_edition_of_paying_plan'.format(env): _max_edition()
    }
Ejemplo n.º 43
0
def domain_is_on_trial(domain_name):
    from corehq.apps.accounting.models import Subscription
    subscription = Subscription.get_active_subscription_by_domain(domain_name)
    return subscription and subscription.is_trial