Esempio n. 1
0
def email_enterprise_report(domain, slug, couch_user):
    account = BillingAccount.get_account_by_domain(domain)
    report = EnterpriseReport.create(slug, account.id, couch_user)

    # Generate file
    csv_file = io.StringIO()
    writer = csv.writer(csv_file)
    writer.writerow(report.headers)
    writer.writerows(report.rows)

    # Store file in redis
    hash_id = uuid.uuid4().hex
    redis = get_redis_client()
    redis.set(hash_id, csv_file.getvalue())
    redis.expire(hash_id, 60 * 60 * 24)
    csv_file.close()

    # Send email
    url = absolute_reverse("enterprise_dashboard_download", args=[domain, report.slug, str(hash_id)])
    link = "<a href='{}'>{}</a>".format(url, url)
    subject = _("Enterprise Dashboard: {}").format(report.title)
    body = "The enterprise report you requested for the account {} is ready.<br>" \
           "You can download the data at the following link: {}<br><br>" \
           "Please remember that this link will only be active for 24 hours.".format(account.name, link)
    send_html_email_async(subject, couch_user.username, body)
Esempio n. 2
0
 def sms_billables(self):
     datespan = DateSpan(DateSentFilter.get_start_date(self.request),
                         DateSentFilter.get_end_date(self.request))
     selected_billables = SmsBillable.get_billables_sent_between(datespan)
     if DateCreatedFilter.use_filter(self.request):
         date_span = DateSpan(
             DateCreatedFilter.get_start_date(self.request),
             DateCreatedFilter.get_end_date(self.request))
         selected_billables = SmsBillable.filter_selected_billables_by_date(
             selected_billables, date_span)
     domain = EnterpriseDomainFilter.get_value(self.request, self.domain)
     if domain:
         selected_billables = selected_billables.filter(domain=domain, )
     else:
         account = BillingAccount.get_account_by_domain(self.request.domain)
         domains = Subscription.get_active_domains_for_account(account)
         selected_billables = selected_billables.filter(domain__in=domains)
     has_gateway_fee = HasGatewayFeeFilter.get_value(
         self.request, self.domain)
     if has_gateway_fee:
         if has_gateway_fee == HasGatewayFeeFilter.YES:
             selected_billables = selected_billables.exclude(
                 gateway_fee=None)
         else:
             selected_billables = selected_billables.filter(
                 gateway_fee=None)
     gateway_type = GatewayTypeFilter.get_value(self.request, self.domain)
     if gateway_type:
         selected_billables = selected_billables.filter(
             gateway_fee__criteria__backend_api_id=gateway_type, )
     return selected_billables
Esempio n. 3
0
def _get_account_name(domain):
    from corehq.apps.accounting.models import BillingAccount
    account = BillingAccount.get_account_by_domain(domain)
    if account is not None:
        return f'account:{account.name}'
    else:
        return f'no_account:{domain}'
def migrate_mirrors(apps, schema_editor):
    from corehq.apps.enterprise.models import EnterprisePermissions
    DomainPermissionsMirror = apps.get_model('users',
                                             'DomainPermissionsMirror')
    sources = {o.source for o in DomainPermissionsMirror.objects.all()}
    for source in sources:
        account = BillingAccount.get_account_by_domain(source)
        account_domains = set(account.get_domains())
        mirror_domains = {
            o.mirror
            for o in DomainPermissionsMirror.objects.filter(source=source)
        }
        if EnterprisePermissions.objects.filter(account=account).exists():
            print(f"""
            Found a pre-existing enterprise permissions configuration for account {account.id}.
            Enterprise permissions no longer supports multiple configurations in the same account.
            Please delete one of the DomainPermissionsMirror source domains in this account.
            """)
            sys.exit(1)
        EnterprisePermissions(
            account=account,
            is_enabled=True,
            source_domain=source,
            domains=list(account_domains & mirror_domains - {source}),
        ).save()
Esempio n. 5
0
def email_enterprise_report(domain, slug, couch_user):
    account = BillingAccount.get_account_by_domain(domain)
    report = EnterpriseReport.create(slug, account.id, couch_user)

    # Generate file
    csv_file = io.StringIO()
    writer = csv.writer(csv_file)
    writer.writerow(report.headers)
    writer.writerows(report.rows)

    # Store file in redis
    hash_id = uuid.uuid4().hex
    redis = get_redis_client()
    redis.set(hash_id, csv_file.getvalue())
    redis.expire(hash_id, 60 * 60 * 24)
    csv_file.close()

    # Send email
    url = absolute_reverse("enterprise_dashboard_download", args=[domain, report.slug, str(hash_id)])
    link = "<a href='{}'>{}</a>".format(url, url)
    subject = _("Enterprise Dashboard: {}").format(report.title)
    body = "The enterprise report you requested for the account {} is ready.<br>" \
           "You can download the data at the following link: {}<br><br>" \
           "Please remember that this link will only be active for 24 hours.".format(account.name, link)
    send_html_email_async(subject, couch_user.username, body)
