Esempio n. 1
0
    def test_transfers(self):
        advanced_plan = DefaultProductPlan.get_default_plan_by_domain(self.domain, edition=SoftwarePlanEdition.ADVANCED)
        standard_plan = DefaultProductPlan.get_default_plan_by_domain(self.domain, edition=SoftwarePlanEdition.STANDARD)
        first_sub = Subscription.new_domain_subscription(self.account, self.domain, advanced_plan)

        product_credit = CreditLine.add_credit(
            self.product_credit_amt, subscription=first_sub, product_type=SoftwareProductType.COMMCARE
        )
        feature_credit = CreditLine.add_credit(
            self.feature_credit_amt, subscription=first_sub, feature_type=FeatureType.USER
        )
        subscription_credit = CreditLine.add_credit(self.subscription_credit_amt, subscription=first_sub)
        original_credits = [product_credit, feature_credit, subscription_credit]

        second_sub = first_sub.change_plan(standard_plan)

        second_credits = self._ensure_transfer(original_credits)
        for credit_line in second_credits:
            self.assertEqual(credit_line.subscription.pk, second_sub.pk)

        second_sub.date_end = datetime.date.today() + datetime.timedelta(days=5)
        second_sub.save()

        third_sub = second_sub.renew_subscription()
        third_credits = self._ensure_transfer(second_credits)
        for credit_line in third_credits:
            self.assertEqual(credit_line.subscription.pk, third_sub.pk)

        third_sub.cancel_subscription()
        account_credits = self._ensure_transfer(third_credits)
        for credit_line in account_credits:
            self.assertIsNone(credit_line.subscription)
            self.assertEqual(credit_line.account.pk, self.account.pk)
    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)
Esempio n. 3
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 setUpClass(cls):
        super(BaseCustomerInvoiceCase, cls).setUpClass()

        if cls.is_using_test_plans:
            generator.bootstrap_test_software_plan_versions()

        cls.billing_contact = generator.create_arbitrary_web_user_name()
        cls.dimagi_user = generator.create_arbitrary_web_user_name(is_dimagi=True)
        cls.account = generator.billing_account(
            cls.dimagi_user, cls.billing_contact)
        cls.domain = generator.arbitrary_domain()
        cls.account.is_customer_billing_account = True
        cls.account.save()

        cls.advanced_plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        cls.advanced_plan.plan.is_customer_software_plan = True

        cls.subscription_length = 15  # months
        subscription_start_date = datetime.date(2016, 2, 23)
        subscription_end_date = add_months_to_date(subscription_start_date, cls.subscription_length)
        cls.subscription = generator.generate_domain_subscription(
            cls.account,
            cls.domain,
            date_start=subscription_start_date,
            date_end=subscription_end_date,
        )

        advanced_subscription_end_date = add_months_to_date(subscription_end_date, 2)
        cls.domain2 = generator.arbitrary_domain()
        cls.sub2 = generator.generate_domain_subscription(
            cls.account,
            cls.domain2,
            date_start=subscription_start_date,
            date_end=advanced_subscription_end_date,
            plan_version=cls.advanced_plan
        )

        cls.domain3 = generator.arbitrary_domain()
        cls.sub3 = generator.generate_domain_subscription(
            cls.account,
            cls.domain3,
            date_start=subscription_start_date,
            date_end=advanced_subscription_end_date,
            plan_version=cls.advanced_plan
        )

        # This subscription should not be included in any customer invoices in these tests
        cls.domain_community = generator.arbitrary_domain()
        cls.sub3 = generator.generate_domain_subscription(
            cls.account,
            cls.domain3,
            date_start=subscription_start_date,
            date_end=advanced_subscription_end_date,
            plan_version=DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.COMMUNITY)
        )
