def handle(self, **options):
        dry_run = options['check']

        # 1. Find domains with locations
        domains_having_locations = (
            SQLLocation.objects.order_by('domain').distinct('domain')
            .values_list('domain', flat=True)
        )
        print("Domain having locations(%s): %s" % (len(domains_having_locations), domains_having_locations))
        # 2. Find domains on flat fixture
        domain_with_flat_fixture_enabled = find_domains_with_flat_fixture_enabled()
        print("Domain with flat fixture enabled(%s): %s" % (len(domain_with_flat_fixture_enabled),
                                                            domain_with_flat_fixture_enabled))

        # 3. Find domains to stay on legacy fixture
        domains_to_stay_on_hierarchical_fixture = (set(domains_having_locations) -
                                                   set(domain_with_flat_fixture_enabled))
        print("Domain to stay on hierarchical fixture(%s): %s" % (len(domains_to_stay_on_hierarchical_fixture),
                                                                  domains_to_stay_on_hierarchical_fixture))

        # 4. Update domains that need to stay on hierarchical with enabled legacy toggle to be able to access conf
        # and update their location configuration to use hierarchical fixture for now
        for domain in domains_to_stay_on_hierarchical_fixture:
            if not dry_run:
                print(u"Setting HIERARCHICAL_LOCATION_FIXTURE toggle for domain: %s" % domain)
                HIERARCHICAL_LOCATION_FIXTURE.set(domain, True, NAMESPACE_DOMAIN)
            else:
                print(u"HIERARCHICAL_LOCATION_FIXTURE toggle would be set for domain: %s" % domain)

            if not dry_run:
                print(u"Enabling legacy fixture for domain: %s" % domain)
                location_configuration = LocationFixtureConfiguration.for_domain(domain)
                print("Current Configuration, Persisted: %s, Use Flat fixture: %s, Use Hierarchical fixture %s" % (
                    not location_configuration._state.adding, location_configuration.sync_hierarchical_fixture,
                    location_configuration.sync_flat_fixture))

                enable_legacy_fixture_for_domain(domain)
            else:
                print(u"Legacy fixture to be enabled for domain: %s" % domain)
                location_configuration = LocationFixtureConfiguration.for_domain(domain)
                print("Current Configuration, Persisted: %s, Use Flat fixture: %s, Use Hierarchical fixture %s" % (
                    not location_configuration._state.adding, location_configuration.sync_hierarchical_fixture,
                    location_configuration.sync_flat_fixture))

        # 5. Domains that need to stay on flat fixture need not worry about any change since they would
        # default to flat fixture but must ensure if they don't have conf set for using hierarchical fixture
        for domain in domain_with_flat_fixture_enabled:
            # For domains with flat fixture enabled and have configuration defined to use hierarchical fixture
            # Notify them to make their state clear
            location_conf_for_domain = LocationFixtureConfiguration.for_domain(domain)
            if not location_conf_for_domain._state.adding and location_conf_for_domain.sync_hierarchical_fixture:
                # Can use the following to update them
                # location_conf_for_domain.sync_flat_fixture = True
                # location_conf_for_domain.sync_hierarchical_fixture = False
                # location_conf_for_domain.save()
                print("Domain that needs attention since its not in a definite state: %s" % domain)