Esempio n. 6
0
 def domain_has_editable_identity_provider(cls, domain):
     """
     Check to see that a Domain is associated with an IdentityProvider
     that is editable.
     :param domain: (String) Domain name
     :return: Boolean (True if an editable IdentityProvider exists)
     """
     owner = BillingAccount.get_account_by_domain(domain)
     return cls.objects.filter(owner=owner, is_editable=True).exists()
Esempio n. 7
0
 def is_domain_using_custom_deactivation(cls, domain):
     if not toggles.AUTO_DEACTIVATE_MOBILE_WORKERS.enabled(
             domain, namespace=toggles.NAMESPACE_DOMAIN):
         return False
     account = BillingAccount.get_account_by_domain(domain)
     try:
         emw_settings = cls.objects.get(account=account)
         return emw_settings.allow_custom_deactivation
     except cls.DoesNotExist:
         return False
Esempio n. 8
0
def _get_account_or_404(request, domain):
    account = BillingAccount.get_account_by_domain(domain)

    if account is None:
        raise Http404()

    if not account.has_enterprise_admin(request.couch_user.username):
        if not has_privilege(request, privileges.ACCOUNTING_ADMIN):
            raise Http404()

    return account
Esempio n. 9
0
def _get_account_or_404(request, domain):
    account = BillingAccount.get_account_by_domain(domain)

    if account is None:
        raise Http404()

    if not account.has_enterprise_admin(request.couch_user.username):
        if not has_privilege(request, privileges.ACCOUNTING_ADMIN):
            raise Http404()

    return account
Esempio n. 10
0
 def get_by_domain(cls, domain):
     """
     Get or create the configuration associated with the given domain's account.
     Note that the domain may be the source domain, one of the controlled domains,
     or another domain in the account that does not use enterprise permissions.
     """
     account = BillingAccount.get_account_by_domain(domain)
     try:
         return cls.objects.get(account=account)
     except cls.DoesNotExist:
         return cls(account=account)
Esempio n. 11
0
def is_domain_using_sso(domain):
    """
    Determines whether a given project is under an active Identity Provider or
    if it trusts an active Identity Provider.
    :param domain: domain name (string)
    :return: boolean (True if using SSO based on the criteria above)
    """
    account = BillingAccount.get_account_by_domain(domain)
    return (IdentityProvider.objects.filter(owner=account,
                                            is_active=True).exists()
            or TrustedIdentityProvider.objects.filter(
                domain=domain, identity_provider__is_active=True).exists())
Esempio n. 12
0
def can_add_extra_mobile_workers(request):
    from corehq.apps.users.models import CommCareUser
    from corehq.apps.accounting.models import BillingAccount
    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):
        account = BillingAccount.get_account_by_domain(request.domain)
        if account is None or account.date_confirmed_extra_charges is None:
            return False
    return True
Esempio n. 13
0
def _setup_subscription(domain_name, user):
    with transaction.atomic():
        ensure_community_or_paused_subscription(
            domain_name, date.today(), SubscriptionAdjustmentMethod.USER,
            web_user=user.username,
        )

    # add user's email as contact email for billing account for the domain
    account = BillingAccount.get_account_by_domain(domain_name)
    billing_contact, _ = BillingContactInfo.objects.get_or_create(account=account)
    billing_contact.email_list = [user.email]
    billing_contact.save()
Esempio n. 14
0
def can_add_extra_mobile_workers(request):
    from corehq.apps.users.models import CommCareUser
    from corehq.apps.accounting.models import BillingAccount
    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):
        account = BillingAccount.get_account_by_domain(request.domain)
        if account is None or account.date_confirmed_extra_charges is None:
            return False
    return True
Esempio n. 15
0
def domain_billing_context(request):
    is_domain_billing_admin = False
    if getattr(request, 'couch_user', None) and getattr(
            request, 'domain', None):
        account = BillingAccount.get_account_by_domain(request.domain)
        if account:
            if has_privilege(request, privileges.ACCOUNTING_ADMIN):
                is_domain_billing_admin = True
            elif account.has_enterprise_admin(request.couch_user.username):
                is_domain_billing_admin = True
    return {
        'IS_DOMAIN_BILLING_ADMIN': is_domain_billing_admin,
    }