Esempio n. 5
0
    def test_transfers(self):
        advanced_plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.ADVANCED
        )
        standard_plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.STANDARD
        )
        first_sub = Subscription.new_domain_subscription(
            self.account, self.domain.name, advanced_plan,
            date_start=datetime.date.today() - relativedelta(days=1),
        )

        product_credit = CreditLine.add_credit(
            self.product_credit_amt, subscription=first_sub,
            is_product=True,
        )
        feature_credit = CreditLine.add_credit(
            self.feature_credit_amt, subscription=first_sub,
            feature_type=FeatureType.USER,
        )
        subscription_credit = CreditLine.add_credit(
            self.subscription_credit_amt, subscription=first_sub,
        )
        original_credits = [
            product_credit, feature_credit, subscription_credit,
        ]

        second_sub = first_sub.change_plan(standard_plan)

        second_credits = self._ensure_transfer(original_credits)
        for credit_line in second_credits:
            self.assertEqual(credit_line.subscription.pk, second_sub.pk)

        second_sub.date_end = datetime.date.today() + datetime.timedelta(days=5)
        second_sub.save()
        third_sub = second_sub.renew_subscription()
        deactivate_subscriptions(second_sub.date_end)
        third_sub = Subscription.visible_objects.get(id=third_sub.id)

        third_credits = self._ensure_transfer(second_credits)
        for credit_line in third_credits:
            self.assertEqual(credit_line.subscription.pk, third_sub.pk)

        third_sub.date_end = third_sub.date_start + relativedelta(days=1)
        third_sub.save()
        Subscription.new_domain_subscription(
            self.other_account, self.domain, DefaultProductPlan.get_default_plan_version(),
            date_start=third_sub.date_end,
        )
        deactivate_subscriptions(third_sub.date_end)

        account_credits = self._ensure_transfer(third_credits)
        for credit_line in account_credits:
            self.assertIsNone(credit_line.subscription)
            self.assertEqual(credit_line.account.pk, self.account.pk)
    def ensure_plans(self, dry_run=False):
        edition_to_features = self.ensure_features(dry_run=dry_run)
        for product_type in self.product_types:
            for edition in self.editions:
                role_slug = self.BOOTSTRAP_EDITION_TO_ROLE[edition]
                try:
                    role = Role.objects.get(slug=role_slug)
                except ObjectDoesNotExist:
                    logging.info("Could not find the role '%s'. Did you forget to run cchq_prbac_bootstrap?")
                    logging.info("Aborting. You should figure this out.")
                    return
                software_plan_version = SoftwarePlanVersion(role=role)

                product, product_rates = self.ensure_product_and_rate(product_type, edition, dry_run=dry_run)
                feature_rates = self.ensure_feature_rates(edition_to_features[edition], edition, dry_run=dry_run)
                software_plan = SoftwarePlan(
                    name='%s Edition' % product.name, edition=edition, visibility=SoftwarePlanVisibility.PUBLIC
                )
                if dry_run:
                    logging.info("[DRY RUN] Creating Software Plan: %s" % software_plan)
                else:
                    try:
                        software_plan = SoftwarePlan.objects.get(name=software_plan.name)
                        logging.info("Plan '%s' already exists. Using existing plan to add version."
                                     % software_plan.name)
                    except ObjectDoesNotExist:
                        software_plan.save()
                        logging.info("Creating Software Plan: %s" % software_plan)

                    software_plan_version.plan = software_plan
                    software_plan_version.save()
                    for product_rate in product_rates:
                        software_plan_version.product_rates.add(product_rate)
                    for feature_rate in feature_rates:
                        software_plan_version.feature_rates.add(feature_rate)
                    software_plan_version.save()

                default_product_plan = DefaultProductPlan(product_type=product.product_type, edition=edition)
                if dry_run:
                    logging.info("[DRY RUN] Setting plan as default for product '%s' and edition '%s'." %
                                 (product.product_type, default_product_plan.edition))
                else:
                    try:
                        default_product_plan = DefaultProductPlan.objects.get(product_type=product.product_type,
                                                                              edition=edition)
                        logging.info("Default for product '%s' and edition '%s' already exists." %
                                     (product.product_type, default_product_plan.edition))
                    except ObjectDoesNotExist:
                        default_product_plan.plan = software_plan
                        default_product_plan.save()
                        logging.info("Setting plan as default for product '%s' and edition '%s'." %
                                     (product.product_type, default_product_plan.edition))
Esempio n. 7
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',
        )
Esempio n. 8
0
        def wrapped(request, *args, **kwargs):
            try:
                if (hasattr(request, 'subscription')
                    and request.subscription is not None
                    and request.subscription.is_trial
                    and request.subscription.date_end is not None
                ):
                    edition_req = DefaultProductPlan.get_lowest_edition_by_domain(
                        request.domain, [slug]
                    )
                    plan_name = request.subscription.plan_version.user_facing_description['name']
                    feature_name = privileges.Titles.get_name_from_privilege(slug)
                    request.show_trial_notice = True
                    request.trial_info = {
                        'current_plan': plan_name,
                        'feature_name': feature_name,
                        'required_plan': edition_req,
                        'date_end': request.subscription.date_end.strftime(USER_DATE_FORMAT)
                    }
                    request.is_billing_admin = (hasattr(request, 'couch_user')
                                                and BillingAccountAdmin.get_admin_status_and_account(
                                                    request.couch_user, request.domain
                                                )[0])

                return requires_privilege(slug, **assignment)(fn)(
                    request, *args, **kwargs
                )
            except PermissionDenied:
                request.show_trial_notice = False
                from corehq.apps.domain.views import SubscriptionUpgradeRequiredView
                return SubscriptionUpgradeRequiredView().get(
                    request, request.domain, slug
                )
    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()
Esempio n. 10
0
    def _test_plan_versions_ensured(self, bootstrap_config):
        ensure_plans(bootstrap_config, True, apps)
        for (edition, is_trial, has_report_builder), config in six.iteritems(bootstrap_config):
            software_plan_version = DefaultProductPlan.get_default_plan_version(
                edition=edition, is_trial=is_trial, is_report_builder_enabled=has_report_builder
            )

            self.assertEqual(software_plan_version.role.slug, config['role'])

            self.assertEqual(software_plan_version.product_rate.monthly_fee, config['product_rate_monthly_fee'])

            self.assertEqual(
                software_plan_version.user_limit,
                config['feature_rates'][FeatureType.USER]['monthly_limit']
            )
            self.assertEqual(
                software_plan_version.user_feature.per_excess_fee,
                config['feature_rates'][FeatureType.USER]['per_excess_fee']
            )

            sms_feature_rate = software_plan_version.feature_rates.get(feature__feature_type=FeatureType.SMS)
            self.assertEqual(
                sms_feature_rate.monthly_limit,
                config['feature_rates'][FeatureType.SMS]['monthly_limit']
            )
            self.assertEqual(sms_feature_rate.per_excess_fee, 0)
