def setUp(self):
        super(TestNewDomainSubscription, self).setUp()
        self.domain = Domain(
            name="test-domain-sub",
            is_active=True,
        )
        self.domain.save()

        self.domain2 = Domain(
            name="test-domain-sub2",
            is_active=True,
        )
        self.domain2.save()

        self.admin_user = generator.arbitrary_web_user()
        self.admin_user.add_domain_membership(self.domain.name, is_admin=True)
        self.admin_user.save()

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.admin_user.username)[0]
        self.account2 = BillingAccount.get_or_create_account_by_domain(
            self.domain2.name, created_by=self.admin_user.username)[0]
        self.standard_plan = DefaultProductPlan.get_default_plan(
            edition=SoftwarePlanEdition.STANDARD)
        self.advanced_plan = DefaultProductPlan.get_default_plan(
            edition=SoftwarePlanEdition.ADVANCED)
Ejemplo n.º 2
0
    def setUp(self):
        super(TestSubscriptionForm, self).setUp()

        self.domain = Domain(
            name="test-sub-form",
            is_active=True
        )
        self.domain.save()
        self.domain2 = Domain(
            name="test-sub-form-2",
            is_active=True
        )
        self.domain2.save()

        self.web_user = WebUser.create(
            self.domain.name, generator.create_arbitrary_web_user_name(), 'testpwd'
        )

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.web_user.username
        )[0]
        self.account.save()
        self.customer_account = BillingAccount.get_or_create_account_by_domain(
            self.domain2.name, created_by=self.web_user.username
        )[0]
        self.customer_account.is_customer_billing_account = True
        self.customer_account.save()

        self.plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        self.customer_plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        self.customer_plan.plan.is_customer_software_plan = True
    def setUp(self):
        super(TestNewDomainSubscription, self).setUp()
        self.domain = Domain(
            name="test-domain-sub",
            is_active=True,
        )
        self.domain.save()

        self.domain2 = Domain(
            name="test-domain-sub2",
            is_active=True,
        )
        self.domain2.save()

        self.admin_user = generator.arbitrary_web_user()
        self.admin_user.add_domain_membership(self.domain.name, is_admin=True)
        self.admin_user.save()

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.admin_user.username)[0]
        self.account2 = BillingAccount.get_or_create_account_by_domain(
            self.domain2.name, created_by=self.admin_user.username)[0]
        self.standard_plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain.name, edition=SoftwarePlanEdition.STANDARD)
        self.advanced_plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain.name, edition=SoftwarePlanEdition.ADVANCED)
Ejemplo n.º 4
0
    def setUp(self):
        super(TestSubscriptionForm, self).setUp()

        self.domain = Domain(
            name="test-sub-form",
            is_active=True
        )
        self.domain.save()
        self.domain2 = Domain(
            name="test-sub-form-2",
            is_active=True
        )
        self.domain2.save()

        self.web_user = WebUser.create(
            self.domain.name, generator.create_arbitrary_web_user_name(), 'testpwd'
        )

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.web_user.username
        )[0]
        self.account.save()
        self.customer_account = BillingAccount.get_or_create_account_by_domain(
            self.domain2.name, created_by=self.web_user.username
        )[0]
        self.customer_account.is_customer_billing_account = True
        self.customer_account.save()

        self.plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        self.customer_plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        self.customer_plan.plan.is_customer_software_plan = True
Ejemplo n.º 5
0
    def create_wire_invoice(self, balance):

        # Gather relevant invoices
        invoices = Invoice.objects.filter(
            subscription__subscriber__domain=self.domain,
            is_hidden=False,
            date_paid__exact=None,
        ).order_by('-date_start')

        BillingAccount.get_or_create_account_by_domain(
            self.domain.name,
            created_by=self.__class__.__name__,
            entry_point=EntryPoint.SELF_STARTED,
        )[0]

        # If no start date supplied, default earliest start date of unpaid invoices
        if self.date_start:
            date_start = self.date_start
        else:
            date_start = invoices.aggregate(
                Min('date_start'))['date_start__min']

        # If no end date supplied, default latest end date of unpaid invoices
        if self.date_end:
            date_end = self.date_end
        else:
            date_end = invoices.aggregate(Max('date_end'))['date_end__max']

        if not date_end:
            date_end = datetime.datetime.today()

        date_due = date_end + datetime.timedelta(DEFAULT_DAYS_UNTIL_DUE)

        wire_invoice = WireInvoice.objects.create(
            domain=self.domain.name,
            date_start=date_start,
            date_end=date_end,
            date_due=date_due,
            balance=balance,
        )

        record = WireBillingRecord.generate_record(wire_invoice)

        if record.should_send_email:
            try:
                for email in self.contact_emails:
                    record.send_email(contact_email=email)
            except InvoiceEmailThrottledError as e:
                # Currently wire invoices are never throttled
                if not self.logged_throttle_error:
                    log_accounting_error(e.message)
                    self.logged_throttle_error = True
        else:
            record.skipped_email = True
            record.save()

        return wire_invoice
Ejemplo n.º 6
0
def billing_account(web_user_creator, web_user_contact, currency=None, save=True):
    account_name = data_gen.arbitrary_unique_name(prefix="BA")[:40]
    currency = currency or Currency.objects.get(code=settings.DEFAULT_CURRENCY)
    billing_account = BillingAccount(name=account_name, created_by=web_user_creator.username, currency=currency)
    if save:
        billing_account.save()
        billing_contact = arbitrary_contact_info(billing_account, web_user_contact)
        billing_contact.save()
    return billing_account
Ejemplo n.º 7
0
 def create_account(self):
     name = self.cleaned_data['name']
     salesforce_account_id = self.cleaned_data['salesforce_account_id']
     currency, _ = Currency.objects.get_or_create(code=self.cleaned_data['currency'])
     account = BillingAccount(name=name,
                              salesforce_account_id=salesforce_account_id,
                              currency=currency)
     account.save()
     return account
Ejemplo n.º 8
0
    def create_account(self):
        name = self.cleaned_data["name"]
        salesforce_account_id = self.cleaned_data["salesforce_account_id"]
        currency, _ = Currency.objects.get_or_create(code=self.cleaned_data["currency"])
        account = BillingAccount(name=name, salesforce_account_id=salesforce_account_id, currency=currency)
        account.save()

        contact_info, _ = BillingContactInfo.objects.get_or_create(account=account)
        contact_info.emails = self.cleaned_data["contact_emails"]
        contact_info.save()

        return account