Esempio n. 16
0
def domain_billing_context(request):
    is_domain_billing_admin = False
    restrict_domain_creation = settings.RESTRICT_DOMAIN_CREATION
    if getattr(request, 'couch_user', None) and getattr(request, 'domain', None):
        account = BillingAccount.get_account_by_domain(request.domain)
        if account:
            if has_privilege(request, privileges.ACCOUNTING_ADMIN):
                is_domain_billing_admin = True
            elif account.has_enterprise_admin(request.couch_user.username):
                is_domain_billing_admin = True
            if not is_domain_billing_admin:
                restrict_domain_creation = restrict_domain_creation or account.restrict_domain_creation
    return {
        'IS_DOMAIN_BILLING_ADMIN': is_domain_billing_admin,
        'restrict_domain_creation': restrict_domain_creation,
    }
Esempio n. 17
0
def domain_billing_context(request):
    is_domain_billing_admin = False
    restrict_domain_creation = settings.RESTRICT_DOMAIN_CREATION
    if getattr(request, 'couch_user', None) and getattr(request, 'domain', None):
        account = BillingAccount.get_account_by_domain(request.domain)
        if account:
            if has_privilege(request, privileges.ACCOUNTING_ADMIN):
                is_domain_billing_admin = True
            elif account.has_enterprise_admin(request.couch_user.username):
                is_domain_billing_admin = True
            if not is_domain_billing_admin:
                restrict_domain_creation = restrict_domain_creation or account.restrict_domain_creation
    return {
        'IS_DOMAIN_BILLING_ADMIN': is_domain_billing_admin,
        'restrict_domain_creation': restrict_domain_creation,
    }
Esempio n. 18
0
 def _format_billables(self, sms_billables):
     return [[
         sms_billable.date_sent,
         BillingAccount.get_account_by_domain(sms_billable.domain).name,
         sms_billable.domain,
         {
             INCOMING: _("Incoming"),
             OUTGOING: _("Outgoing"),
         }.get(sms_billable.direction, ""),
         sms_billable.multipart_count,
         sms_billable.gateway_fee.criteria.backend_api_id
         if sms_billable.gateway_fee else "",
         sms_billable.gateway_charge,
         sms_billable.usage_charge,
         sms_billable.gateway_charge + sms_billable.usage_charge,
         sms_billable.log_id,
         sms_billable.is_valid,
         sms_billable.date_created,
     ] for sms_billable in sms_billables]
Esempio n. 19
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user)

    dom_req = RegistrationRequest()
    if is_new_user:
        dom_req.request_time = now
        dom_req.request_ip = get_ip(request)
        dom_req.activation_guid = uuid.uuid1().hex

    project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get(
        'project_name')
    name = name_to_url(project_name, "project")
    with CriticalSection(['request_domain_name_{}'.format(name)]):
        name = Domain.generate_name(name)
        new_domain = Domain(name=name,
                            hr_name=project_name,
                            is_active=False,
                            date_created=datetime.utcnow(),
                            creating_user=current_user.username,
                            secure_submissions=True,
                            use_sql_backend=True,
                            first_domain_for_user=is_new_user)

        if form.cleaned_data.get('domain_timezone'):
            new_domain.default_timezone = form.cleaned_data['domain_timezone']

        if not is_new_user:
            new_domain.is_active = True

        # ensure no duplicate domain documents get created on cloudant
        new_domain.save(**get_safe_write_kwargs())

    if not new_domain.name:
        new_domain.name = new_domain._id
        new_domain.save()  # we need to get the name from the _id

    if is_new_user:
        # Only new-user domains are eligible for Advanced trial
        # domains with no subscription are equivalent to be on free Community plan
        create_30_day_advanced_trial(new_domain, current_user.username)
    else:
        ensure_explicit_community_subscription(new_domain.name, date.today())

    UserRole.init_domain_with_presets(new_domain.name)

    # add user's email as contact email for billing account for the domain
    account = BillingAccount.get_account_by_domain(new_domain.name)
    billing_contact, _ = BillingContactInfo.objects.get_or_create(
        account=account)
    billing_contact.email_list = [current_user.email]
    billing_contact.save()

    dom_req.domain = new_domain.name

    if request.user.is_authenticated():
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username

    if is_new_user:
        dom_req.save()
        send_domain_registration_email(request.user.email, dom_req.domain,
                                       dom_req.activation_guid,
                                       request.user.get_full_name())
    send_new_request_update_email(request.user,
                                  get_ip(request),
                                  new_domain.name,
                                  is_new_user=is_new_user)

    meta = get_meta(request)
    track_created_new_project_space_on_hubspot.delay(current_user,
                                                     request.COOKIES, meta)
    return new_domain.name