Esempio n. 11
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,
    )
Esempio n. 12
0
 def cancel_subscription(self):
     self.subscription.change_plan(
         new_plan_version=DefaultProductPlan.get_default_plan_version(),
         note=self.cancel_form.cleaned_data['note'],
         web_user=self.request.user.username,
     )
     self.subscription_canceled = True
Esempio n. 13
0
def create_30_day_trial(domain_obj):
    from corehq.apps.accounting.models import (
        DefaultProductPlan,
        SoftwarePlanEdition,
        BillingAccount,
        Currency,
        BillingAccountType,
        Subscription,
        SubscriptionAdjustmentMethod,
    )
    # Create a 30 Day Trial subscription to the Advanced Plan
    advanced_plan_version = DefaultProductPlan.get_default_plan_by_domain(
        domain_obj, edition=SoftwarePlanEdition.ADVANCED, is_trial=True
    )
    expiration_date = date.today() + timedelta(days=30)
    trial_account = BillingAccount.objects.get_or_create(
        name="Trial Account for %s" % domain_obj.name,
        currency=Currency.get_default(),
        created_by_domain=domain_obj.name,
        account_type=BillingAccountType.TRIAL,
    )[0]
    trial_subscription = Subscription.new_domain_subscription(
        trial_account, domain_obj.name, advanced_plan_version,
        date_end=expiration_date,
        adjustment_method=SubscriptionAdjustmentMethod.TRIAL,
        is_trial=True,
    )
    trial_subscription.is_active = True
    trial_subscription.save()
Esempio n. 14
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,
    )
    def _init_pro_with_rb_plan_and_version(self):
        plan = SoftwarePlan(
            name="Pro_with_30_RB_reports",
            description="Pro + 30 report builder reports",
            edition=SoftwarePlanEdition.PRO,
            visibility=SoftwarePlanVisibility.INTERNAL,
        )
        plan.save()

        role = Role.objects.create(
            slug="pro_with_rb_30_role",
            name="Pro + 30 rb reports",
        )
        for privilege in [privileges.REPORT_BUILDER_30]:  # Doesn't actually include the pro roles...
            privilege = Role.objects.get(slug=privilege)
            Grant.objects.create(
                from_role=role,
                to_role=privilege,
            )
        self.pro_rb_version = SoftwarePlanVersion(
            plan=plan,
            role=role
        )
        self.pro_rb_version.product_rate = DefaultProductPlan.get_default_plan_version(
            SoftwarePlanEdition.PRO
        ).product_rate
        self.pro_rb_version.save()
Esempio n. 16
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
Esempio n. 17
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()
    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)
Esempio n. 19
0
    def test_resubscription(self):
        subscription = Subscription.new_domain_subscription(
            self.account, self.domain.name, self.advanced_plan,
            web_user=self.admin_user.username
        )
        self._change_std_roles()
        new_subscription = subscription.change_plan(DefaultProductPlan.get_default_plan_version())
        custom_role = UserRole.get(self.custom_role.get_id)
        self.assertTrue(custom_role.is_archived)
        new_subscription.change_plan(self.advanced_plan, web_user=self.admin_user.username)
        custom_role = UserRole.get(self.custom_role.get_id)
        self.assertFalse(custom_role.is_archived)

        # disable this part of the test until we improve the UX for notifying
        # downgraded users of their privilege changes
        # custom_web_user = WebUser.get(self.web_users[0].get_id)
        # custom_commcare_user = CommCareUser.get(self.commcare_users[0].get_id)
        # self.assertEqual(
        #     custom_web_user.get_domain_membership(self.domain.name).role_id,
        #     self.read_only_role.get_id
        # )
        # self.assertIsNone(
        #     custom_commcare_user.get_domain_membership(self.domain.name).role_id
        # )

        self._assertInitialRoles()
        self._assertStdUsers()
Esempio n. 20
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()
Esempio n. 21
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()
Esempio n. 22
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)
Esempio n. 23
0
def _downgrade_domain(subscription):
    subscription.change_plan(
        DefaultProductPlan.get_default_plan_version(
            SoftwarePlanEdition.COMMUNITY
        ),
        note='Automatic downgrade to community for invoice 60 days late',
        internal_change=True
    )
    def test_app_icon_permissions(self):
        LOGO_HOME = 'hq_logo_android_home'
        LOGO_LOGIN = '******'

        advanced_sub = self._subscribe_to_advanced()

        with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-standard.json')) as f:
            standard_source = json.load(f)
        with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-build.json')) as f:
            build_source = json.load(f)

        app_standard = Application.wrap(standard_source)
        app_standard.save()
        self.assertEqual(self.project.name, app_standard.domain)

        app_build = Application.wrap(build_source)
        app_build.save()
        self.assertEqual(self.project.name, app_build.domain)

        self.assertTrue(LOGO_HOME in app_standard.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_standard.logo_refs)
        self.assertTrue(LOGO_HOME in app_build.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_build.logo_refs)

        community_sub = advanced_sub.change_plan(DefaultProductPlan.get_default_plan_version())

        app_standard = Application.get(app_standard._id)
        app_build = Application.get(app_build._id)

        self.assertFalse(LOGO_HOME in app_standard.logo_refs)
        self.assertFalse(LOGO_LOGIN in app_standard.logo_refs)
        self.assertFalse(LOGO_HOME in app_build.logo_refs)
        self.assertFalse(LOGO_LOGIN in app_build.logo_refs)

        community_sub.change_plan(
            DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        )

        app_standard = Application.get(app_standard._id)
        app_build = Application.get(app_build._id)

        self.assertTrue(LOGO_HOME in app_standard.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_standard.logo_refs)
        self.assertTrue(LOGO_HOME in app_build.logo_refs)
        self.assertTrue(LOGO_LOGIN in app_build.logo_refs)