Ejemplo n.º 9
0
 def account(self):
     account = BillingAccount.get_or_create_account_by_domain(
         self.domain,
         created_by=self.couch_user.username,
         account_type=BillingAccountType.USER_CREATED,
     )[0]
     return account
 def handle(self, *args, **options):
     if len(args) != 1:
         print "Invalid arguments: %s" % str(args)
         return
     domain = Domain.get_by_name(args[0])
     if not domain:
         print "Invalid domain name: %s" % args[0]
         return
     account, _ = BillingAccount.get_or_create_account_by_domain(
         domain.name,
         account_type=BillingAccountType.CONTRACT,
         created_by="management command",
     )
     enterprise_plan_version = SoftwarePlanVersion.objects.filter(
         plan__edition=SoftwarePlanEdition.ENTERPRISE
     )[0]
     try:
         subscription = Subscription.new_domain_subscription(
             account,
             domain.name,
             enterprise_plan_version
         )
     except NewSubscriptionError as e:
         print e.message
         return
     subscription.is_active = True
     subscription.save()
     print 'Domain %s has been upgraded to enterprise level.' % domain.name
Ejemplo n.º 11
0
def assign_explicit_community_subscription(domain_name, start_date):
    future_subscriptions = Subscription.objects.filter(
        CONSISTENT_DATES_CHECK
    ).filter(
        date_start__gt=start_date,
        subscriber__domain=domain_name,
    )
    if future_subscriptions.exists():
        end_date = future_subscriptions.latest('date_start').date_start
    else:
        end_date = None

    return Subscription.new_domain_subscription(
        account=BillingAccount.get_or_create_account_by_domain(
            domain_name,
            created_by='assign_explicit_community_subscriptions',
            entry_point=EntryPoint.SELF_STARTED,
        )[0],
        domain=domain_name,
        plan_version=DefaultProductPlan.get_default_plan_version(),
        date_start=start_date,
        date_end=end_date,
        skip_invoicing_if_no_feature_charges=True,
        adjustment_method=SubscriptionAdjustmentMethod.TASK,
        internal_change=True,
        service_type=SubscriptionType.PRODUCT,
    )
Ejemplo n.º 12
0
def create_wire_credits_invoice(domain_name,
                                account_created_by,
                                account_entry_point,
                                amount,
                                invoice_items,
                                contact_emails):
    account = BillingAccount.get_or_create_account_by_domain(
        domain_name,
        created_by=account_created_by,
        entry_point=account_entry_point
    )[0]
    wire_invoice = WirePrepaymentInvoice.objects.create(
        domain=domain_name,
        date_start=datetime.datetime.utcnow(),
        date_end=datetime.datetime.utcnow(),
        date_due=None,
        balance=amount,
        account=account,
    )
    wire_invoice.items = invoice_items

    record = WirePrepaymentBillingRecord.generate_record(wire_invoice)
    if record.should_send_email:
        try:
            record.send_email(contact_emails=contact_emails)
        except Exception as e:
            log_accounting_error(
                "Error sending email for WirePrepaymentBillingRecord %d: %s" % (record.id, e.message),
                show_stack_trace=True,
            )
    else:
        record.skipped_email = True
        record.save()
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
 def ensure_full_coverage(self, subscriptions):
     plan_version = DefaultProductPlan.get_default_plan_by_domain(
         self.domain,
         edition=SoftwarePlanEdition.COMMUNITY).plan.get_version()
     if not plan_version.feature_charges_exist_for_domain(self.domain):
         return
     community_ranges = self.get_community_ranges(subscriptions)
     if not community_ranges:
         return
     do_not_invoice = any([s.do_not_invoice for s in subscriptions])
     account = BillingAccount.get_or_create_account_by_domain(
         self.domain.name,
         created_by=self.__class__.__name__,
         created_by_invoicing=True)[0]
     if account.date_confirmed_extra_charges is None:
         subject = "[%s] Invoice Generation Issue" % self.domain.name
         email_content = render_to_string(
             'accounting/invoice_error_email.html', {
                 'project':
                 self.domain.name,
                 'error_msg':
                 "This project is incurring charges on their "
                 "Community subscription, but they haven't "
                 "agreed to the charges yet. Someone should "
                 "follow up with this project to see if everything "
                 "is configured correctly or if communication "
                 "needs to happen between Dimagi and the project's"
                 "admins. For now, the invoices generated are "
                 "marked as Do Not Invoice.",
             })
         send_HTML_email(subject,
                         settings.BILLING_EMAIL,
                         email_content,
                         email_from="Dimagi Billing Bot <%s>" %
                         settings.DEFAULT_FROM_EMAIL)
         do_not_invoice = True
     if not BillingContactInfo.objects.filter(account=account).exists():
         # No contact information exists for this account.
         # This shouldn't happen, but if it does, we can't continue
         # with the invoice generation.
         raise BillingContactInfoError(
             "Project %s has incurred charges, but does not have their "
             "Billing Contact Info filled out. Someone should follow up "
             "on this." % self.domain.name)
     # First check to make sure none of the existing subscriptions is set
     # to do not invoice. Let's be on the safe side and not send a
     # community invoice out, if that's the case.
     for c in community_ranges:
         # create a new community subscription for each
         # date range that the domain did not have a subscription
         community_subscription = Subscription(
             account=account,
             plan_version=plan_version,
             subscriber=self.subscriber,
             date_start=c[0],
             date_end=c[1],
             do_not_invoice=do_not_invoice,
         )
         community_subscription.save()
         subscriptions.append(community_subscription)
