Last active
April 23, 2026 11:59
-
-
Save hbruno/78443416ae0f25ca24685ab5bfd0812c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| """ | |
| Script to update all filters that are supported by VOICE. | |
| For a filter to be supported by VOICE: | |
| 1. The filter's field_name must exist in the FeedbackRequest model within the respondent_mapped_fields or subject_mapped_fields JSON fields. | |
| 2. Consider the specific filters for each organization (org_id). | |
| 3. Consider the filter's entity field. | |
| 4. Consider available_modules (must include FilterModule.VOICE or be None). | |
| """ | |
| import warnings | |
| from sqlalchemy.exc import SAWarning | |
| warnings.filterwarnings('ignore', category=SAWarning, message='.*relationship.*will copy column.*') | |
| from sqlalchemy import or_, select | |
| from libs.db import db | |
| from libs.crosschq_importer.models import ImportType | |
| from libs.filters.models import Filter, FilterModule | |
| from libs.orgs.models import Organization | |
| from libs.survey_answers_analytics.helpers import FILTER_MAPPING_VOICE | |
| from libs.survey_answers_analytics.models import FeedbackRequest, FeedbackSettings | |
| def get_last_object(entity: str, org_id: str | None) -> FeedbackRequest: | |
| """Get the last object of the given entity""" | |
| print("\tget_last_object") | |
| feedback_query = ( | |
| select(FeedbackRequest) | |
| .join(FeedbackSettings, FeedbackRequest.feedback_settings_id == FeedbackSettings.id) | |
| .where(FeedbackRequest.subject_type == entity) | |
| .where(FeedbackSettings.feedback_origin == 'voice') | |
| .order_by(FeedbackRequest.created_on.desc()) | |
| .limit(1) | |
| ) | |
| if org_id: | |
| feedback_query = feedback_query.where(FeedbackRequest.org_id == org_id) | |
| result = db.session.execute(feedback_query) | |
| return result.scalars().first() | |
| def get_filters_for_org(entity: str, org_id: str | None) -> list[Filter]: | |
| print(f"\tget_filters_for_org {entity}, {org_id}") | |
| filters_query = select(Filter).where(Filter.is_active.is_(True), Filter.entity == entity, or_(Filter.is_deleted.is_(False), Filter.is_deleted.is_(None))) | |
| if org_id: | |
| filters_query = filters_query.where(Filter.org_id == org_id) | |
| else: | |
| filters_query = filters_query.where(Filter.org_id.is_(None)) | |
| result = db.session.execute(filters_query) | |
| return list(result.scalars().all()) | |
| def is_filter_supported_by_voice(filter_item: Filter, sample_object: FeedbackRequest) -> bool: | |
| if filter_item.field_name in FILTER_MAPPING_VOICE: | |
| return True | |
| subject_fields = sample_object.subject_mapped_fields or {} | |
| respondent_fields = sample_object.respondent_mapped_fields or {} | |
| return filter_item.field_name in subject_fields or filter_item.field_name in respondent_fields | |
| def update_filter_available_modules(filter_item: Filter, is_supported: bool) -> bool: | |
| print("\tupdate_filter_available_modules") | |
| current_modules = filter_item.available_modules or [] | |
| has_voice = FilterModule.VOICE in current_modules | |
| modified = False | |
| if is_supported and not has_voice: | |
| if current_modules: | |
| filter_item.available_modules = list(current_modules) + [FilterModule.VOICE] | |
| else: | |
| pass | |
| modified = True | |
| elif not is_supported and has_voice: | |
| new_modules = [m for m in current_modules if m != FilterModule.VOICE] | |
| filter_item.available_modules = new_modules if new_modules else None | |
| modified = True | |
| elif not is_supported and not current_modules: | |
| all_modules_except_voice = [m for m in FilterModule if m != FilterModule.VOICE] | |
| filter_item.available_modules = all_modules_except_voice | |
| modified = True | |
| return modified | |
| def check_filter_by_entity(entity: str, org_id: str | None): | |
| print("\tcheck_filter_by_entity") | |
| sample_object = get_last_object(entity, org_id) | |
| if not sample_object: | |
| print(f"\t\tNo sample object found for entity {entity} and org_id {org_id}") | |
| return | |
| filters = get_filters_for_org(entity, org_id) | |
| modified_count = 0 | |
| for filter_item in filters: | |
| is_supported = is_filter_supported_by_voice(filter_item, sample_object) | |
| if update_filter_available_modules(filter_item, is_supported): | |
| modified_count += 1 | |
| print("\tUpdated filter %s (codename=%s): VOICE supported=%s", filter_item.id, filter_item.codename, is_supported) | |
| if modified_count > 0: | |
| db.session.commit() | |
| def get_orgs_with_voice() -> list[str]: | |
| return Organization.objects(is_voice_enable=True).values_list('org_id') | |
| def count_filters_with_modules(): | |
| from sqlalchemy import TEXT, VARCHAR, Boolean, Column, Enum, ForeignKey, desc, func, or_, select, sql, text | |
| filter_count = select(func.count()).select_from(Filter).where(Filter.is_active.is_(True), Filter.available_modules.isnot(None)) | |
| res = db.session.execute(filter_count) | |
| return res.scalar() | |
| def main(): | |
| all_orgs = [None] + list(get_orgs_with_voice()) | |
| all_orgs = [ | |
| None, | |
| "68024e2a-7a5c-4847-b4fa-f69ced866094", | |
| "46c35c85-2469-4de9-bf2b-6553899ed348", | |
| "3119feab-d369-4435-91fa-1d081f85ec39", | |
| "21e8d75e-cfe0-4634-a1b7-c4c3dbd76dd3", | |
| "b877fc16-afac-4ce9-8290-c8fbbf3a29bb", | |
| "91600e74-01d8-4c1a-8439-37d5657655ea", | |
| "c1030490-c58e-47b3-89b9-a159e617aeb5", | |
| "daa62f8b-85de-4dd3-b578-8767fe918dd1", | |
| "f623ef10-24fb-4e60-a2de-1b54dc8db2c9", | |
| "a82f026d-ad20-437f-b1c8-b0f0159f6cb5", | |
| "59b0a5af-adf4-46be-86b4-10e7220543c5", | |
| "5af71862-5928-42f0-8b7b-b674efc09221", | |
| "2b6cf6d2-4b00-448e-977a-641b2a6df34b", | |
| "90dd6811-83c5-420e-856e-9b1046165d1f", | |
| "f5d72bd4-4f78-49e7-a97c-f64e31d4e797", | |
| "1ec7c5e7-c87a-4aea-98f2-6292f3be8fee", | |
| "5186f003-fd95-4f72-a8df-d9494d10c5d4", | |
| "c309dc81-7508-4306-8f85-0e4b633db204", | |
| "a713b5ac-ee86-4328-b37f-3fd878d1a873", | |
| "4be56648-e938-4521-861a-d2cda2e51942", | |
| "220a7c7a-575e-4dd2-82d0-6c175eb46ca8", | |
| "cc527f96-2515-46c8-adba-fcf3f722645c", | |
| "a85a4644-dea5-49dc-9006-191ea686fa04", | |
| "6fe12dda-b185-405a-9fbc-ca0d42f5920e", | |
| "32b7431e-961b-45d3-82d4-c877dbd02e5a", | |
| "826f2aaa-69bc-42da-8496-6a3d2aa6781d", | |
| "1ee2ed33-b498-4caa-9dd9-f2189b3e238c", | |
| "bbb7eb45-f7e2-480d-8900-1cd8a9b47417", | |
| "81b50461-0d5b-487d-9e67-3c529923c598", | |
| "a0645a08-e0d7-40bc-ba64-75ddb6e38452", | |
| "3f5e5ef8-3dc8-4b93-b7a7-2761e7a5892a", | |
| "3b8bbd67-b2d8-46b6-8b20-1d5be70bc432", | |
| "f7843e1b-11a7-455f-8c9a-a5a56fdb62e3", | |
| "bb9f3448-b019-46be-82df-7d51e187a888", | |
| "299cbf31-0dd0-4ab0-b892-00f55a3015a5", | |
| "db474f6c-87d0-4ab8-9a69-d8562233d797", | |
| "01d912b7-23ba-426f-80b7-b9042fd75f7f", | |
| "aa4e8f74-7d2d-476e-943c-bc688c0d7ae6", | |
| "83788f1a-9fcf-45e7-bdde-3942705d1f40", | |
| "ffff9cbb-5d4c-45eb-acb2-a5717b56c79d", | |
| "f1ae888a-9819-422f-9d57-eb0f3ac71b28", | |
| "d85c8005-937f-4828-9519-b86efb499346", | |
| "30015fab-a7ea-4571-bb67-39169f004bd1", | |
| "cdc7bf5e-7b1b-4e34-83b0-660e85d6d220", | |
| "acfced87-fdfd-4fbe-a5ba-7305f896e3e4", | |
| "ac6338cc-c36c-4525-b8c5-1ecc22834f9f", | |
| "40a27799-1097-488c-be4f-1190d62f11dc", | |
| "390c120c-85bf-4acd-822d-9d7ff1d3d84c", | |
| "a6026b73-808d-471d-aec0-b21d3bea2f10", | |
| "e175ae19-4913-4215-8b59-fd00395329dc", | |
| "c8f72693-5eb8-41ec-a570-e9a413cd2e24", | |
| "a65aaaaf-6147-4b47-ad65-c58e3bd577e5", | |
| "34841aa8-31f1-4d77-ac3b-697548fec2c1", | |
| "9b0c8286-9ec9-494c-8b18-1ca19e1cad89", | |
| "5cab4e49-f20f-4ca7-9ecb-ec7fce946dce", | |
| "b0d0482c-ed02-4e8d-a0bf-58a6fc80116a", | |
| "f9775b39-5720-4fc9-8530-5b861d0af1d0", | |
| "410fd465-7af5-4d93-b7cf-ebe11c07c5f4", | |
| "9efde923-95d2-4b39-a69f-b41997274e16", | |
| "eb9cfc94-057d-4a19-b521-43659ec6521d", | |
| "474289cf-1bfd-421c-9c09-6ba51af1df86", | |
| "4f1c4f42-ed8f-45c8-a9ac-e7d94ef90b70", | |
| "52f9a9c3-2d27-44bc-8a3b-88ffe2729eb8", | |
| "5d215673-84e9-4d8b-b4d0-7c5abf46a3da", | |
| "e533b985-6308-4735-9cf9-4bb4a9526aeb", | |
| "8fc7e503-51da-44c1-9c7e-8601f3deec83", | |
| "5ead77e9-8266-4bd6-9ea8-8f4e3a3ccb5d", | |
| "5de8adc0-2b98-4da8-aa2b-dc0edb7612c1", | |
| "c19a0168-d326-4fe0-ae17-56052b1997de", | |
| "b1015433-eaff-4a87-acf4-9a9355f2ceb3", | |
| "4b24601b-c303-4c46-a4a7-e126e0db9a82", | |
| "5fa5a084-5f72-42e7-9a1f-7d499acbcf35", | |
| "2f382192-2657-4a51-8f14-a286ba8a07ac", | |
| "aa46ae5a-9405-4181-8415-7e283da39b52" | |
| ] | |
| for org_id in all_orgs: | |
| print(org_id) | |
| check_filter_by_entity('candidate', org_id) | |
| check_filter_by_entity('employee', org_id) | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment