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
        )
        product = SoftwareProduct.objects.get(name='CommCare Pro', product_type=SoftwareProductType.COMMCARE)
        rate = product.get_rate()
        rate.save()
        self.pro_rb_version.product_rate = rate
        self.pro_rb_version.save()
    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
        )
        product = SoftwareProduct.objects.get(name='CommCare Pro', product_type=SoftwareProductType.COMMCARE)
        rate = product.get_rate()
        rate.save()
        self.pro_rb_version.product_rate = rate
        self.pro_rb_version.save()
示例#3
0
def _get_or_create_new_software_plan(from_plan, dry_run=False):
    """
    :param from_plan: plan to copy attributes from
    :param dry_run: if True, will not make changes to the db
    :return: newly created SoftwarePlan
    """
    dry_run_tag = '[DRY_RUN]' if dry_run else ''
    new_name = from_plan.name + NEW_NAME_SUFFIX
    try:
        plan = SoftwarePlan.objects.get(name=new_name)
    except SoftwarePlan.DoesNotExist:
        plan = SoftwarePlan(
            name=new_name,
            description=from_plan.description,
            edition=from_plan.edition,
            visibility=from_plan.visibility,
            is_customer_software_plan=from_plan.is_customer_software_plan,
            max_domains=from_plan.max_domains,
            is_annual_plan=from_plan.is_annual_plan,
        )
        logger.info(
            f"{dry_run_tag}Created new software plan {plan.name} from existing plan {from_plan.name}."
        )
    else:
        logger.info(f"{dry_run_tag}Found existing software plan {plan.name}.")

    if not dry_run:
        plan.save()

    return plan
    def test_changes_inactive_versions(self):
        plan = SoftwarePlan(name='Test Plan')
        plan.save()
        inactive_version = SoftwarePlanVersion(
            role=self.old_role,
            plan=plan,
            product_rate=self.generic_product_rate,
            is_active=False,
        )
        inactive_version.save()
        self.assertEqual(inactive_version.version, 1)

        active_role = Role.objects.create(slug='active_role', name='active')
        active_version = SoftwarePlanVersion(
            role=active_role,
            plan=plan,
            product_rate=self.generic_product_rate)
        active_version.save()

        change_role_for_software_plan_version('old_role', 'new_role')

        # refetch
        plan = SoftwarePlan.objects.get(name='Test Plan')
        # ensure software plan's active version is still the active role
        self.assertEqual(plan.get_version().role.slug, 'active_role')
        inactive_version = plan.softwareplanversion_set.filter(
            is_active=False).latest('date_created')
        # ensure the inactive plan version was updated to the new role
        self.assertEqual(inactive_version.role.slug, 'new_role')
    def test_limit_to_plan_version_id(self):
        plan_to_update = SoftwarePlan(name='Plan To Update')
        plan_to_update.save()
        version_to_update = SoftwarePlanVersion(
            role=self.old_role,
            plan=plan_to_update,
            product_rate=self.generic_product_rate)
        version_to_update.save()

        plan_to_ignore = SoftwarePlan(name='Plan To Ignore')
        plan_to_ignore.save()
        version_to_ignore = SoftwarePlanVersion(
            role=self.old_role,
            plan=plan_to_ignore,
            product_rate=self.generic_product_rate)
        version_to_ignore.save()

        change_role_for_software_plan_version(
            'old_role',
            'new_role',
            limit_to_plan_version_id=version_to_update.id)

        # refetch
        plan_to_update = SoftwarePlan.objects.get(name='Plan To Update')
        plan_to_ignore = SoftwarePlan.objects.get(name='Plan To Ignore')
        self.assertEqual(plan_to_update.get_version().role.slug, 'new_role')
        self.assertEqual(plan_to_ignore.get_version().role.slug, 'old_role')
示例#6
0
 def create_plan(self):
     name = self.cleaned_data["name"]
     description = self.cleaned_data["description"]
     edition = self.cleaned_data["edition"]
     visibility = self.cleaned_data["visibility"]
     plan = SoftwarePlan(name=name, description=description, edition=edition, visibility=visibility)
     plan.save()
     return plan