Ejemplo n.º 15
0
def create_wire_credits_invoice(domain_name,
                                account_created_by,
                                account_entry_point,
                                amount,
                                invoice_items,
                                contact_emails):
    account = BillingAccount.get_or_create_account_by_domain(
        domain_name,
        created_by=account_created_by,
        created_by_invoicing=True,
        entry_point=account_entry_point
    )[0]
    wire_invoice = WirePrepaymentInvoice.objects.create(
        domain=domain_name,
        date_start=datetime.datetime.utcnow(),
        date_end=datetime.datetime.utcnow(),
        date_due=None,
        balance=amount,
        account=account,
    )
    wire_invoice.items = invoice_items

    record = WirePrepaymentBillingRecord.generate_record(wire_invoice)
    try:
        record.send_email(contact_emails=contact_emails)
    except Exception as e:
        logger.error("[BILLING] %s" % e)
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()
Ejemplo n.º 17
0
 def update_credits(self, payment_record):
     amount = payment_record.amount
     for invoice in self.invoices:
         deduct_amount = min(amount, invoice.balance)
         amount -= deduct_amount
         if deduct_amount > 0:
             if self.account and self.account.is_customer_billing_account:
                 customer_invoice = invoice
                 subscription_invoice = None
                 account = self.account
             else:
                 customer_invoice = None
                 subscription_invoice = invoice
                 account = invoice.subscription.account
             # TODO - refactor duplicated functionality
             CreditLine.add_credit(
                 deduct_amount,
                 account=account,
                 payment_record=payment_record,
             )
             CreditLine.add_credit(
                 -deduct_amount,
                 account=account,
                 invoice=subscription_invoice,
                 customer_invoice=customer_invoice
             )
             invoice.update_balance()
             invoice.save()
     if amount:
         account = BillingAccount.get_or_create_account_by_domain(self.domain)[0]
         CreditLine.add_credit(
             amount, account=account,
             payment_record=payment_record,
         )
Ejemplo n.º 18
0
 def setUp(self):
     super(TestCreditTransfers, self).setUp()
     self.product_credit_amt = Decimal("500.00")
     self.feature_credit_amt = Decimal("200.00")
     self.subscription_credit_amt = Decimal("600.00")
     self.domain = generator.arbitrary_domain()
     self.account = BillingAccount.get_or_create_account_by_domain(self.domain, created_by="*****@*****.**")[0]
Ejemplo n.º 19
0
def _deactivate_subscription(subscription):
    subscription.is_active = False
    subscription.save()
    next_subscription = subscription.next_subscription
    activate_next_subscription = next_subscription and next_subscription.date_start == subscription.date_end
    if activate_next_subscription:
        new_plan_version = next_subscription.plan_version
        next_subscription.is_active = True
        next_subscription.save()
    else:
        domain = subscription.subscriber.domain
        if not subscription.account.is_customer_billing_account:
            account = subscription.account
        else:
            account = BillingAccount.create_account_for_domain(
                domain, created_by='default_community_after_customer_level'
            )
        next_subscription = assign_explicit_community_subscription(
            domain, subscription.date_end, SubscriptionAdjustmentMethod.DEFAULT_COMMUNITY, account=account
        )
        new_plan_version = next_subscription.plan_version
    _, downgraded_privs, upgraded_privs = get_change_status(subscription.plan_version, new_plan_version)
    if subscription.account == next_subscription.account:
        subscription.transfer_credits(subscription=next_subscription)
    else:
        subscription.transfer_credits()
    subscription.subscriber.deactivate_subscription(
        downgraded_privileges=downgraded_privs,
        upgraded_privileges=upgraded_privs,
        old_subscription=subscription,
        new_subscription=next_subscription if activate_next_subscription else None,
    )
Ejemplo n.º 20
0
def prepare_domain(domain_name):
    from corehq.apps.commtrack.tests import bootstrap_domain
    domain = bootstrap_domain(domain_name)
    previous = None
    for name, administrative in [("MOHSW", True), ("MSDZONE", True),
                                 ("REGION", True), ("DISTRICT", True),
                                 ("FACILITY", False)]:
        previous, _ = LocationType.objects.get_or_create(
            domain=domain_name,
            name=name,
            parent_type=previous,
            administrative=administrative,
        )

    generator.instantiate_accounting_for_tests()
    account = BillingAccount.get_or_create_account_by_domain(
        domain.name,
        created_by="automated-test",
    )[0]
    plan = DefaultProductPlan.get_default_plan_by_domain(
        domain, edition=SoftwarePlanEdition.ADVANCED)
    commtrack = domain.commtrack_settings
    commtrack.actions.append(
        CommtrackActionConfig(action='receipts',
                              keyword='delivered',
                              caption='Delivered'))
    commtrack.save()
    subscription = Subscription.new_domain_subscription(
        account, domain.name, plan)
    subscription.is_active = True
    subscription.save()
    ils_config = ILSGatewayConfig(enabled=True, domain=domain.name)
    ils_config.save()
    return domain
Ejemplo n.º 21
0
 def account(self):
     """
     First try to grab the account used for the last subscription.
     If an account is not found, create it.
     """
     account, _ = BillingAccount.get_or_create_account_by_domain(self.domain.name, self.__class__.__name__)
     return account
Ejemplo n.º 22
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
Ejemplo n.º 23
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}'
Ejemplo n.º 24
0
def assign_explicit_community_subscription(domain_name, start_date, method, account=None, web_user=None):
    future_subscriptions = Subscription.visible_objects.filter(
        date_start__gt=start_date,
        subscriber__domain=domain_name,
    )
    if future_subscriptions.exists():
        end_date = future_subscriptions.earliest('date_start').date_start
    else:
        end_date = None

    if account is None:
        account = BillingAccount.get_or_create_account_by_domain(
            domain_name,
            created_by='assign_explicit_community_subscriptions',
            entry_point=EntryPoint.SELF_STARTED,
        )[0]

    return Subscription.new_domain_subscription(
        account=account,
        domain=domain_name,
        plan_version=DefaultProductPlan.get_default_plan_version(),
        date_start=start_date,
        date_end=end_date,
        skip_invoicing_if_no_feature_charges=True,
        adjustment_method=method,
        internal_change=True,
        service_type=SubscriptionType.PRODUCT,
        web_user=web_user,
    )
Ejemplo n.º 25
0
    def check_username_availability(self, data):
        email = data['email'].strip()
        duplicate = CouchUser.get_by_username(email)
        is_existing = User.objects.filter(username__iexact=email).count() > 0 or duplicate

        message = None
        restricted_by_domain = None
        if is_existing:
            message = _("There is already a user with this email.")
        else:
            domain = email[email.find("@") + 1:]
            for account in BillingAccount.get_enterprise_restricted_signup_accounts():
                if domain in account.enterprise_restricted_signup_domains:
                    restricted_by_domain = domain
                    message = account.restrict_signup_message
                    message += _("""
                        <br>Please contact <a href='mailto:{}?subject={}'>{}</a> to register for an account.
                    """).format(account.restrict_signup_email,
                                _("CommCareHQ account request"),
                                account.restrict_signup_email)
                    break
        return {
            'isValid': message is None,
            'restrictedByDomain': restricted_by_domain,
            'message': message,
        }