Esempio n. 20
0
 def domain_has_editable_identity_provider(cls, domain):
     owner = BillingAccount.get_account_by_domain(domain)
     return cls.objects.filter(owner=owner, is_editable=True).exists()
Esempio n. 21
0
def manage_registry(request, domain, registry_slug):
    registry = _get_registry_or_404(domain, registry_slug)
    if not RegistryPermissionCheck(
            domain, request.couch_user).can_manage_registry(registry.slug):
        return HttpResponseForbidden()

    is_owner = registry.domain == domain
    all_invitations = list(registry.invitations.all())
    domain_invitation = [
        invitation for invitation in all_invitations
        if invitation.domain == domain
    ][0]
    if is_owner:
        invitations = all_invitations
        grants = registry.grants.all()
        available_domains = BillingAccount.get_account_by_domain(
            domain).get_domains()
    else:
        invitations, available_domains = [], []
        grants = registry.grants.filter(
            Q(from_domain=domain) | Q(to_domains__contains=[domain]))
    context = {
        "domain": domain,
        "is_owner": is_owner,
        "registry": {
            "domain":
            registry.domain,
            "current_domain":
            domain,
            "is_owner":
            is_owner,
            "name":
            registry.name,
            "description":
            registry.description or '',
            "slug":
            registry.slug,
            "is_active":
            registry.is_active,
            "schema":
            registry.wrapped_schema.case_types,
            "invitations": [
                invitation.to_json() for invitation in invitations
                if invitation.domain != domain
            ],
            "domain_invitation":
            domain_invitation,
            "grants": [grant.to_json() for grant in grants]
        },
        "available_case_types":
        list(get_data_dict_case_types(registry.domain)),
        "available_domains": available_domains,
        "invited_domains":
        [invitation.domain for invitation in all_invitations],
        "log_action_types":
        DataRegistryAuditViewHelper.action_options(is_owner),
        "user_timezone": get_timezone_for_user(request.couch_user, domain),
        "current_page": {
            "title":
            _("Manage Registry"),
            "page_name":
            _("Manage Registry"),
            "parents": [
                {
                    "title": _("Data Registries"),
                    "page_name": _("Data Registries"),
                    "url": reverse("data_registries", args=[domain]),
                },
            ],
        },
        'section': {
            'page_name': _('Project Settings'),
            'url': reverse("domain_settings_default", args=[domain]),
        },
    }
    return render(request, "registry/registry_edit.html", context)
Esempio n. 22
0
 def account(self):
     return BillingAccount.get_account_by_domain(self.domain)