示例#7
0
 def create_plan(self):
     name = self.cleaned_data['name']
     description = self.cleaned_data['description']
     edition = self.cleaned_data['edition']
     visibility = self.cleaned_data['visibility']
     plan = SoftwarePlan(name=name,
                         description=description,
                         edition=edition,
                         visibility=visibility)
     plan.save()
     return plan
    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))
    def test_dry_run(self):
        plan = SoftwarePlan(name='Test Plan')
        plan.save()
        version = SoftwarePlanVersion(role=self.old_role,
                                      plan=plan,
                                      product_rate=self.generic_product_rate)
        version.save()

        change_role_for_software_plan_version('old_role',
                                              'new_role',
                                              dry_run=True)

        # refetch
        plan = SoftwarePlan.objects.get(name='Test Plan')
        self.assertEqual(plan.get_version().role.slug, 'old_role')
    def test_raises_exception_if_plan_version_id_does_not_reference_old_role(
            self):
        plan = SoftwarePlan(name='Test Plan 1')
        plan.save()
        version = SoftwarePlanVersion(role=self.old_role,
                                      plan=plan,
                                      product_rate=self.generic_product_rate)
        version.save()
        Role.objects.create(slug='mismatch_role', name='mismatch')

        with self.assertRaises(PlanVersionAndRoleMismatch):
            change_role_for_software_plan_version(
                'mismatch_role',
                'new_role',
                limit_to_plan_version_id=version.id)
    def test_changes_active_versions(self):
        plan = SoftwarePlan(name='Test Plan')
        plan.save()
        active_version = SoftwarePlanVersion(
            role=self.old_role,
            plan=plan,
            product_rate=self.generic_product_rate,
            is_active=True)
        active_version.save()
        self.assertEqual(active_version.version, 1)

        change_role_for_software_plan_version('old_role', 'new_role')

        # refetch
        plan = SoftwarePlan.objects.get(name='Test Plan')
        self.assertEqual(plan.get_version().version, 1)
        self.assertEqual(plan.get_version().role.slug, 'new_role')
示例#12
0
    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:
                    logger.info("Could not find the role '%s'. Did you forget to run cchq_prbac_bootstrap?")
                    logger.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:
                    logger.info("[DRY RUN] Creating Software Plan: %s" % software_plan.name)
                else:
                    try:
                        software_plan = SoftwarePlan.objects.get(name=software_plan.name)
                        if self.verbose:
                            logger.info("Plan '%s' already exists. Using existing plan to add version."
                                        % software_plan.name)
                    except SoftwarePlan.DoesNotExist:
                        software_plan.save()
                        if self.verbose:
                            logger.info("Creating Software Plan: %s" % software_plan.name)

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

                if edition == SoftwarePlanEdition.ADVANCED:
                    trials = [True, False]
                else:
                    trials = [False]
                for is_trial in trials:
                    default_product_plan = DefaultProductPlan(product_type=product.product_type, edition=edition, is_trial=is_trial)
                    if dry_run:
                        logger.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, is_trial=is_trial)
                            if self.verbose:
                                logger.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()
                            if self.verbose:
                                logger.info("Setting plan as default for product '%s' and edition '%s'." %
                                            (product.product_type,
                                             default_product_plan.edition))
示例#13
0
def ensure_plans(config, verbose, apps):
    DefaultProductPlan = apps.get_model('accounting', 'DefaultProductPlan')
    SoftwarePlan = apps.get_model('accounting', 'SoftwarePlan')
    SoftwarePlanVersion = apps.get_model('accounting', 'SoftwarePlanVersion')
    Role = apps.get_model('django_prbac', 'Role')

    for plan_key, plan_deets in config.items():
        edition, is_trial, is_report_builder_enabled = plan_key
        features = _ensure_features(edition, verbose, apps)
        try:
            role = _ensure_role(plan_deets['role'], apps)
        except Role.DoesNotExist:
            return

        product, product_rate = _ensure_product_rate(
            plan_deets['product_rate_monthly_fee'],
            edition,
            verbose=verbose,
            apps=apps,
        )
        feature_rates = _ensure_feature_rates(
            plan_deets['feature_rates'],
            features,
            edition,
            verbose=verbose,
            apps=apps,
        )

        software_plan = SoftwarePlan(
            name=((('%s Trial' % product_rate.name) if is_trial else
                   ('%s Edition' % product_rate.name)) if product is None else
                  product.name  # TODO - remove after squashing migrations
                  ),
            edition=edition,
            visibility=SoftwarePlanVisibility.PUBLIC)
        if is_report_builder_enabled:
            software_plan.name = '%s - Report Builder (5 Reports)' % software_plan.name

        try:
            software_plan = SoftwarePlan.objects.get(name=software_plan.name)
            if verbose:
                log_accounting_info(
                    "Plan '%s' already exists. Using existing plan to add version."
                    % software_plan.name)
        except SoftwarePlan.DoesNotExist:
            software_plan.save()
            if verbose:
                log_accounting_info("Creating Software Plan: %s" %
                                    software_plan.name)

        product_rate.save()
        software_plan_version = SoftwarePlanVersion(role=role,
                                                    plan=software_plan,
                                                    product_rate=product_rate)
        software_plan_version.save()

        for feature_rate in feature_rates:
            feature_rate.save()
            software_plan_version.feature_rates.add(feature_rate)
        software_plan_version.save()

        try:
            default_product_plan = DefaultProductPlan.objects.get(
                edition=edition,
                is_trial=is_trial,
                is_report_builder_enabled=is_report_builder_enabled,
            )
            if verbose:
                log_accounting_info(
                    "Default for edition '%s' with is_trial='%s' already exists."
                    % (default_product_plan.edition, is_trial))
        except DefaultProductPlan.DoesNotExist:
            default_product_plan = DefaultProductPlan(
                edition=edition,
                is_trial=is_trial,
                is_report_builder_enabled=is_report_builder_enabled,
            )
        finally:
            default_product_plan.plan = software_plan
            default_product_plan.save()
            if verbose:
                log_accounting_info(
                    "Setting plan as default for edition '%s' with is_trial='%s'."
                    % (default_product_plan.edition, is_trial))

    _clear_cache(SoftwarePlan.objects.all())