Ejemplo n.º 26
0
    def setUp(self):
        super(OptTestCase, self).setUp()
        self.domain = "opt-test"

        self.domain_obj = Domain(name=self.domain)
        self.domain_obj.save()

        generator.instantiate_accounting_for_tests()
        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain_obj.name,
            created_by="automated-test",
        )[0]
        plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain_obj, edition=SoftwarePlanEdition.ADVANCED
        )
        self.subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain_obj.name,
            plan
        )
        self.subscription.is_active = True
        self.subscription.save()

        self.backend = TestSMSBackend(is_global=True)
        self.backend.save()

        self.backend_mapping = BackendMapping(
            is_global=True,
            prefix="*",
            backend_id=self.backend._id,
        )
        self.backend_mapping.save()
Ejemplo n.º 27
0
    def setUp(self):
        super(OptTestCase, self).setUp()
        self.domain = "opt-test"

        self.domain_obj = Domain(name=self.domain)
        self.domain_obj.save()

        generator.instantiate_accounting_for_tests()
        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain_obj.name,
            created_by="automated-test",
        )[0]
        plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain_obj, edition=SoftwarePlanEdition.ADVANCED)
        self.subscription = Subscription.new_domain_subscription(
            self.account, self.domain_obj.name, plan)
        self.subscription.is_active = True
        self.subscription.save()

        self.backend = TestSMSBackend(is_global=True)
        self.backend.save()

        self.backend_mapping = BackendMapping(
            is_global=True,
            prefix="*",
            backend_id=self.backend._id,
        )
        self.backend_mapping.save()
Ejemplo n.º 28
0
def _deactivate_subscription(subscription):
    subscription.is_active = False
    subscription.save()
    next_subscription = subscription.next_subscription
    activate_next_subscription = next_subscription and next_subscription.date_start == subscription.date_end
    if activate_next_subscription:
        new_plan_version = next_subscription.plan_version
        next_subscription.is_active = True
        next_subscription.save()
    else:
        domain = subscription.subscriber.domain
        if not subscription.account.is_customer_billing_account:
            account = subscription.account
        else:
            account = BillingAccount.create_account_for_domain(
                domain, created_by='default_community_after_customer_level')
        next_subscription = assign_explicit_community_subscription(
            domain,
            subscription.date_end,
            SubscriptionAdjustmentMethod.DEFAULT_COMMUNITY,
            account=account)
        new_plan_version = next_subscription.plan_version
    _, downgraded_privs, upgraded_privs = get_change_status(
        subscription.plan_version, new_plan_version)
    if subscription.account == next_subscription.account:
        subscription.transfer_credits(subscription=next_subscription)
    else:
        subscription.transfer_credits()
    subscription.subscriber.deactivate_subscription(
        downgraded_privileges=downgraded_privs,
        upgraded_privileges=upgraded_privs,
        old_subscription=subscription,
        new_subscription=next_subscription
        if activate_next_subscription else None,
    )
Ejemplo n.º 29
0
    def test_community_over_limit(self):
        """
        For a domain under community (no subscription) with users over the community limit, make sure that:
        - base_description is None
        - base_cost is 0.0
        - unit_description is not None
        - unit_cost is equal to the per_excess_fee on the user rate
        - quantity is equal to number of commcare users in that domain minus the monthly_limit on the user rate
        - total and subtotals are equal to number of extra users * per_excess_fee
        """
        domain = generator.arbitrary_domain()
        num_active = generator.create_excess_community_users(domain)

        account = BillingAccount.get_or_create_account_by_domain(
            domain, created_by=self.dimagi_user)[0]
        billing_contact = generator.arbitrary_contact_info(account, self.dimagi_user)
        billing_contact.save()
        account.date_confirmed_extra_charges = datetime.date.today()
        account.save()

        tasks.generate_invoices()
        subscriber = Subscriber.objects.get(domain=domain.name)
        invoice = Invoice.objects.filter(subscription__subscriber=subscriber).get()
        user_line_item = invoice.lineitem_set.get_feature_by_type(FeatureType.USER).get()

        self.assertIsNone(user_line_item.base_description)
        self.assertEqual(user_line_item.base_cost, Decimal('0.0000'))

        num_to_charge = num_active - self.community_plan.user_limit
        self.assertIsNotNone(user_line_item.unit_description)
        self.assertEqual(user_line_item.quantity, num_to_charge)
        self.assertEqual(user_line_item.unit_cost, self.user_rate.per_excess_fee)
        self.assertEqual(user_line_item.subtotal, num_to_charge * self.user_rate.per_excess_fee)
        self.assertEqual(user_line_item.total, num_to_charge * self.user_rate.per_excess_fee)
        domain.delete()
Ejemplo n.º 30
0
def assign_explicit_community_subscription(domain_name, start_date, method, account=None, web_user=None):
    future_subscriptions = Subscription.visible_objects.filter(
        date_start__gt=start_date,
        subscriber__domain=domain_name,
    )
    if future_subscriptions.exists():
        end_date = future_subscriptions.earliest('date_start').date_start
    else:
        end_date = None

    if account is None:
        account = BillingAccount.get_or_create_account_by_domain(
            domain_name,
            created_by='assign_explicit_community_subscriptions',
            entry_point=EntryPoint.SELF_STARTED,
        )[0]

    return Subscription.new_domain_subscription(
        account=account,
        domain=domain_name,
        plan_version=DefaultProductPlan.get_default_plan_version(),
        date_start=start_date,
        date_end=end_date,
        skip_invoicing_if_no_feature_charges=True,
        adjustment_method=method,
        internal_change=True,
        service_type=SubscriptionType.PRODUCT,
        web_user=web_user,
    )
Ejemplo n.º 31
0
    def setUp(self):
        super(BaseReminderTestCase, self).setUp()
        self.domain_obj = Domain(name="test")
        self.domain_obj.save()
        # Prevent resource conflict
        self.domain_obj = Domain.get(self.domain_obj._id)

        self.account, _ = BillingAccount.get_or_create_account_by_domain(
            self.domain_obj.name,
            created_by="tests"
        )
        advanced_plan_version = DefaultProductPlan.get_default_plan_by_domain(
            self.domain_obj, edition=SoftwarePlanEdition.ADVANCED)
        self.subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain_obj.name,
            advanced_plan_version
        )
        self.subscription.is_active = True
        self.subscription.save()

        self.sms_backend = TestSMSBackend(named="MOBILE_BACKEND_TEST", is_global=True)
        self.sms_backend.save()

        self.sms_backend_mapping = BackendMapping(is_global=True,prefix="*",backend_id=self.sms_backend._id)
        self.sms_backend_mapping.save()