Esempio n. 25
0
def _downgrade_domain(subscription):
    subscription.change_plan(
        DefaultProductPlan.get_default_plan_version(
            SoftwarePlanEdition.COMMUNITY
        ),
        adjustment_method=SubscriptionAdjustmentMethod.AUTOMATIC_DOWNGRADE,
        note='Automatic downgrade to community for invoice 60 days late',
        internal_change=True
    )
    def test_change_plan_on_renewal(self):
        new_edition = SoftwarePlanEdition.ADVANCED
        new_plan = DefaultProductPlan.get_default_plan_by_domain(self.domain.name, new_edition)

        self.renewed_subscription = self.subscription.renew_subscription(
            new_version=new_plan
        )

        self.assertEqual(self.renewed_subscription.plan_version, new_plan)
Esempio n. 27
0
    def setup_subscription(cls, domain_name, software_plan):
        generator.instantiate_accounting()

        plan = DefaultProductPlan.get_default_plan_version(edition=software_plan)
        cls.account = BillingAccount.get_or_create_account_by_domain(
            domain_name, created_by="automated-test" + cls.__name__
        )[0]
        cls.subscription = Subscription.new_domain_subscription(cls.account, domain_name, plan)
        cls.subscription.is_active = True
        cls.subscription.save()
    def setUp(self):
        super(TestSoftwarePlanChanges, self).setUp()
        self.domain = Domain(
            name="test-plan-changes",
            is_active=True,
        )
        self.domain.save()
        self.domain2 = Domain(
            name="other-domain",
            is_active=True,
        )
        self.domain2.save()

        self.admin_username = generator.create_arbitrary_web_user_name()
        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.admin_username)[0]
        self.advanced_plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
        self.advanced_plan.plan.max_domains = 1
        self.community_plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.COMMUNITY)
Esempio n. 29
0
 def setUp(self):
     self._clear_docs()
     self.domain = create_domain(DOMAIN)
     self.account = BillingAccount.get_or_create_account_by_domain(DOMAIN, created_by="automated-test")[0]
     plan = DefaultProductPlan.get_default_plan_by_domain(DOMAIN, edition=SoftwarePlanEdition.ADVANCED)
     self.subscription = Subscription.new_domain_subscription(self.account, DOMAIN, plan)
     self.subscription.is_active = True
     self.subscription.save()
     self.couch_user = WebUser.create(None, "test", "foobar")
     self.couch_user.add_domain_membership(DOMAIN, is_admin=True)
     self.couch_user.save()
Esempio n. 30
0
    def setUpClass(cls):
        super(TestOdataFeed, cls).setUpClass()

        cls.client = Client()
        cls.domain = Domain(name='test_domain')
        cls.domain.save()
        cls.web_user = WebUser.create(cls.domain.name, 'test_user', 'my_password')

        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)
Esempio n. 31
0
def _generate_invoice_and_subscription(days_ago,
                                       is_customer_billing_account=False):
    """
    :param days_ago: The number of days ago an invoice should be due
    :return: random domain, with invoices generated on the backend
    """
    invoice_due_date = datetime.date.today() - datetime.timedelta(
        days=days_ago)

    billing_contact = generator.create_arbitrary_web_user_name()
    dimagi_user = generator.create_arbitrary_web_user_name(is_dimagi=True)
    account = generator.billing_account(dimagi_user, billing_contact)
    account.is_customer_billing_account = is_customer_billing_account
    account.save()

    domain = generator.arbitrary_domain()
    subscription_start_date = utils.months_from_date(invoice_due_date, -2)

    subscription = generator.generate_domain_subscription(
        account,
        domain,
        date_start=subscription_start_date,
        date_end=None,
        plan_version=DefaultProductPlan.get_default_plan_version(
            SoftwarePlanEdition.ADVANCED),
        service_type=SubscriptionType.PRODUCT,
    )
    subscription.is_active = True
    subscription.save()

    invoice_date = utils.months_from_date(invoice_due_date, -1)
    DomainUserHistory.objects.create(domain=domain.name,
                                     num_users=20,
                                     record_date=invoice_date -
                                     datetime.timedelta(days=1))
    tasks.generate_invoices(invoice_date)

    # for testing purposes, force the latest invoice due_date to be
    # the "invoice_due_date" specified above
    if is_customer_billing_account:
        latest_invoice = CustomerInvoice.objects.filter(
            account=account, ).latest('date_created')
    else:
        latest_invoice = subscription.invoice_set.latest('date_created')
    latest_invoice.date_due = invoice_due_date
    latest_invoice.save()

    return domain, latest_invoice
    def setUp(self):
        super(TestUserRoleSubscriptionChanges, self).setUp()
        self.domain = Domain(
            name="test-sub-changes",
            is_active=True,
        )
        self.domain.save()
        self.other_domain = Domain(
            name="other-domain",
            is_active=True,
        )
        self.other_domain.save()
        initialize_domain_with_default_roles(self.domain.name)
        self.user_roles = UserRole.objects.get_by_domain(self.domain.name)
        self.custom_role = UserRole.create(
            self.domain.name,
            "Custom Role",
            permissions=Permissions(
                edit_apps=True,
                view_apps=True,
                edit_web_users=True,
                view_web_users=True,
                view_roles=True,
            )
        )

        self.admin_username = generator.create_arbitrary_web_user_name()

        self.web_users = []
        self.commcare_users = []
        for role in [self.custom_role] + self.user_roles:
            web_user = WebUser.create(
                self.other_domain.name, generator.create_arbitrary_web_user_name(), 'test123', None, None
            )
            web_user.is_active = True
            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_username)[0]
        self.advanced_plan = DefaultProductPlan.get_default_plan_version(edition=SoftwarePlanEdition.ADVANCED)
