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)
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
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()
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)
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()
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
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
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
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)
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())
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
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()
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
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, }
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, }
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, }
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]
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
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()
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)
def account(self): return BillingAccount.get_account_by_domain(self.domain)
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 ))
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)
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)
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
def get_account_or_404(domain): account = BillingAccount.get_account_by_domain(domain) if account is None: raise Http404() return account
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) ])
def __init__(self, payment_method, domain): self.payment_method = payment_method self.domain = domain self.account = BillingAccount.get_account_by_domain(self.domain)
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, }
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