Ejemplo n.º 32
0
    def setUp(self):
        super(TestRenewSubscriptions, self).setUp()
        self.domain = Domain(
            name="test-domain-sub",
            is_active=True,
        )
        self.domain.save()

        self.admin_user = generator.arbitrary_web_user()
        self.admin_user.add_domain_membership(self.domain.name, is_admin=True)
        self.admin_user.save()

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.admin_user.username)[0]

        self.standard_plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.STANDARD)

        today = datetime.date.today()
        yesterday = today + datetime.timedelta(days=-1)
        tomorrow = today + datetime.timedelta(days=1)

        self.subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            self.standard_plan,
            web_user=self.admin_user.username,
            date_start=yesterday,
            date_end=tomorrow,
        )

        self.subscription.save()
    def setUp(self):
        super(TestUserRoleSubscriptionChanges, self).setUp()
        self.domain = generator.arbitrary_domain()
        UserRole.init_domain_with_presets(self.domain.name)
        self.user_roles = UserRole.by_domain(self.domain.name)
        self.custom_role = UserRole.get_or_create_with_permissions(
            self.domain.name,
            Permissions(edit_apps=True, edit_web_users=True),
            "Custom Role"
        )
        self.custom_role.save()
        self.read_only_role = UserRole.get_read_only_role_by_domain(self.domain.name)

        self.admin_user = generator.arbitrary_web_user()
        self.admin_user.add_domain_membership(self.domain.name, is_admin=True)
        self.admin_user.save()

        self.web_users = []
        self.commcare_users = []
        for role in [self.custom_role] + self.user_roles:
            web_user = generator.arbitrary_web_user()
            web_user.add_domain_membership(self.domain.name, role_id=role.get_id)
            web_user.save()
            self.web_users.append(web_user)

            commcare_user = generator.arbitrary_commcare_user(
                domain=self.domain.name)
            commcare_user.set_role(self.domain.name, role.get_qualified_id())
            commcare_user.save()
            self.commcare_users.append(commcare_user)

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name,created_by=self.admin_user.username)[0]
        self.advanced_plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain.name,edition=SoftwarePlanEdition.ADVANCED)
    def setUp(self):
        super(TestRenewSubscriptions, self).setUp()
        self.domain = Domain(
            name="test-domain-sub",
            is_active=True,
        )
        self.domain.save()

        self.admin_user = generator.arbitrary_web_user()
        self.admin_user.add_domain_membership(self.domain.name, is_admin=True)
        self.admin_user.save()

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.admin_user.username)[0]

        self.standard_plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain.name, edition=SoftwarePlanEdition.STANDARD)

        today = datetime.date.today()
        yesterday = today + datetime.timedelta(days=-1)
        tomorrow = today + datetime.timedelta(days=1)

        self.subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            self.standard_plan,
            web_user=self.admin_user.username,
            date_start=yesterday,
            date_end=tomorrow,
        )

        self.subscription.save()
Ejemplo n.º 35
0
 def test_community_invoice(self):
     """
     For an unsubscribed domain with any charges over the community limit for the month of invoicing,
     make sure that an invoice is generated in addition to a subscription for that month to
     the community plan.
     """
     domain = generator.arbitrary_domain()
     generator.create_excess_community_users(domain)
     account = BillingAccount.get_or_create_account_by_domain(
         domain, created_by=self.dimagi_user)[0]
     billing_contact = generator.arbitrary_contact_info(account, self.dimagi_user)
     account.date_confirmed_extra_charges = datetime.date.today()
     account.save()
     tasks.generate_invoices()
     subscriber = Subscriber.objects.get(domain=domain.name)
     invoices = Invoice.objects.filter(subscription__subscriber=subscriber)
     self.assertEqual(invoices.count(), 1)
     invoice = invoices.get()
     self.assertEqual(invoice.subscription.subscriber.domain, domain.name)
     self.assertEqual(invoice.subscription.date_start, invoice.date_start)
     self.assertEqual(
         invoice.subscription.date_end - datetime.timedelta(days=1),
         invoice.date_end
     )
     domain.delete()
Ejemplo n.º 36
0
    def test_community_over_limit(self):
        """
        For a domain under community (no subscription) with users over the community limit, make sure that:
        - base_description is None
        - base_cost is 0.0
        - unit_description is not None
        - unit_cost is equal to the per_excess_fee on the user rate
        - quantity is equal to number of commcare users in that domain minus the monthly_limit on the user rate
        - total and subtotals are equal to number of extra users * per_excess_fee
        """
        domain = generator.arbitrary_domain()
        num_active = generator.create_excess_community_users(domain)

        account = BillingAccount.get_or_create_account_by_domain(
            domain, created_by=self.dimagi_user)[0]
        billing_contact = generator.arbitrary_contact_info(account, self.dimagi_user)
        account.date_confirmed_extra_charges = datetime.date.today()
        account.save()

        tasks.generate_invoices()
        subscriber = Subscriber.objects.get(domain=domain.name)
        invoice = Invoice.objects.filter(subscription__subscriber=subscriber).get()
        user_line_item = invoice.lineitem_set.get_feature_by_type(FeatureType.USER).get()

        self.assertIsNone(user_line_item.base_description)
        self.assertEqual(user_line_item.base_cost, Decimal('0.0000'))

        community_plan = DefaultProductPlan.get_default_plan_version()
        num_to_charge = num_active - community_plan.user_limit
        self.assertIsNotNone(user_line_item.unit_description)
        self.assertEqual(user_line_item.quantity, num_to_charge)
        self.assertEqual(user_line_item.unit_cost, self.user_rate.per_excess_fee)
        self.assertEqual(user_line_item.subtotal, num_to_charge * self.user_rate.per_excess_fee)
        self.assertEqual(user_line_item.total, num_to_charge * self.user_rate.per_excess_fee)
        domain.delete()