Esempio n. 33
0
def prepare_domain(domain_name):
    from corehq.apps.commtrack.tests import bootstrap_domain
    domain = bootstrap_domain(domain_name)

    def _make_loc_type(name, administrative=False, parent_type=None):
        return LocationType.objects.get_or_create(
            domain=domain_name,
            name=name,
            administrative=administrative,
            parent_type=parent_type,
        )[0]

    country = _make_loc_type(name="country", administrative=True)
    _make_loc_type(name="Central Medical Store", parent_type=country)
    _make_loc_type(name="Teaching Hospital", parent_type=country)

    region = _make_loc_type(name="region",
                            administrative=True,
                            parent_type=country)
    _make_loc_type(name="Regional Medical Store", parent_type=region)
    _make_loc_type(name="Regional Hospital", parent_type=region)

    district = _make_loc_type(name="district",
                              administrative=True,
                              parent_type=region)
    _make_loc_type(name="Clinic", parent_type=district)
    _make_loc_type(name="District Hospital", parent_type=district)
    _make_loc_type(name="Health Centre", parent_type=district)
    _make_loc_type(name="CHPS Facility", parent_type=district)
    _make_loc_type(name="Hospital", parent_type=district)
    _make_loc_type(name="Psychiatric Hospital", parent_type=district)
    _make_loc_type(name="Polyclinic", parent_type=district)
    _make_loc_type(name="facility", parent_type=district)

    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)
    subscription = Subscription.new_domain_subscription(
        account, domain.name, plan)
    subscription.is_active = True
    subscription.save()
    ews_config = EWSGhanaConfig(enabled=True, domain=domain.name)
    ews_config.save()
    return domain
Esempio n. 34
0
    def setUp(self):
        super(TestDomainInvoiceFactory, self).setUp()
        self.invoice_start, self.invoice_end = get_previous_month_date_range()

        self.domain = generator.arbitrary_domain()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain=self.domain.name, created_by="TEST"
        )[0]
        self.community = DefaultProductPlan.get_default_plan_version()
        generator.arbitrary_commcare_users_for_domain(
            self.domain.name, self.community.user_limit + 1
        )

        self.invoice_factory = DomainInvoiceFactory(
            self.invoice_start, self.invoice_end, self.domain
        )
Esempio n. 35
0
def bootrap_domain_for_zapier(domain_name):
    domain_object = Domain.get_or_create_with_name(domain_name, is_active=True)

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

    web_user = WebUser.create(domain_name, 'test', '******', None, None)
    api_key_object, _ = HQApiKey.objects.get_or_create(
        user=web_user.get_django_user())
    return ZapierDomainConfig(domain_object, web_user, api_key_object.key)
    def setUp(self):
        super(TestSubscriptionPermissionsChanges, self).setUp()
        self.project = Domain(
            name="test-sub-changes",
            is_active=True,
        )
        self.project.save()

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

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.project.name, created_by=self.admin_user.username)[0]
        self.advanced_plan = DefaultProductPlan.get_default_plan(edition=SoftwarePlanEdition.ADVANCED)
        self._init_pro_with_rb_plan_and_version()
 def handle(self, *args, **kwargs):
     domain_names = args
     privileges = sorted(_privilege_to_response_function().keys())
     print(','.join(['Project Space'] + privileges + ['Lowest Plan']))
     for domain in filter(lambda domain: domain, map(Domain.get_by_name, domain_names)):
         is_privilege_being_used = {
             priv: _is_domain_using_privilege(domain, priv)
             for priv in privileges
         }
         using_privileges = [priv for (priv, is_in_use) in is_privilege_being_used.items() if is_in_use]
         minimum_plan = DefaultProductPlan.get_lowest_edition(using_privileges)
         print(','.join(
             [domain.name] +
             ['X' if is_privilege_being_used[priv] else '' for priv in privileges] +
             [minimum_plan]
         ))
    def setup_domain(cls, name):
        domain_obj = Domain(name=name,
                            sms_mobile_worker_registration_enabled=True)
        domain_obj.save()

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

        domain_obj = Domain.get(domain_obj.get_id)
        return (domain_obj, account, subscription)
    def setUpClass(cls):
        super(BaseCustomerInvoiceCase, cls).setUpClass()

        cls.billing_contact = generator.create_arbitrary_web_user_name()
        cls.dimagi_user = generator.create_arbitrary_web_user_name(
            is_dimagi=True)
        cls.account = generator.billing_account(cls.dimagi_user,
                                                cls.billing_contact)
        cls.domain = generator.arbitrary_domain()
        cls.account.is_customer_billing_account = True
        cls.account.save()

        cls.advanced_plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.ADVANCED)
        cls.advanced_plan.plan.is_customer_software_plan = True

        cls.subscription_length = 15  # months
        subscription_start_date = datetime.date(2016, 2, 23)
        subscription_end_date = add_months_to_date(subscription_start_date,
                                                   cls.subscription_length)
        cls.subscription = generator.generate_domain_subscription(
            cls.account,
            cls.domain,
            date_start=subscription_start_date,
            date_end=subscription_end_date,
        )
        cls.subscription.plan_version.plan.is_customer_software_plan = True

        advanced_subscription_end_date = add_months_to_date(
            subscription_end_date, 2)
        cls.domain2 = generator.arbitrary_domain()
        cls.sub2 = generator.generate_domain_subscription(
            cls.account,
            cls.domain2,
            date_start=subscription_start_date,
            date_end=advanced_subscription_end_date,
            plan_version=cls.advanced_plan)
        cls.sub2.plan_version.plan.is_customer_software_plan = True

        cls.domain3 = generator.arbitrary_domain()
        cls.sub3 = generator.generate_domain_subscription(
            cls.account,
            cls.domain3,
            date_start=subscription_start_date,
            date_end=advanced_subscription_end_date,
            plan_version=cls.advanced_plan)
        cls.sub3.plan_version.plan.is_customer_software_plan = True