示例#14
0
def ensure_plans(config, verbose, apps):
    DefaultProductPlan = apps.get_model('accounting', 'DefaultProductPlan')
    SoftwarePlan = apps.get_model('accounting', 'SoftwarePlan')
    SoftwarePlanVersion = apps.get_model('accounting', 'SoftwarePlanVersion')
    Role = apps.get_model('django_prbac', 'Role')

    for plan_key, plan_deets in six.iteritems(config):
        edition, is_trial, is_report_builder_enabled = plan_key
        features = _ensure_features(edition, verbose, apps)
        try:
            role = _ensure_role(plan_deets['role'], apps)
        except Role.DoesNotExist:
            return

        product, product_rate = _ensure_product_rate(
            plan_deets['product_rate_monthly_fee'], edition,
            verbose=verbose, apps=apps,
        )
        feature_rates = _ensure_feature_rates(
            plan_deets['feature_rates'], features, edition,
            verbose=verbose, apps=apps,
        )

        software_plan = SoftwarePlan(
            name=(
                (('%s Trial' % product_rate.name) if is_trial else ('%s Edition' % product_rate.name))
                if product is None else product.name  # TODO - remove after squashing migrations
            ),
            edition=edition,
            visibility=SoftwarePlanVisibility.PUBLIC
        )
        if is_report_builder_enabled:
            software_plan.name = '%s - Report Builder (5 Reports)' % software_plan.name

        try:
            software_plan = SoftwarePlan.objects.get(name=software_plan.name)
            if verbose:
                log_accounting_info(
                    "Plan '%s' already exists. Using existing plan to add version." % software_plan.name
                )
        except SoftwarePlan.DoesNotExist:
            software_plan.save()
            if verbose:
                log_accounting_info("Creating Software Plan: %s" % software_plan.name)

        product_rate.save()
        software_plan_version = SoftwarePlanVersion(role=role, plan=software_plan, product_rate=product_rate)
        software_plan_version.save()

        for feature_rate in feature_rates:
            feature_rate.save()
            software_plan_version.feature_rates.add(feature_rate)
        software_plan_version.save()

        try:
            default_product_plan = DefaultProductPlan.objects.get(
                edition=edition,
                is_trial=is_trial,
                is_report_builder_enabled=is_report_builder_enabled,
            )
            if verbose:
                log_accounting_info(
                    "Default for edition '%s' with is_trial='%s' already exists."
                    % (default_product_plan.edition, is_trial)
                )
        except DefaultProductPlan.DoesNotExist:
            default_product_plan = DefaultProductPlan(
                edition=edition,
                is_trial=is_trial,
                is_report_builder_enabled=is_report_builder_enabled,
            )
        finally:
            default_product_plan.plan = software_plan
            default_product_plan.save()
            if verbose:
                log_accounting_info(
                    "Setting plan as default for edition '%s' with is_trial='%s'."
                    % (default_product_plan.edition, is_trial)
                )

    _clear_cache(SoftwarePlan.objects.all())