Ejemplo n.º 37
0
    def test_wrong_domain(self):
        '''
        If correct credentials for a user in a different domain are submitted, the response is forbidden
        '''
        wrong_domain = Domain.get_or_create_with_name('dvorak', is_active=True)
        self.addCleanup(wrong_domain.delete)

        # have to set up subscription for the bad domain or it will fail on authorization
        new_account = BillingAccount.get_or_create_account_by_domain(
            wrong_domain.name, created_by="automated-test")[0]
        plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.ADVANCED)
        new_subscription = Subscription.new_domain_subscription(
            new_account, wrong_domain.name, plan)
        new_subscription.is_active = True
        new_subscription.save()
        wrong_list_endpoint = reverse(
            'api_dispatch_list',
            kwargs=dict(domain=wrong_domain.name,
                        api_name=self.api_name,
                        resource_name=self.resource.Meta.resource_name))
        response = self.client.post(wrong_list_endpoint, {
            'username': self.username,
            'password': self.password
        })
        self.assertEqual(response.status_code, 403)
Ejemplo n.º 38
0
    def check_username_availability(self, data):
        email = data['email'].strip()
        duplicate = CouchUser.get_by_username(email)
        is_existing = User.objects.filter(
            username__iexact=email).count() > 0 or duplicate

        message = None
        restricted_by_domain = None
        if is_existing:
            message = _("There is already a user with this email.")
        else:
            domain = email[email.find("@") + 1:]
            for account in BillingAccount.get_enterprise_restricted_signup_accounts(
            ):
                if domain in account.enterprise_restricted_signup_domains:
                    restricted_by_domain = domain
                    message = account.restrict_signup_message
                    regex = r'(\b[a-zA-Z0-9_.+%-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+\b)'
                    subject = _("CommCareHQ account request")
                    message = re.sub(
                        regex,
                        "<a href='mailto:\\1?subject={}'>\\1</a>".format(
                            subject), message)
                    break
        return {
            'isValid': message is None,
            'restrictedByDomain': restricted_by_domain,
            'message': message,
        }
Ejemplo n.º 39
0
 def _setup_accounting(cls):
     cls.account, _ = BillingAccount.get_or_create_account_by_domain(
         cls.domain.name, created_by='')
     plan_version = DefaultProductPlan.get_default_plan_version(
         SoftwarePlanEdition.STANDARD)
     cls.subscription = Subscription.new_domain_subscription(
         cls.account, cls.domain.name, plan_version)
Ejemplo n.º 40
0
    def setUp(self):
        super(TestDeleteDomain, self).setUp()
        self.domain = Domain(name="test", is_active=True)
        self.domain.save()
        self.domain.convert_to_commtrack()
        self.current_subscription = Subscription.new_domain_subscription(
            BillingAccount.get_or_create_account_by_domain(
                self.domain.name, created_by='tests')[0],
            self.domain.name,
            DefaultProductPlan.get_default_plan_version(
                SoftwarePlanEdition.ADVANCED),
            date_start=date.today() - relativedelta(days=1),
        )

        self.domain2 = Domain(name="test2", is_active=True)
        self.domain2.save()
        self.domain2.convert_to_commtrack()

        LocationType.objects.create(
            domain='test',
            name='facility',
        )
        LocationType.objects.create(
            domain='test2',
            name='facility',
        )
        LocationType.objects.create(
            domain='test',
            name='facility2',
        )
        LocationType.objects.create(
            domain='test2',
            name='facility2',
        )
Ejemplo n.º 41
0
    def create_domain(self, domain):
        domain_obj = Domain(name=domain)
        domain_obj.use_default_sms_response = True
        domain_obj.default_sms_response = "Default SMS Response"
        domain_obj.save()

        # I tried making this class inherit from BaseSMSTest, but somehow
        # the multiple inheritance was causing the postgres connection to
        # get in a weird state where it wasn't commiting any changes. So
        # for now, keeping this subscription setup code as is.
        generator.instantiate_accounting_for_tests()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain_obj.name,
            created_by="automated-test",
        )[0]
        plan = DefaultProductPlan.get_default_plan_by_domain(
            domain_obj, edition=SoftwarePlanEdition.ADVANCED
        )
        self.subscription = Subscription.new_domain_subscription(
            self.account,
            domain_obj.name,
            plan
        )
        self.subscription.is_active = True
        self.subscription.save()
        return domain_obj
Ejemplo n.º 42
0
 def test_community_invoice(self):
     """
     For an unsubscribed domain with any charges over the community limit for the month of invoicing,
     make sure that an invoice is generated in addition to a subscription for that month to
     the community plan.
     """
     domain = generator.arbitrary_domain()
     generator.create_excess_community_users(domain)
     account = BillingAccount.get_or_create_account_by_domain(
         domain, created_by=self.dimagi_user)[0]
     billing_contact = generator.arbitrary_contact_info(account, self.dimagi_user)
     billing_contact.save()
     account.date_confirmed_extra_charges = datetime.date.today()
     account.save()
     tasks.generate_invoices()
     subscriber = Subscriber.objects.get(domain=domain.name)
     invoices = Invoice.objects.filter(subscription__subscriber=subscriber)
     self.assertEqual(invoices.count(), 1)
     invoice = invoices.get()
     self.assertEqual(invoice.subscription.subscriber.domain, domain.name)
     self.assertEqual(invoice.subscription.date_start, invoice.date_start)
     self.assertEqual(
         invoice.subscription.date_end - datetime.timedelta(days=1),
         invoice.date_end
     )
     domain.delete()
Ejemplo n.º 43
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)
Ejemplo n.º 44
0
 def update_credits(self, payment_record):
     amount = payment_record.amount
     for invoice in self.invoices:
         deduct_amount = min(amount, invoice.balance)
         amount -= deduct_amount
         if deduct_amount > 0:
             # TODO - refactor duplicated functionality
             CreditLine.add_credit(
                 deduct_amount,
                 account=invoice.subscription.account,
                 payment_record=payment_record,
             )
             CreditLine.add_credit(
                 -deduct_amount,
                 account=invoice.subscription.account,
                 invoice=invoice,
             )
             invoice.update_balance()
             invoice.save()
     if amount:
         account = BillingAccount.get_or_create_account_by_domain(
             self.domain)
         CreditLine.add_credit(
             amount,
             account=account,
             payment_record=payment_record,
         )