Esempio n. 40
0
    def test_accounting_future_subscription_suppressed(self):
        self.current_subscription.date_end = self.current_subscription.date_start + relativedelta(
            days=5)
        self.current_subscription.save()
        next_subscription = Subscription.new_domain_subscription(
            self.current_subscription.account,
            self.domain.name,
            DefaultProductPlan.get_default_plan_version(
                edition=SoftwarePlanEdition.PRO),
            date_start=self.current_subscription.date_end,
        )

        self.domain.delete()

        self.assertTrue(
            Subscription.visible_and_suppressed_objects.get(
                id=next_subscription.id).is_hidden_to_ops)
    def setUpClass(cls):
        super(TestDomainsInLineItemForCustomerInvoicing, cls).setUpClass()

        cls.customer_account = generator.billing_account('*****@*****.**', '*****@*****.**')
        cls.customer_account.is_customer_billing_account = True
        cls.customer_account.save()

        cls.customer_plan_version = DefaultProductPlan.get_default_plan_version()
        cls.customer_plan_version.plan.is_customer_software_plan = True
        cls.customer_plan_version.plan.save()

        cls.mock_customer_invoice = Mock()
        cls.mock_customer_invoice.date_start = date(2019, 5, 1)
        cls.mock_customer_invoice.date_end = date(2019, 5, 31)

        cls.domain = Domain(name='test_domain')
        cls.domain.save()
Esempio n. 42
0
def prepare_domain(domain_name):
    from corehq.apps.commtrack.tests.util 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()
    account = BillingAccount.get_or_create_account_by_domain(
        domain.name,
        created_by="automated-test",
    )[0]
    plan = DefaultProductPlan.get_default_plan_version(
        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,
                                  all_stock_data=True)
    ils_config.save()
    fields_definition = CustomDataFieldsDefinition.get_or_create(
        domain.name, 'LocationFields')
    fields_definition.fields.append(
        CustomDataField(slug='group',
                        label='Group',
                        is_required=False,
                        choices=['A', 'B', 'C'],
                        is_multiple_choice=False))
    fields_definition.save()
    return domain
Esempio n. 43
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:
         logger.error(
             "[BILLING] "
             "Domain '%s' is going to get charged on "
             "Community, but they haven't formally acknowledged this. "
             "Someone on ops should reconcile this soon. To be on the "
             "safe side, we've marked the invoices as Do Not Invoice."
             % self.domain.name
         )
         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 InvoiceError("No Billing Contact Info could be found "
                            "for domain '%s'." % 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)
Esempio n. 44
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,
         entry_point=EntryPoint.SELF_STARTED,
     )[0]
     if account.date_confirmed_extra_charges is None:
         logger.info(
             "Did not generate invoice because date_confirmed_extra_charges "
             "was null for domain %s" % self.domain.name)
         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." % 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)
Esempio n. 45
0
 def setUpClass(cls):
     super(TestZapierCreateCaseAction, cls).setUpClass()
     cls.domain_object = Domain.get_or_create_with_name('fruit',
                                                        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.query_string = "?domain=fruit&case_type=watermelon&owner_id=test_user&user=test"
     cls.data = {'case_name': 'test1', 'price': '11'}
     cls.user = WebUser.create(cls.domain, 'test', '******', None, None)
     api_key_object, _ = HQApiKey.objects.get_or_create(
         user=cls.user.get_django_user())
     cls.api_key = api_key_object.key
Esempio n. 46
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()
        self.addCleanup(domain.delete)
        num_active = generator.create_excess_community_users(domain)

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

        calculate_users_in_all_domains(
            datetime.date(today.year, today.month, 1))
        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)
Esempio 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)
        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, _ = ApiKey.objects.get_or_create(user=WebUser.get_django_user(cls.user))
Esempio n. 48
0
def pause_current_subscription(domain_name, web_user, current_subscription):
    from corehq.apps.accounting.models import (
        Subscription,
        DefaultProductPlan,
        SoftwarePlanEdition,
        SubscriptionAdjustmentMethod,
        SubscriptionType,
        ProBonoStatus,
        FundingSource,
    )
    cancel_future_subscriptions(domain_name, datetime.date.today(), web_user)
    paused_plan_version = DefaultProductPlan.get_default_plan_version(
        SoftwarePlanEdition.PAUSED)
    if current_subscription.is_below_minimum_subscription:
        current_subscription.update_subscription(
            date_start=current_subscription.date_start,
            date_end=current_subscription.date_start +
            datetime.timedelta(days=30))
        return Subscription.new_domain_subscription(
            account=current_subscription.account,
            domain=domain_name,
            plan_version=paused_plan_version,
            date_start=current_subscription.date_start +
            datetime.timedelta(days=30),
            web_user=web_user,
            adjustment_method=SubscriptionAdjustmentMethod.USER,
            service_type=SubscriptionType.PRODUCT,
            pro_bono_status=ProBonoStatus.NO,
            funding_source=FundingSource.CLIENT,
            do_not_invoice=True,
            no_invoice_reason='Paused plan',
        )
    else:
        return current_subscription.change_plan(
            paused_plan_version,
            web_user=web_user,
            adjustment_method=SubscriptionAdjustmentMethod.USER,
            service_type=SubscriptionType.PRODUCT,
            pro_bono_status=ProBonoStatus.NO,
            do_not_invoice=True,
            no_invoice_reason='Paused plan',
        )
Esempio n. 49
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)
Esempio n. 50
0
    def setUp(self):
        super(BaseInvoiceTestCase, self).setUp()
        self.billing_contact = generator.arbitrary_web_user()
        self.dimagi_user = generator.arbitrary_web_user(is_dimagi=True)
        self.currency = generator.init_default_currency()
        self.account = generator.billing_account(
            self.dimagi_user, self.billing_contact)
        self.domain = generator.arbitrary_domain()

        self.subscription_length = 15  # months
        subscription_start_date = datetime.date(2016, 2, 23)
        subscription_end_date = add_months_to_date(subscription_start_date, self.subscription_length)
        self.subscription = generator.generate_domain_subscription(
            self.account,
            self.domain,
            date_start=subscription_start_date,
            date_end=subscription_end_date,
        )

        self.community_plan = DefaultProductPlan.get_default_plan_version()
Esempio n. 51
0
 def setUp(self):
     super(TestExportUtils, self).setUp()
     self.domain = Domain.get_or_create_with_name('test-export-utils',
                                                  is_active=True)
     self.user = WebUser.create(self.domain.name,
                                "export-settings-user",
                                "*******",
                                None,
                                None,
                                is_admin=True)
     self.account, _ = BillingAccount.get_or_create_account_by_domain(
         self.domain.name, created_by='*****@*****.**')
     self.account.save()
     subscription = Subscription.new_domain_subscription(
         self.account,
         self.domain.name,
         DefaultProductPlan.get_default_plan_version(
             edition=SoftwarePlanEdition.ENTERPRISE),
         date_start=date.today() - timedelta(days=3))
     subscription.is_active = True
     subscription.save()
Esempio n. 52
0
def create_30_day_trial(domain_obj):
    # Create a 30 Day Trial subscription to the Advanced Plan
    advanced_plan_version = DefaultProductPlan.get_default_plan_by_domain(
        domain_obj, edition=SoftwarePlanEdition.ADVANCED, is_trial=True)
    expiration_date = date.today() + timedelta(days=30)
    trial_account = BillingAccount.objects.get_or_create(
        name="Trial Account for %s" % domain_obj.name,
        currency=Currency.get_default(),
        created_by_domain=domain_obj.name,
        account_type=BillingAccountType.TRIAL,
    )[0]
    trial_subscription = Subscription.new_domain_subscription(
        trial_account,
        domain_obj.name,
        advanced_plan_version,
        date_end=expiration_date,
        adjustment_method=SubscriptionAdjustmentMethod.TRIAL,
        is_trial=True,
    )
    trial_subscription.is_active = True
    trial_subscription.save()
Esempio n. 53
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()
    def setUp(self):
        super(TestUserRoleSubscriptionChanges, self).setUp()
        self.domain = Domain(
            name="test-sub-changes",
            is_active=True,
        )
        self.domain.save()
        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(
            edition=SoftwarePlanEdition.ADVANCED)
Esempio n. 55
0
    def _ensure_full_coverage(self, subscriptions):
        plan_version = DefaultProductPlan.get_default_plan(
            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

        # 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.
        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__,
            entry_point=EntryPoint.SELF_STARTED,
        )[0]
        if account.date_confirmed_extra_charges is None:
            log_accounting_info(
                "Did not generate invoice because date_confirmed_extra_charges "
                "was null for domain %s" % self.domain.name)
            do_not_invoice = True

        for start_date, end_date 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=start_date,
                date_end=end_date,
                do_not_invoice=do_not_invoice,
            )
            community_subscription.save()
            subscriptions.append(community_subscription)