Beispiel #2
0
    def copy_locations(self, types_only=False):
        from corehq.apps.locations.models import LocationType, SQLLocation
        from corehq.apps.locations.views import LocationFieldsView

        self._copy_custom_data(LocationFieldsView.field_type)

        location_types = LocationType.objects.by_domain(self.existing_domain)
        location_types_map = {}
        for location_type in location_types:
            if location_type.parent_type_id:
                location_type.parent_type_id = location_types_map[location_type.parent_type_id]
            old_id, new_id = self.save_sql_copy(location_type, self.new_domain)
            location_types_map[old_id] = new_id

        if not types_only:
            # MPTT sorts this queryset so we can just save in the same order
            new_loc_pks_by_code = {}
            for loc in SQLLocation.active_objects.filter(domain=self.existing_domain):
                # start with a new location so we don't inadvertently copy over a bunch of foreign keys
                new_loc = SQLLocation()
                for field in ["name", "site_code", "external_id", "metadata",
                              "is_archived", "latitude", "longitude"]:
                    setattr(new_loc, field, getattr(loc, field, None))
                new_loc.domain = self.new_domain
                new_loc.parent_id = new_loc_pks_by_code[loc.parent.site_code] if loc.parent_id else None
                new_loc.location_type_id = location_types_map[loc.location_type_id]
                _, new_pk = self.save_sql_copy(new_loc, self.new_domain)
                new_loc_pks_by_code[new_loc.site_code] = new_pk

            existing_fixture_config = LocationFixtureConfiguration.for_domain(self.existing_domain)
            self.save_sql_copy(existing_fixture_config, self.new_domain)
Beispiel #3
0
def should_sync_flat_fixture(project):
    # Sync flat fixture for domains with conf for flat fixture enabled
    # This does not check for toggle for migration to allow domains those domains to migrate to flat fixture
    return (
        project.uses_locations and
        LocationFixtureConfiguration.for_domain(project.name).sync_flat_fixture
    )
Beispiel #4
0
    def copy_locations(self, types_only=False):
        from corehq.apps.locations.models import LocationType, SQLLocation
        from corehq.apps.locations.views import LocationFieldsView

        self._copy_custom_data(LocationFieldsView.field_type)

        location_types = LocationType.objects.by_domain(self.existing_domain)
        location_types_map = {}
        for location_type in location_types:
            if location_type.parent_type_id:
                location_type.parent_type_id = location_types_map[location_type.parent_type_id]
            old_id, new_id = self.save_sql_copy(location_type, self.new_domain)
            location_types_map[old_id] = new_id

        if not types_only:
            # use get_descendants, which sorts locations hierarchically,
            # so we can save in the same order
            locs = SQLLocation.objects.get_queryset_descendants(
                Q(domain=self.existing_domain, parent_id__isnull=True)
            ).filter(is_archived=False)
            new_loc_pks_by_code = {}
            for loc in locs:
                # start with a new location so we don't inadvertently copy over a bunch of foreign keys
                new_loc = SQLLocation()
                for field in ["name", "site_code", "external_id", "metadata",
                              "is_archived", "latitude", "longitude"]:
                    setattr(new_loc, field, getattr(loc, field, None))
                new_loc.domain = self.new_domain
                new_loc.parent_id = new_loc_pks_by_code[loc.parent.site_code] if loc.parent_id else None
                new_loc.location_type_id = location_types_map[loc.location_type_id]
                _, new_pk = self.save_sql_copy(new_loc, self.new_domain)
                new_loc_pks_by_code[new_loc.site_code] = new_pk

            existing_fixture_config = LocationFixtureConfiguration.for_domain(self.existing_domain)
            self.save_sql_copy(existing_fixture_config, self.new_domain)
Beispiel #5
0
def should_sync_hierarchical_fixture(project):
    # Sync hierarchical fixture for domains with fixture toggle enabled for migration and
    # configuration set to use hierarchical fixture
    # Even if both fixtures are set up, this one takes priority for domains with toggle enabled
    return (project.uses_locations
            and toggles.HIERARCHICAL_LOCATION_FIXTURE.enabled(project.name)
            and LocationFixtureConfiguration.for_domain(
                project.name).sync_hierarchical_fixture)
Beispiel #6
0
    def post(self, request, *args, **kwargs):
        location_settings = LocationFixtureConfiguration.for_domain(self.domain)
        form = LocationFixtureForm(request.POST, instance=location_settings)
        if form.is_valid():
            form.save()
            messages.success(request, _("Location configuration updated successfully"))

        return self.get(request, *args, **kwargs)