Ejemplo n.º 45
0
    def setUpClass(cls):
        super(TestZapierIntegration, cls).setUpClass()
        generator.instantiate_accounting()

        cls.domain_object = Domain.get_or_create_with_name(TEST_DOMAIN,
                                                           is_active=True)
        cls.domain = cls.domain_object.name

        account = BillingAccount.get_or_create_account_by_domain(
            cls.domain, created_by="automated-test")[0]
        plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.STANDARD)
        subscription = Subscription.new_domain_subscription(
            account, cls.domain, plan)
        subscription.is_active = True
        subscription.save()

        cls.web_user = WebUser.create(cls.domain, 'test', '******')
        api_key_object, _ = ApiKey.objects.get_or_create(
            user=cls.web_user.get_django_user())
        cls.api_key = api_key_object.key
        cls.application = Application.new_app(cls.domain, 'Test App')
        cls.application.save()
        module = cls.application.add_module(Module.new_module(
            "Module 1", "en"))
        cls.application.new_form(module.id,
                                 name="Form1",
                                 attachment=XFORM,
                                 lang="en")
        cls.application.save()
Ejemplo n.º 46
0
 def update_credits(self, payment_record):
     amount = payment_record.amount
     for invoice in self.invoices:
         deduct_amount = min(amount, invoice.balance)
         amount -= deduct_amount
         if deduct_amount > 0:
             if self.account and self.account.is_customer_billing_account:
                 customer_invoice = invoice
                 subscription_invoice = None
                 account = self.account
             else:
                 customer_invoice = None
                 subscription_invoice = invoice
                 account = invoice.subscription.account
             # TODO - refactor duplicated functionality
             CreditLine.add_credit(
                 deduct_amount,
                 account=account,
                 payment_record=payment_record,
             )
             CreditLine.add_credit(-deduct_amount,
                                   account=account,
                                   invoice=subscription_invoice,
                                   customer_invoice=customer_invoice)
             invoice.update_balance()
             invoice.save()
     if amount:
         account = BillingAccount.get_or_create_account_by_domain(
             self.domain)[0]
         CreditLine.add_credit(
             amount,
             account=account,
             payment_record=payment_record,
         )
Ejemplo n.º 47
0
    def setUpClass(cls):
        super(APIResourceTest, cls).setUpClass()

        Role.get_cache().clear()
        cls.domain = Domain.get_or_create_with_name('qwerty', is_active=True)
        cls.list_endpoint = cls._get_list_endpoint()
        cls.username = '******'
        cls.password = '******'
        cls.user = WebUser.create(cls.domain.name,
                                  cls.username,
                                  cls.password,
                                  None,
                                  None,
                                  email='*****@*****.**',
                                  first_name='rudolph',
                                  last_name='commcare')
        cls.user.set_role(cls.domain.name, 'admin')
        cls.user.save()

        cls.account = BillingAccount.get_or_create_account_by_domain(
            cls.domain.name, created_by="automated-test")[0]
        plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.ADVANCED)
        cls.subscription = Subscription.new_domain_subscription(
            cls.account, cls.domain.name, plan)
        cls.subscription.is_active = True
        cls.subscription.save()

        cls.api_key, _ = HQApiKey.objects.get_or_create(
            user=WebUser.get_django_user(cls.user))
Ejemplo n.º 48
0
def create_wire_credits_invoice(domain_name, account_created_by,
                                account_entry_point, amount, invoice_items,
                                contact_emails):
    account = BillingAccount.get_or_create_account_by_domain(
        domain_name,
        created_by=account_created_by,
        entry_point=account_entry_point)[0]
    wire_invoice = WirePrepaymentInvoice.objects.create(
        domain=domain_name,
        date_start=datetime.datetime.utcnow(),
        date_end=datetime.datetime.utcnow(),
        date_due=None,
        balance=amount,
        account=account,
    )
    wire_invoice.items = invoice_items

    record = WirePrepaymentBillingRecord.generate_record(wire_invoice)
    if record.should_send_email:
        try:
            record.send_email(contact_emails=contact_emails)
        except Exception as e:
            log_accounting_error(
                "Error sending email for WirePrepaymentBillingRecord %d: %s" %
                (record.id, e.message),
                show_stack_trace=True,
            )
    else:
        record.skipped_email = True
        record.save()
Ejemplo n.º 49
0
def assign_explicit_community_subscription(domain_name, start_date):
    future_subscriptions = Subscription.objects.filter(
        CONSISTENT_DATES_CHECK).filter(
            date_start__gt=start_date,
            subscriber__domain=domain_name,
        )
    if future_subscriptions.exists():
        end_date = future_subscriptions.latest('date_start').date_start
    else:
        end_date = None

    return Subscription.new_domain_subscription(
        account=BillingAccount.get_or_create_account_by_domain(
            domain_name,
            created_by='assign_explicit_community_subscriptions',
            entry_point=EntryPoint.SELF_STARTED,
        )[0],
        domain=domain_name,
        plan_version=DefaultProductPlan.get_default_plan_version(),
        date_start=start_date,
        date_end=end_date,
        skip_invoicing_if_no_feature_charges=True,
        adjustment_method=SubscriptionAdjustmentMethod.TASK,
        internal_change=True,
        service_type=SubscriptionType.PRODUCT,
    )
Ejemplo n.º 50
0
    def setUp(self):
        super(TestDeleteDomain, self).setUp()
        self.domain = Domain(name="test", is_active=True)
        self.domain.save()
        self.domain.convert_to_commtrack()
        self.current_subscription = Subscription.new_domain_subscription(
            BillingAccount.get_or_create_account_by_domain(self.domain.name, created_by='tests')[0],
            self.domain.name,
            DefaultProductPlan.get_default_plan_version(SoftwarePlanEdition.ADVANCED),
            date_start=date.today() - relativedelta(days=1),
        )

        self.domain2 = Domain(name="test2", is_active=True)
        self.domain2.save()
        self.domain2.convert_to_commtrack()

        LocationType.objects.create(
            domain='test',
            name='facility',
        )
        LocationType.objects.create(
            domain='test2',
            name='facility',
        )
        LocationType.objects.create(
            domain='test',
            name='facility2',
        )
        LocationType.objects.create(
            domain='test2',
            name='facility2',
        )