Esempio n. 56
0
def create_30_day_advanced_trial(domain_obj):
    # Create a 30 Day Trial subscription to the Advanced Plan
    advanced_plan_version = DefaultProductPlan.get_default_plan_version(
        edition=SoftwarePlanEdition.ADVANCED, is_trial=True)
    expiration_date = date.today() + timedelta(days=30)
    trial_account = BillingAccount.objects.get_or_create(
        name=DEFAULT_ACCOUNT_FORMAT % domain_obj.name,
        currency=Currency.get_default(),
        created_by_domain=domain_obj.name,
        account_type=BillingAccountType.USER_CREATED,
        pre_or_post_pay=PreOrPostPay.POSTPAY,
    )[0]
    trial_subscription = Subscription.new_domain_subscription(
        trial_account,
        domain_obj.name,
        advanced_plan_version,
        date_end=expiration_date,
        adjustment_method=SubscriptionAdjustmentMethod.TRIAL,
        is_trial=True,
        service_type=SubscriptionType.TRIAL)
    trial_subscription.is_active = True
    trial_subscription.save()
Esempio n. 57
0
    def test_date_due_not_set_small_invoice(self):
        """Date Due doesn't get set if the invoice is small"""
        Subscription.objects.all().delete()
        plan_version = DefaultProductPlan.get_default_plan_version(SoftwarePlanEdition.STANDARD)

        subscription_length = 5  # months
        subscription_start_date = datetime.date(2016, 2, 23)
        subscription_end_date = add_months_to_date(subscription_start_date, subscription_length)
        subscription = generator.generate_domain_subscription(
            self.account,
            self.domain,
            date_start=subscription_start_date,
            date_end=subscription_end_date,
            plan_version=plan_version,
        )

        invoice_date_small = utils.months_from_date(subscription.date_start, 1)
        tasks.generate_invoices(invoice_date_small)
        small_invoice = subscription.invoice_set.first()

        self.assertTrue(small_invoice.balance <= SMALL_INVOICE_THRESHOLD)
        self.assertIsNone(small_invoice.date_due)
Esempio n. 58
0
    def test_date_due_set_large_invoice(self):
        """Date Due only gets set for a large invoice (> $100)"""
        Subscription.objects.all().delete()
        plan_version = DefaultProductPlan.get_default_plan_version(SoftwarePlanEdition.ADVANCED)

        subscription_length = 5  # months
        subscription_start_date = datetime.date(2016, 2, 23)
        subscription_end_date = add_months_to_date(subscription_start_date, subscription_length)
        subscription = generator.generate_domain_subscription(
            self.account,
            self.domain,
            date_start=subscription_start_date,
            date_end=subscription_end_date,
            plan_version=plan_version
        )

        invoice_date_large = utils.months_from_date(subscription.date_start, 3)
        tasks.generate_invoices(invoice_date_large)
        large_invoice = subscription.invoice_set.last()

        self.assertTrue(large_invoice.balance > SMALL_INVOICE_THRESHOLD)
        self.assertIsNotNone(large_invoice.date_due)
Esempio n. 59
0
        def wrapped(request, *args, **kwargs):
            try:
                if (hasattr(request, 'subscription')
                        and request.subscription is not None and
                    (request.subscription.is_trial
                     or request.subscription.plan_version.plan.visibility
                     == SoftwarePlanVisibility.TRIAL_INTERNAL)
                        and request.subscription.date_end is not None):
                    edition_req = DefaultProductPlan.get_lowest_edition_by_domain(
                        request.domain, [slug])
                    plan_name = request.subscription.plan_version.user_facing_description[
                        'name']
                    feature_name = privileges.Titles.get_name_from_privilege(
                        slug)
                    request.show_trial_notice = True
                    request.trial_info = {
                        'current_plan':
                        plan_name,
                        'feature_name':
                        feature_name,
                        'required_plan':
                        edition_req,
                        'date_end':
                        request.subscription.date_end.strftime(
                            USER_DATE_FORMAT)
                    }
                    request.is_domain_admin = (
                        hasattr(request, 'couch_user')
                        and request.couch_user.is_domain_admin(request.domain))

                return requires_privilege(slug,
                                          **assignment)(fn)(request, *args,
                                                            **kwargs)
            except PermissionDenied:
                request.show_trial_notice = False
                from corehq.apps.domain.views import SubscriptionUpgradeRequiredView
                return SubscriptionUpgradeRequiredView().get(
                    request, request.domain, slug)
    def response_mobile_worker_creation(domain, new_plan_version):
        """ Deactivates users if there are too many for a community plan """
        from corehq.apps.accounting.models import (DefaultProductPlan,
                                                   FeatureType,
                                                   UNLIMITED_FEATURE_USAGE)

        # checks for community plan
        if (new_plan_version != DefaultProductPlan.get_default_plan_version()):
            return True

        # checks if unlimited is on for this user
        user_rate = new_plan_version.feature_rates.filter(
            feature__feature_type=FeatureType.USER).latest('date_created')
        if user_rate.monthly_limit == UNLIMITED_FEATURE_USAGE:
            return True

        # checks for extra users
        num_users = CommCareUser.total_by_domain(domain.name, is_active=True)
        num_allowed = user_rate.monthly_limit
        if num_users > num_allowed:
            # offloads deactivation onto a separate thread
            bulk_deactivate_users.delay(domain)
        return True