def get_projects(token_info, include_stats, is_active=None): validate_admin_access(token_info) with Transaction() as t: admin_repo = AdminRepo(t) projects_list = admin_repo.get_projects(include_stats, is_active) result = [x.to_api() for x in projects_list] return jsonify(result), 200
def _set_up_and_query_projects(self, t, include_stats, is_active_val): updated_dict = self._FULL_PROJECT_DICT.copy() updated_dict[p.PROJ_NAME_KEY] = 'test_proj' input = p.Project.from_dict(updated_dict) admin_repo = AdminRepo(t) # existing project 8 in test db admin_repo.update_project(8, input) set_up_sql = """ -- add some additional scans to project 8 so can test that -- computed statistics based on latest scans are choosing all -- (and only) the scans that they should: -- add a scan w an earlier timestamp (though added into db -- later) than existing one showing that this barcode USED TO -- have a problem but no longer does. insert into barcodes.barcode_scans (barcode, scan_timestamp, sample_status) VALUES ('000007640', '2012-11-01', 'no-registered-account'); -- add a second *sample-is-valid* scan for the same barcode -- so can ensure that sample status count are distinct insert into barcodes.barcode_scans (barcode, scan_timestamp, sample_status) VALUES ('000007640', '2012-12-01', 'sample-is-valid'); -- add two additional scans for a different barcode: a valid -- scan followed by a problem scan, thus indicting this sample -- currently has a problem. insert into barcodes.barcode_scans (barcode, scan_timestamp, sample_status) VALUES ('000070796', '2020-07-01', 'sample-is-valid'); insert into barcodes.barcode_scans (barcode, scan_timestamp, sample_status) VALUES ('000070796', '2020-09-01', 'no-registered-account'); UPDATE barcodes.project SET is_active = FALSE WHERE project_id = 2; """ with t.cursor() as cur: cur.execute(set_up_sql) output = admin_repo.get_projects(include_stats, is_active_val) updated_dict["project_id"] = 8 computed_stats = \ {p.NUM_FULLY_RETURNED_KITS_KEY: 1, p.NUM_KITS_KEY: 5, p.NUM_KITS_W_PROBLEMS_KEY: 1, 'num_no_associated_source': 0, 'num_no_collection_info': 0, 'num_no_registered_account': 1, 'num_received_unknown_validity': 0, 'num_sample_is_valid': 4, p.NUM_PARTIALLY_RETURNED_KITS_KEY: 2, p.NUM_SAMPLES_KEY: 20, p.NUM_SAMPLES_RECEIVED_KEY: 5, p.NUM_UNIQUE_SOURCES_KEY: 4} updated_dict[p.COMPUTED_STATS_KEY] = \ computed_stats if include_stats else {} return updated_dict, output
def list_barcode_query_fields(token_info): validate_admin_access(token_info) # Generates a json array declaring the filters # that can be used for barcode queries # Will be parseable by jQuery QueryBuilder # to allow a user to modify queries. # Barcode queries can filter on: # - project (categorical, any project in our db) # - sample_status (categorical, fixed list) # - sample_type (categorical, fixed list) # See examples https://querybuilder.js.org/demo.html # https://querybuilder.js.org/assets/demo-import-export.js with Transaction() as t: admin_repo = AdminRepo(t) projects_list = admin_repo.get_projects(False) projects_list.sort(key=lambda x: x.project_name) filter_fields = [] filter_fields.append( { 'id': 'project_id', 'label': 'Project', 'type': 'integer', 'input': 'select', 'values': { x.project_id: x.project_name for x in projects_list }, 'operators': ['equal', 'not_equal'] } ) filter_fields.append( { 'id': 'sample_status', 'label': 'Sample Status', 'type': 'string', 'input': 'select', 'values': { "sample-is-valid": "Sample Is Valid", "no-associated-source": "No Associated Source", "no-registered-account": "No Registered Account", "no-collection-info": "No Collection Info", "sample-has-inconsistencies": "Sample Has Inconsistencies", "received-unknown-validity": "Received Unknown Validity" }, 'operators': ['equal', 'not_equal', 'is_null', 'is_not_null'] } ) filter_fields.append( { 'id': 'site_sampled', 'label': 'Sample Site', 'type': 'string', 'input': 'select', 'values': { "Blood (skin prick)": "Blood (skin prick)", "Saliva": "Saliva", "Ear wax": "Ear wax", "Forehead": "Forehead", "Fur": "Fur", "Hair": "Hair", "Left hand": "Left hand", "Left leg": "Left leg", "Mouth": "Mouth", "Nares": "Nares", "Nasal mucus": "Nasal mucus", "Right hand": "Right hand", "Right leg": "Right leg", "Stool": "Stool", "Tears": "Tears", "Torso": "Torso", "Vaginal mucus": "Vaginal mucus" }, 'operators': ['equal', 'not_equal', 'is_null', 'is_not_null'] } ) filter_fields.append( { # Note that this id string must match the # latest scan timestamp in the exact # barcode search query. 'id': 'scan_timestamp_latest', 'label': 'Last Scanned', 'type': 'date', 'description': "YYYY/MM/DD", 'default_value': "YYYY/MM/DD", 'validation': { "format": "YYYY/MM/DD" }, 'operators': ['less_or_equal', 'greater_or_equal', 'is_null', 'is_not_null'] } ) return jsonify(filter_fields), 200