Esempio n. 23
0
    def process_request(self, request):
        customer = None
        amount = self.get_charge_amount(request)
        card = request.POST.get('stripeToken')
        remove_card = request.POST.get('removeCard')
        is_saved_card = request.POST.get('selectedCardType') == 'saved'
        save_card = request.POST.get('saveCard') and not is_saved_card
        autopay = request.POST.get('autopayCard')
        billing_account = BillingAccount.get_account_by_domain(self.domain)
        generic_error = {
            'error': {
                'message': _(
                    "Something went wrong while processing your payment. "
                    "We're working quickly to resolve the issue. No charges "
                    "were issued. Please try again in a few hours."
                ),
            },
        }
        try:
            with transaction.atomic():
                if remove_card:
                    self.payment_method.remove_card(card)
                    return {'success': True, 'removedCard': card, }
                if save_card:
                    card = self.payment_method.create_card(card, billing_account, self.domain, autopay=autopay)
                if save_card or is_saved_card:
                    customer = self.payment_method.customer

                payment_record = PaymentRecord.create_record(
                    self.payment_method, 'temp', amount
                )
                self.update_credits(payment_record)

                charge = self.create_charge(amount, card=card, customer=customer)

            payment_record.transaction_id = charge.id
            payment_record.save()
            self.update_payment_information(billing_account)
        except stripe.error.CardError as e:
            # card was declined
            return e.json_body
        except (
            stripe.error.AuthenticationError,
            stripe.error.InvalidRequestError,
            stripe.error.APIConnectionError,
            stripe.error.StripeError,
        ) as e:
            log_accounting_error(
                "A payment for %(cost_item)s failed due "
                "to a Stripe %(error_class)s: %(error_msg)s" % {
                    'error_class': e.__class__.__name__,
                    'cost_item': self.cost_item_name,
                    'error_msg': e.json_body['error']
                }
            )
            return generic_error
        except Exception as e:
            log_accounting_error(
                "A payment for %(cost_item)s failed due to: %(error_msg)s" % {
                    'cost_item': self.cost_item_name,
                    'error_msg': e,
                }
            )
            return generic_error

        try:
            self.send_email(payment_record)
        except Exception:
            log_accounting_error(
                "Failed to send out an email receipt for "
                "payment related to PaymentRecord No. %s. "
                "Everything else succeeded."
                % payment_record.id
            )

        return {
            'success': True,
            'card': card,
            'wasSaved': save_card,
            'changedBalance': amount,
        }
    def handle(self, *args, **options):
        if raw_input(
            'Are you sure you want to re-bill all SMS billables with'
            ' gateway fees in INR calculated prior to March 1, 2016?\n'
            'This action will invalidate the old billables, create new ones,'
            ' and add the difference as general account credit to each'
            ' affected domain. \n[y/n]'
        ).lower() != 'y':
            raise CommandError('abort')

        inr = Currency.objects.filter(code="INR").first()

        affected_criteria = SmsBillable.objects.filter(
            gateway_fee__currency__code=inr.code,
            date_created__lt=datetime.date(2016, 3, 1),
            is_valid=True
        )
        for unique_b in affected_criteria.order_by('domain').distinct('domain'):
            all_affected_billables = affected_criteria.filter(
                domain=unique_b.domain,
            )
            total_affected = all_affected_billables.count()
            if total_affected > 0:
                print(
                    "\nUpdating {total_affected} billables for"
                    " domain {domain}".format(
                        domain=unique_b.domain,
                        total_affected=total_affected
                    )
                )
                stdout.write(">> BILLABLES: ")
            total_diff = Decimal('0.0')
            for billable in all_affected_billables.all():
                stdout.write('.')
                updated_billable = self._get_updated_billable(billable, inr)

                old_gateway_cost = (
                    billable.gateway_fee.amount /
                    billable.gateway_fee_conversion_rate
                )
                new_gateway_cost = (
                    updated_billable.gateway_fee.amount /
                    updated_billable.gateway_fee_conversion_rate
                )

                difference = old_gateway_cost - new_gateway_cost
                total_diff += difference * Decimal('1.0000')
                total_diff += difference * Decimal('1.0000')
            stdout.flush()
            if total_diff > Decimal('0.0'):
                print(
                    "\n!! >>> FOUND difference of {diff}, "
                    "applying General Credits to domain {domain}".format(
                        diff=round(total_diff, 4),
                        domain=unique_b.domain,
                    )
                )
                try:
                    affected_account = BillingAccount.get_account_by_domain(unique_b.domain)
                    CreditLine.add_credit(
                        total_diff,
                        affected_account,
                        note="Automated re-calc for UNICEL SMS Fees due to incorrect"
                             "conversion rate",
                        reason=CreditAdjustmentReason.MANUAL,
                    )
                    for b in all_affected_billables.all():
                        b.is_valid = False
                        b.save()
                except Exception as e:
                    print("Could not add credits to {domain} due to {error}".format(
                        domain=unique_b.domain,
                        error=e
                    ))