Beispiel #7
0
def location_fixture_instances(domain, instance_name):
    from corehq.apps.locations.models import LocationFixtureConfiguration
    if (toggles.HIERARCHICAL_LOCATION_FIXTURE.enabled(domain)
            and not LocationFixtureConfiguration.for_domain(
                domain).sync_flat_fixture):
        return Instance(id=instance_name,
                        src='jr://fixture/commtrack:{}'.format(instance_name))
    return Instance(id=instance_name,
                    src='jr://fixture/{}'.format(instance_name))
Beispiel #8
0
def should_sync_flat_fixture(project, app):
    if not project.uses_locations:
        return False

    if app and app.location_fixture_restore in SYNC_FLAT_FIXTURES:
        return True

    if app and app.location_fixture_restore != DEFAULT_LOCATION_FIXTURE_OPTION:
        return False

    return LocationFixtureConfiguration.for_domain(project.name).sync_flat_fixture
Beispiel #9
0
def should_sync_flat_fixture(project, app):
    if not project.uses_locations:
        return False

    if app and app.location_fixture_restore in SYNC_FLAT_FIXTURES:
        return True

    if app and app.location_fixture_restore != DEFAULT_LOCATION_FIXTURE_OPTION:
        return False

    return LocationFixtureConfiguration.for_domain(project.name).sync_flat_fixture
Beispiel #10
0
def should_sync_hierarchical_fixture(project, app):
    if (not project.uses_locations
            or not toggles.HIERARCHICAL_LOCATION_FIXTURE.enabled(project.name)):
        return False

    if app and app.location_fixture_restore in SYNC_HIERARCHICAL_FIXTURE:
        return True

    if app and app.location_fixture_restore != DEFAULT_LOCATION_FIXTURE_OPTION:
        return False

    return LocationFixtureConfiguration.for_domain(project.name).sync_hierarchical_fixture
Beispiel #11
0
def should_sync_hierarchical_fixture(project, app):
    if (not project.uses_locations
            or not toggles.HIERARCHICAL_LOCATION_FIXTURE.enabled(project.name)):
        return False

    if app and app.location_fixture_restore in SYNC_HIERARCHICAL_FIXTURE:
        return True

    if app and app.location_fixture_restore != DEFAULT_LOCATION_FIXTURE_OPTION:
        return False

    return LocationFixtureConfiguration.for_domain(project.name).sync_hierarchical_fixture
Beispiel #12
0
def should_sync_flat_fixture(domain):
    return (
        toggles.FLAT_LOCATION_FIXTURE.enabled(domain) and
        LocationFixtureConfiguration.for_domain(domain).sync_flat_fixture
    )
Beispiel #13
0
 def page_context(self):
     location_settings = LocationFixtureConfiguration.for_domain(
         self.domain)
     form = LocationFixtureForm(instance=location_settings)
     return {'form': form}
Beispiel #14
0
def location_fixture_instances(domain, instance_name):
    from corehq.apps.locations.models import LocationFixtureConfiguration
    if (toggles.HIERARCHICAL_LOCATION_FIXTURE.enabled(domain)
            and not LocationFixtureConfiguration.for_domain(domain).sync_flat_fixture):
        return Instance(id=instance_name, src='jr://fixture/commtrack:{}'.format(instance_name))
    return Instance(id=instance_name, src='jr://fixture/{}'.format(instance_name))
def enable_legacy_fixture_for_domain(domain):
    location_configuration = LocationFixtureConfiguration.for_domain(domain)
    location_configuration.sync_hierarchical_fixture = True
    location_configuration.sync_flat_fixture = False
    location_configuration.save()
Beispiel #16
0
def should_sync_hierarchical_fixture(project):
    return (project.uses_locations and LocationFixtureConfiguration.for_domain(
        project.name).sync_hierarchical_fixture)
Beispiel #17
0
def should_sync_flat_fixture(domain):
    return (toggles.FLAT_LOCATION_FIXTURE.enabled(domain) and
            LocationFixtureConfiguration.for_domain(domain).sync_flat_fixture)
Beispiel #18
0
def should_sync_hierarchical_fixture(project):
    return (
        project.uses_locations and
        LocationFixtureConfiguration.for_domain(project.name).sync_hierarchical_fixture
    )