Ejemplo n.º 51
0
 def ensure_full_coverage(self, subscriptions):
     plan_version = DefaultProductPlan.get_default_plan_by_domain(
         self.domain, edition=SoftwarePlanEdition.COMMUNITY
     ).plan.get_version()
     if not plan_version.feature_charges_exist_for_domain(self.domain):
         return
     community_ranges = self.get_community_ranges(subscriptions)
     if not community_ranges:
         return
     do_not_invoice = any([s.do_not_invoice for s in subscriptions])
     account = BillingAccount.get_or_create_account_by_domain(
         self.domain.name, created_by=self.__class__.__name__,
         created_by_invoicing=True)[0]
     if account.date_confirmed_extra_charges is None:
         if self.domain.is_active:
             subject = "[%s] Invoice Generation Issue" % self.domain.name
             email_content = render_to_string(
                 'accounting/invoice_error_email.html', {
                     'project': self.domain.name,
                     'error_msg': "This project is incurring charges on their "
                                  "Community subscription, but they haven't "
                                  "agreed to the charges yet. Someone should "
                                  "follow up with this project to see if everything "
                                  "is configured correctly or if communication "
                                  "needs to happen between Dimagi and the project's"
                                  "admins. For now, the invoices generated are "
                                  "marked as Do Not Invoice.",
                 }
             )
             send_HTML_email(
                 subject, settings.BILLING_EMAIL, email_content,
                 email_from="Dimagi Billing Bot <%s>" % settings.DEFAULT_FROM_EMAIL
             )
         do_not_invoice = True
     if not BillingContactInfo.objects.filter(account=account).exists():
         # No contact information exists for this account.
         # This shouldn't happen, but if it does, we can't continue
         # with the invoice generation.
         raise BillingContactInfoError(
             "Project %s has incurred charges, but does not have their "
             "Billing Contact Info filled out. Someone should follow up "
             "on this." % self.domain.name
         )
     # First check to make sure none of the existing subscriptions is set
     # to do not invoice. Let's be on the safe side and not send a
     # community invoice out, if that's the case.
     for c in community_ranges:
         # create a new community subscription for each
         # date range that the domain did not have a subscription
         community_subscription = Subscription(
             account=account,
             plan_version=plan_version,
             subscriber=self.subscriber,
             date_start=c[0],
             date_end=c[1],
             do_not_invoice=do_not_invoice,
         )
         community_subscription.save()
         subscriptions.append(community_subscription)
Ejemplo n.º 52
0
 def _setup_accounting(cls):
     call_command('cchq_prbac_bootstrap')
     cls.account, _ = BillingAccount.get_or_create_account_by_domain(
         cls.domain.name, created_by='')
     plan_version = DefaultProductPlan.get_default_plan_version(
         SoftwarePlanEdition.ADVANCED)
     cls.subscription = Subscription.new_domain_subscription(
         cls.account, cls.domain.name, plan_version)
Ejemplo n.º 53
0
 def setUp(self):
     super(TestCreditStripePaymentHandler, self).setUp()
     self.domain = Domain(name='test-domain')
     self.domain.save()
     self.payment_method = PaymentMethod()
     self.payment_method.save()
     self.account, _ = BillingAccount.get_or_create_account_by_domain(
         self.domain.name, created_by='*****@*****.**')
Ejemplo n.º 54
0
 def account(self):
     account = BillingAccount.get_or_create_account_by_domain(
         self.domain,
         created_by=self.couch_user.username,
         account_type=BillingAccountType.USER_CREATED,
         entry_point=EntryPoint.SELF_STARTED,
     )[0]
     return account
Ejemplo n.º 55
0
 def setUp(self):
     self.domain = Domain(name='test-domain')
     self.domain.save()
     self.payment_method = PaymentMethod()
     self.payment_method.save()
     self.account, _ = BillingAccount.get_or_create_account_by_domain(
         self.domain.name, created_by='*****@*****.**'
     )
Ejemplo n.º 56
0
    def create_wire_invoice(self, balance):

        # Gather relevant invoices
        if self.account and self.account.is_customer_billing_account:
            invoices = CustomerInvoice.objects.filter(account=self.account)
        else:
            invoices = Invoice.objects.filter(
                subscription__subscriber__domain=self.domain.name,
                is_hidden=False,
                date_paid__exact=None
            ).order_by('-date_start')
            self.account = BillingAccount.get_or_create_account_by_domain(
                self.domain.name,
                created_by=self.__class__.__name__,
                entry_point=EntryPoint.SELF_STARTED
            )[0]

        # If no start date supplied, default earliest start date of unpaid invoices
        if self.date_start:
            date_start = self.date_start
        else:
            date_start = invoices.aggregate(Min('date_start'))['date_start__min']

        # If no end date supplied, default latest end date of unpaid invoices
        if self.date_end:
            date_end = self.date_end
        else:
            date_end = invoices.aggregate(Max('date_end'))['date_end__max']

        if not date_end:
            date_end = datetime.datetime.today()

        date_due = date_end + datetime.timedelta(DEFAULT_DAYS_UNTIL_DUE)

        wire_invoice = WireInvoice.objects.create(
            domain=self.domain.name,
            date_start=date_start,
            date_end=date_end,
            date_due=date_due,
            balance=balance,
        )

        record = WireBillingRecord.generate_record(wire_invoice)

        if record.should_send_email:
            try:
                for email in self.contact_emails:
                    record.send_email(contact_email=email)
            except InvoiceEmailThrottledError as e:
                # Currently wire invoices are never throttled
                if not self.logged_throttle_error:
                    log_accounting_error(six.text_type(e))
                    self.logged_throttle_error = True
        else:
            record.skipped_email = True
            record.save()

        return wire_invoice
Ejemplo n.º 57
0
 def setUpClass(cls):
     super(TestCreditStripePaymentHandler, cls).setUpClass()
     cls.domain = Domain(name='test-domain')
     cls.domain.save()
     cls.payment_method = PaymentMethod()
     cls.payment_method.save()
     cls.account, _ = BillingAccount.get_or_create_account_by_domain(
         cls.domain.name, created_by='*****@*****.**'
     )
Ejemplo n.º 58
0
 def account(self):
     """
     First try to grab the account used for the last subscription.
     If an account is not found, create it.
     """
     account, _ = BillingAccount.get_or_create_account_by_domain(self.domain.name, self.__class__.__name__)
     # todo: fix so that contact_emails gets correctly populated.
     BillingContactInfo.objects.get_or_create(account=account)
     return account
 def setUp(self):
     super(TestCreditStripePaymentHandler, self).setUp()
     self.domain = Domain(name='test-domain')
     self.domain.save()
     self.payment_method = PaymentMethod()
     self.payment_method.save()
     self.account, _ = BillingAccount.get_or_create_account_by_domain(
         self.domain.name, created_by='*****@*****.**'
     )