Esempio n. 25
0
 def __init__(self, payment_method, domain):
     self.payment_method = payment_method
     self.domain = domain
     self.account = BillingAccount.get_account_by_domain(self.domain)
    def handle(self, *args, **options):
        if len(args) != 1:
            print "Invalid arguments: %s" % str(args)
            return

        completed = 0
        total = 0
        filename = args[0]
        with open(filename) as f:
            reader = csv.reader(f)
            reader.next()
            for row in reader:
                total = total + 1
                domain = row[0]
                plan_version, subscription = Subscription.get_subscribed_plan_by_domain(
                    domain)
                if subscription is None:
                    print "Could not find Subscription for %s" % domain

                account = BillingAccount.get_account_by_domain(domain)
                if account is None:
                    print "Could not find BillingAccount for %s" % domain

                if account is not None and subscription is not None:
                    '''
                    service_type = self.normalize(row[1])  # self service, contracted, or not set
                    if service_type == "selfservice":
                        #print "%s service_type => SELF_SERVICE" % domain
                        subscription.service_type = SubscriptionType.SELF_SERVICE
                    elif service_type == "contracted":
                        #print "%s service_type => CONTRACTED" % domain
                        subscription.service_type = SubscriptionType.CONTRACTED
                    elif service_type == "notset":
                        #print "%s service_type => NOT_SET" % domain
                        subscription.service_type = SubscriptionType.NOT_SET
                    else:
                        pass
                        #print "Skipping service type for %s" % domain

                    entry_point = self.normalize(row[2])  # yes if self starter, might be missing
                    if entry_point == "yes":
                        #print "%s entry_point => SELF_STARTED" % domain
                        account.entry_point = EntryPoint.SELF_STARTED
                    elif entry_point == "no":
                        #print "%s entry_point => CONTRACTED" % domain
                        account.entry_point = EntryPoint.CONTRACTED
                    else:
                        #print "Skipping entry point for %s" % domain
                        pass
                    '''

                    pro_bono_status = self.normalize(row[3])  # yes/no
                    if pro_bono_status == "yes":
                        #print "%s pro_bono_status => YES" % domain
                        subscription.pro_bono_status = ProBonoStatus.YES
                    elif pro_bono_status == "discounted":
                        #print "%s pro_bono_status => DISCOUNTED" % domain
                        subscription.pro_bono_status = ProBonoStatus.DISCOUNTED
                    else:
                        #print "%s pro_bono_status => NO" % domain
                        subscription.pro_bono_status = ProBonoStatus.NO
                    '''print "setting %s's service_type=%s, entry_point=%s, pro_bono=%s" % (
                        domain, subscription.service_type, account.entry_point, subscription.pro_bono_status
                    )'''

                    subscription.save()
                    account.save()
                    completed = completed + 1

        print "Completed %i of %i domains" % (completed, total)
Esempio n. 27
0
 def _for_domains(self):
     return BillingAccount.get_account_by_domain(self.domain).get_domains()
    def handle(self, *args, **options):
        if len(args) != 1:
            print "Invalid arguments: %s" % str(args)
            return

        completed = 0
        total = 0
        filename = args[0]
        with open(filename) as f:
            reader = csv.reader(f)
            reader.next()
            for row in reader:
                total = total + 1
                domain = row[0]
                plan_version, subscription = Subscription.get_subscribed_plan_by_domain(domain)
                if subscription is None:
                    print "Could not find Subscription for %s" % domain

                account = BillingAccount.get_account_by_domain(domain)
                if account is None:
                    print "Could not find BillingAccount for %s" % domain

                if account is not None and subscription is not None:
                    '''
                    service_type = self.normalize(row[1])  # self service, contracted, or not set
                    if service_type == "selfservice":
                        #print "%s service_type => SELF_SERVICE" % domain
                        subscription.service_type = SubscriptionType.SELF_SERVICE
                    elif service_type == "contracted":
                        #print "%s service_type => CONTRACTED" % domain
                        subscription.service_type = SubscriptionType.CONTRACTED
                    elif service_type == "notset":
                        #print "%s service_type => NOT_SET" % domain
                        subscription.service_type = SubscriptionType.NOT_SET
                    else:
                        pass
                        #print "Skipping service type for %s" % domain

                    entry_point = self.normalize(row[2])  # yes if self starter, might be missing
                    if entry_point == "yes":
                        #print "%s entry_point => SELF_STARTED" % domain
                        account.entry_point = EntryPoint.SELF_STARTED
                    elif entry_point == "no":
                        #print "%s entry_point => CONTRACTED" % domain
                        account.entry_point = EntryPoint.CONTRACTED
                    else:
                        #print "Skipping entry point for %s" % domain
                        pass
                    '''

                    pro_bono_status = self.normalize(row[3])  # yes/no
                    if pro_bono_status == "yes":
                        #print "%s pro_bono_status => YES" % domain
                        subscription.pro_bono_status = ProBonoStatus.YES
                    elif pro_bono_status == "discounted":
                        #print "%s pro_bono_status => DISCOUNTED" % domain
                        subscription.pro_bono_status = ProBonoStatus.DISCOUNTED
                    else:
                        #print "%s pro_bono_status => NO" % domain
                        subscription.pro_bono_status = ProBonoStatus.NO

                    '''print "setting %s's service_type=%s, entry_point=%s, pro_bono=%s" % (
                        domain, subscription.service_type, account.entry_point, subscription.pro_bono_status
                    )'''

                    subscription.save()
                    account.save()
                    completed = completed + 1

        print "Completed %i of %i domains" % (completed, total)
Esempio n. 29
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user, strict=True)

    dom_req = RegistrationRequest()
    if is_new_user:
        dom_req.request_time = now
        dom_req.request_ip = get_ip(request)
        dom_req.activation_guid = uuid.uuid1().hex

    project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get('project_name')
    name = name_to_url(project_name, "project")
    with CriticalSection(['request_domain_name_{}'.format(name)]):
        name = Domain.generate_name(name)
        new_domain = Domain(
            name=name,
            hr_name=project_name,
            is_active=False,
            date_created=datetime.utcnow(),
            creating_user=current_user.username,
            secure_submissions=True,
            use_sql_backend=True,
            first_domain_for_user=is_new_user
        )

        # Avoid projects created by dimagi.com staff members as self started
        new_domain.internal.self_started = not current_user.is_dimagi

        if form.cleaned_data.get('domain_timezone'):
            new_domain.default_timezone = form.cleaned_data['domain_timezone']

        if not is_new_user:
            new_domain.is_active = True

        # ensure no duplicate domain documents get created on cloudant
        new_domain.save(**get_safe_write_kwargs())

    if not new_domain.name:
        new_domain.name = new_domain._id
        new_domain.save()  # we need to get the name from the _id

    if is_new_user:
        # Only new-user domains are eligible for Advanced trial
        # domains with no subscription are equivalent to be on free Community plan
        create_30_day_advanced_trial(new_domain, current_user.username)
    else:
        ensure_explicit_community_subscription(
            new_domain.name, date.today(), SubscriptionAdjustmentMethod.USER,
            web_user=current_user.username,
        )

    UserRole.init_domain_with_presets(new_domain.name)

    # add user's email as contact email for billing account for the domain
    account = BillingAccount.get_account_by_domain(new_domain.name)
    billing_contact, _ = BillingContactInfo.objects.get_or_create(account=account)
    billing_contact.email_list = [current_user.email]
    billing_contact.save()

    dom_req.domain = new_domain.name

    if request.user.is_authenticated:
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username

    if is_new_user:
        dom_req.save()
        if settings.IS_SAAS_ENVIRONMENT:
            from corehq.apps.app_manager.tasks import load_appcues_template_app
            chain(
                load_appcues_template_app.si(new_domain.name, current_user.username, HEALTH_APP),
                load_appcues_template_app.si(new_domain.name, current_user.username, AGG_APP),
                load_appcues_template_app.si(new_domain.name, current_user.username, WASH_APP),
                send_domain_registration_email.si(
                    request.user.email,
                    dom_req.domain,
                    dom_req.activation_guid,
                    request.user.get_full_name(),
                    request.user.first_name
                )
            ).apply_async()
        else:
            send_domain_registration_email(request.user.email,
                                           dom_req.domain,
                                           dom_req.activation_guid,
                                           request.user.get_full_name(),
                                           request.user.first_name)
    send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user)

    send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request)
    return new_domain.name
Esempio n. 30
0
def get_account_or_404(domain):
    account = BillingAccount.get_account_by_domain(domain)
    if account is None:
        raise Http404()
    return account
Esempio n. 31
0
 def options(self):
     account = BillingAccount.get_account_by_domain(self.request.domain)
     return clean_options([
         (domain, domain)
         for domain in Subscription.get_active_domains_for_account(account)
     ])
Esempio n. 32
0
 def __init__(self, payment_method, domain):
     self.payment_method = payment_method
     self.domain = domain
     self.account = BillingAccount.get_account_by_domain(self.domain)
Esempio n. 33
0
    def process_request(self, request):
        customer = None
        amount = self.get_charge_amount(request)
        card = request.POST.get('stripeToken')
        remove_card = request.POST.get('removeCard')
        is_saved_card = request.POST.get('selectedCardType') == 'saved'
        save_card = request.POST.get('saveCard') and not is_saved_card
        autopay = request.POST.get('autopayCard')
        billing_account = BillingAccount.get_account_by_domain(self.domain)
        generic_error = {
            'error': {
                'message':
                _("Something went wrong while processing your payment. "
                  "We're working quickly to resolve the issue. No charges "
                  "were issued. Please try again in a few hours."),
            },
        }
        try:
            with transaction.atomic():
                if remove_card:
                    self.payment_method.remove_card(card)
                    return {
                        'success': True,
                        'removedCard': card,
                    }
                if save_card:
                    card = self.payment_method.create_card(card,
                                                           billing_account,
                                                           self.domain,
                                                           autopay=autopay)
                if save_card or is_saved_card:
                    customer = self.payment_method.customer

                payment_record = PaymentRecord.create_record(
                    self.payment_method, 'temp', amount)
                self.update_credits(payment_record)

                charge = self.create_charge(amount,
                                            card=card,
                                            customer=customer)

            payment_record.transaction_id = charge.id
            payment_record.save()
            self.update_payment_information(billing_account)
        except stripe.error.CardError as e:
            # card was declined
            return e.json_body
        except (
                stripe.error.AuthenticationError,
                stripe.error.InvalidRequestError,
                stripe.error.APIConnectionError,
                stripe.error.StripeError,
        ) as e:
            log_accounting_error(
                "A payment for %(cost_item)s failed due "
                "to a Stripe %(error_class)s: %(error_msg)s" % {
                    'error_class': e.__class__.__name__,
                    'cost_item': self.cost_item_name,
                    'error_msg': e.json_body['error']
                },
                show_stack_trace=True,
            )
            return generic_error
        except Exception as e:
            log_accounting_error(
                "A payment for %(cost_item)s failed due to: %(error_msg)s" % {
                    'cost_item': self.cost_item_name,
                    'error_msg': e,
                },
                show_stack_trace=True,
            )
            return generic_error

        try:
            self.send_email(payment_record)
        except Exception:
            log_accounting_error(
                "Failed to send out an email receipt for "
                "payment related to PaymentRecord No. %s. "
                "Everything else succeeded." % payment_record.id,
                show_stack_trace=True,
            )

        return {
            'success': True,
            'card': card,
            'wasSaved': save_card,
            'changedBalance': amount,
        }
Esempio n. 34
0
def request_new_domain(request, form, is_new_user=True):
    now = datetime.utcnow()
    current_user = CouchUser.from_django_user(request.user, strict=True)

    dom_req = RegistrationRequest()
    if is_new_user:
        dom_req.request_time = now
        dom_req.request_ip = get_ip(request)
        dom_req.activation_guid = uuid.uuid1().hex

    project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get(
        'project_name')
    name = name_to_url(project_name, "project")
    with CriticalSection(['request_domain_name_{}'.format(name)]):
        name = Domain.generate_name(name)
        new_domain = Domain(name=name,
                            hr_name=project_name,
                            is_active=False,
                            date_created=datetime.utcnow(),
                            creating_user=current_user.username,
                            secure_submissions=True,
                            use_sql_backend=True,
                            first_domain_for_user=is_new_user)

        # Avoid projects created by dimagi.com staff members as self started
        new_domain.internal.self_started = not current_user.is_dimagi

        if form.cleaned_data.get('domain_timezone'):
            new_domain.default_timezone = form.cleaned_data['domain_timezone']

        if not is_new_user:
            new_domain.is_active = True

        # ensure no duplicate domain documents get created on cloudant
        new_domain.save(**get_safe_write_kwargs())

    if not new_domain.name:
        new_domain.name = new_domain._id
        new_domain.save()  # we need to get the name from the _id

    with transaction.atomic():
        if is_new_user:
            # Only new-user domains are eligible for Advanced trial
            # domains with no subscription are equivalent to be on free Community plan
            create_30_day_advanced_trial(new_domain, current_user.username)
        else:
            ensure_explicit_community_subscription(
                new_domain.name,
                date.today(),
                SubscriptionAdjustmentMethod.USER,
                web_user=current_user.username,
            )

    UserRole.init_domain_with_presets(new_domain.name)

    # add user's email as contact email for billing account for the domain
    account = BillingAccount.get_account_by_domain(new_domain.name)
    billing_contact, _ = BillingContactInfo.objects.get_or_create(
        account=account)
    billing_contact.email_list = [current_user.email]
    billing_contact.save()

    dom_req.domain = new_domain.name

    if request.user.is_authenticated:
        if not current_user:
            current_user = WebUser()
            current_user.sync_from_django_user(request.user)
            current_user.save()
        current_user.add_domain_membership(new_domain.name, is_admin=True)
        current_user.save()
        dom_req.requesting_user_username = request.user.username
        dom_req.new_user_username = request.user.username

    if is_new_user:
        dom_req.save()
        if settings.IS_SAAS_ENVIRONMENT:
            #  Load template apps to the user's new domain in parallel
            from corehq.apps.app_manager.tasks import load_appcues_template_app
            header = [
                load_appcues_template_app.si(new_domain.name,
                                             current_user.username, slug)
                for slug in APPCUES_APP_SLUGS
            ]
            callback = send_domain_registration_email.si(
                request.user.email, dom_req.domain, dom_req.activation_guid,
                request.user.get_full_name(), request.user.first_name)
            chord(header)(callback)
        else:
            send_domain_registration_email(request.user.email, dom_req.domain,
                                           dom_req.activation_guid,
                                           request.user.get_full_name(),
                                           request.user.first_name)
    send_new_request_update_email(request.user,
                                  get_ip(request),
                                  new_domain.name,
                                  is_new_user=is_new_user)

    send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request)
    return new_domain.name