def _deprecated_update_original_family_fields(project, family, fields): # also update base family base_family = BaseFamily.objects.filter( project__project_id=project.deprecated_project_id, family_id=family.family_id) base_family = base_family[0] update_family_from_json(base_family, fields)
def update_family_field_handler(request, family_guid, field_name): """Updates the specified field in the Family model. Args: family_guid (string): GUID of the family. field_name (string): Family model field name to update """ family = Family.objects.get(guid=family_guid) # check permission project = family.project if not request.user.is_staff and not request.user.has_perm(CAN_EDIT, project): raise PermissionDenied("%s does not have EDIT permissions for %s" % (request.user, project)) request_json = json.loads(request.body) if "value" not in request_json: raise ValueError("Request is missing 'value' key") value = request_json['value'] family_json = {field_name: value} update_family_from_json(family, family_json) _deprecated_update_original_family_record(project, family, field_name, value) return create_json_response({ family.guid: _get_json_for_family(family, request.user) })
def update_family_field_handler(request, family_guid, field_name): """Updates the specified field in the Family model. Args: family_guid (string): GUID of the family. field_name (string): Family model field name to update """ family = Family.objects.get(guid=family_guid) # check permission project = family.project check_permissions(project, request.user, CAN_EDIT) request_json = json.loads(request.body) if "value" not in request_json: raise ValueError("Request is missing 'value' key: %s" % (request.body, )) value = request_json['value'] family_json = {field_name: value} update_family_from_json(family, family_json) _deprecated_update_original_family_field(project, family, field_name, value) return create_json_response( {family.guid: _get_json_for_family(family, request.user)})
def edit_families_handler(request, project_guid): """Edit or one or more Family records. Args: project_guid (string): GUID of project that contains these individuals. """ project = get_project_and_check_pm_permissions(project_guid, request.user) request_json = json.loads(request.body) if request_json.get('uploadedFileId'): modified_families = load_uploaded_file( request_json.get('uploadedFileId')) else: modified_families = request_json.get('families') if modified_families is None: return create_json_response({}, status=400, reason="'families' not specified") updated_families = [] for fields in modified_families: if fields.get('familyGuid'): family = Family.objects.get(project=project, guid=fields['familyGuid']) elif fields.get(PREVIOUS_FAMILY_ID_FIELD): family = Family.objects.get( project=project, family_id=fields[PREVIOUS_FAMILY_ID_FIELD]) else: family, _ = get_or_create_model_from_json( Family, { 'project': project, 'family_id': fields[FAMILY_ID_FIELD] }, update_json=None, user=request.user) update_family_from_json(family, fields, user=request.user, allow_unknown_keys=True) updated_families.append(family) updated_families_by_guid = { 'familiesByGuid': { family.guid: _get_json_for_family(family, request.user, add_individual_guids_field=True) for family in updated_families } } return create_json_response(updated_families_by_guid)
def edit_families_handler(request, project_guid): """Edit or one or more Family records. Args: project_guid (string): GUID of project that contains these individuals. """ project = get_project_and_check_permissions(project_guid, request.user, CAN_EDIT) request_json = json.loads(request.body) if 'form' not in request_json: return create_json_response( {}, status=400, reason="Invalid request: 'form' key not specified") form_data = request_json['form'] modified_families_by_guid = form_data.get('modifiedFamilies') if modified_families_by_guid is None: return create_json_response( {}, status=400, reason="'modifiedIndividuals' not specified") # TODO more validation #errors, warnings = validate_fam_file_records(modified_individuals_list) #if errors: # return create_json_response({'errors': errors, 'warnings': warnings}) updated_families = [] for familyGuid, fields in modified_families_by_guid.items(): family = Family.objects.get(project=project, guid=familyGuid) update_family_from_json(family, fields) updated_families.append(family) for key, value in fields.items(): # TODO do this more efficiently _deprecated_update_original_family_field(project, family, key, value) updated_families_by_guid = { 'familiesByGuid': { family.guid: _get_json_for_family(family, request.user, add_individual_guids_field=True) for family in updated_families } } return create_json_response(updated_families_by_guid)
def update_family_fields_handler(request, family_guid): """Updates the specified field in the Family model. Args: family_guid (string): GUID of the family. """ family = Family.objects.get(guid=family_guid) # check permission - can be edited by anyone with access to the project check_project_permissions(family.project, request.user) request_json = json.loads(request.body) update_family_from_json(family, request_json, user=request.user, allow_unknown_keys=True, immutable_keys=[ 'family_id', 'display_name', ]) return create_json_response({ family.guid: _get_json_for_family(family, request.user) })
def update_family_fields_handler(request, family_guid): """Updates the specified field in the Family model. Args: family_guid (string): GUID of the family. """ family = Family.objects.get(guid=family_guid) # check permission project = family.project check_project_permissions(project, request.user, can_edit=True) request_json = json.loads(request.body) update_family_from_json(family, request_json, user=request.user, allow_unknown_keys=True) return create_json_response({ family.guid: _get_json_for_family(family, request.user) })
def update_family_fields_handler(request, family_guid): """Updates the specified field in the Family model. Args: family_guid (string): GUID of the family. """ family = Family.objects.get(guid=family_guid) # check permission project = family.project check_permissions(project, request.user, CAN_EDIT) request_json = json.loads(request.body) update_family_from_json(family, request_json, user=request.user, allow_unknown_keys=True) return create_json_response({ family.guid: _get_json_for_family(family, request.user) })
def edit_families_handler(request, project_guid): """Edit or one or more Family records. Args: project_guid (string): GUID of project that contains these individuals. """ request_json = json.loads(request.body) if request_json.get('uploadedFileId'): modified_families = load_uploaded_file(request_json.get('uploadedFileId')) else: modified_families = request_json.get('families') if modified_families is None: return create_json_response( {}, status=400, reason="'families' not specified") project = get_project_and_check_permissions(project_guid, request.user, CAN_EDIT) updated_families = [] for fields in modified_families: if fields.get('familyGuid'): family = Family.objects.get(project=project, guid=fields['familyGuid']) elif fields.get(PREVIOUS_FAMILY_ID_FIELD): family = Family.objects.get(project=project, family_id=fields[PREVIOUS_FAMILY_ID_FIELD]) else: family, _ = get_or_create_seqr_model(Family, project=project, family_id=fields[FAMILY_ID_FIELD]) update_family_from_json(family, fields, user=request.user, allow_unknown_keys=True) updated_families.append(family) updated_families_by_guid = { 'familiesByGuid': { family.guid: _get_json_for_family(family, request.user, add_individual_guids_field=True) for family in updated_families } } return create_json_response(updated_families_by_guid)
def add_or_update_individuals_and_families(project, individual_records, user): """ Add or update individual and family records in the given project. Args: project (object): Django ORM model for the project to add families to individual_records (list): A list of JSON records representing individuals. See the return value of pedigree_info_utils#convert_fam_file_rows_to_json(..) Return: 2-tuple: updated_families, updated_individuals containing Django ORM models """ updated_families = set() updated_individuals = set() parent_updates = [] family_ids = {_get_record_family_id(record) for record in individual_records} families_by_id = {f.family_id: f for f in Family.objects.filter(project=project, family_id__in=family_ids)} missing_family_ids = family_ids - set(families_by_id.keys()) for family_id in missing_family_ids: family = create_model_from_json(Family, {'project': project, 'family_id': family_id}, user) families_by_id[family_id] = family updated_families.add(family) individual_models = Individual.objects.filter(family__project=project).prefetch_related( 'family', 'mother', 'father') has_individual_guid = any(record.get('individualGuid') for record in individual_records) if has_individual_guid: individual_lookup = { i.guid: i for i in individual_models.filter( guid__in=[record['individualGuid'] for record in individual_records]) } else: individual_lookup = defaultdict(dict) for i in individual_models.filter( individual_id__in=[_get_record_individual_id(record) for record in individual_records]): individual_lookup[i.individual_id][i.family] = i for record in individual_records: family_id = _get_record_family_id(record) family = families_by_id.get(family_id) if has_individual_guid: individual = individual_lookup[record.pop('individualGuid')] else: # uploaded files do not have unique guid's so fall back to a combination of family and individualId individual_id = _get_record_individual_id(record) individual = individual_lookup[individual_id].get(family) if not individual: individual = create_model_from_json( Individual, {'family': family, 'individual_id': individual_id, 'case_review_status': 'I'}, user) record['family'] = family record.pop('familyId', None) if individual.family != family: family = individual.family updated_families.add(family) previous_id = record.pop(JsonConstants.PREVIOUS_INDIVIDUAL_ID_COLUMN, None) if previous_id: updated_individuals.update(individual.maternal_children.all()) updated_individuals.update(individual.paternal_children.all()) record['displayName'] = '' # Update the parent ids last, so if they are referencing updated individuals they will check for the correct ID if record.get('maternalId') or record.get('paternalId'): parent_updates.append({ 'individual': individual, 'maternalId': record.pop('maternalId', None), 'paternalId': record.pop('paternalId', None), }) family_notes = record.pop(JsonConstants.FAMILY_NOTES_COLUMN, None) if family_notes: update_family_from_json(family, {'analysis_notes': family_notes}, user) updated_families.add(family) is_updated = update_individual_from_json(individual, record, user=user, allow_unknown_keys=True) if is_updated: updated_individuals.add(individual) updated_families.add(family) for update in parent_updates: individual = update.pop('individual') is_updated = update_individual_from_json(individual, update, user=user) if is_updated: updated_individuals.add(individual) updated_families.add(individual.family) # update pedigree images update_pedigree_images(updated_families, user, project_guid=project.guid) return list(updated_families), list(updated_individuals)
def _add_or_update_individuals_and_families(project, individual_records, user=None): """Add or update individual and family records in the given project. Args: project (object): Django ORM model for the project to add families to individual_records (list): A list of JSON records representing individuals. See the return value of pedigree_info_utils#convert_fam_file_rows_to_json(..) Return: 2-tuple: updated_families, updated_individuals containing Django ORM models """ families = {} updated_individuals = set() parent_updates = [] for i, record in enumerate(individual_records): # family id will be in different places in the json depending on whether it comes from a flat uploaded file or from the nested individual object family_id = record.get(JsonConstants.FAMILY_ID_COLUMN) or record.get('family', {}).get('familyId') if not family_id: raise ValueError("record #%s doesn't contain a 'familyId' key: %s" % (i, record)) if JsonConstants.INDIVIDUAL_ID_COLUMN not in record and 'individualGuid' not in record: raise ValueError("record #%s doesn't contain an 'individualId' key: %s" % (i, record)) family = families.get(family_id) if family: created = False else: family, created = Family.objects.get_or_create(project=project, family_id=family_id) if created: logger.info("Created family: %s", family) # uploaded files do not have unique guid's so fall back to a combination of family and individualId if record.get('individualGuid'): individual_filters = {'guid': record['individualGuid']} else: individual_id = record.get(JsonConstants.PREVIOUS_INDIVIDUAL_ID_COLUMN) or record[JsonConstants.INDIVIDUAL_ID_COLUMN] individual_filters = {'family': family, 'individual_id': individual_id} individual, created = Individual.objects.get_or_create(**individual_filters) if created: record.update({ 'caseReviewStatus': 'I', }) record['family'] = family record.pop('familyId', None) if individual.family != family: families[individual.family.family_id] = individual.family if record.get(JsonConstants.PREVIOUS_INDIVIDUAL_ID_COLUMN): updated_individuals.update(individual.maternal_children.all()) updated_individuals.update(individual.paternal_children.all()) record['displayName'] = '' # Update the parent ids last, so if they are referencing updated individuals they will check for the correct ID if record.get('maternalId') or record.get('paternalId'): parent_updates.append({ 'individual': individual, 'maternalId': record.pop('maternalId', None), 'paternalId': record.pop('paternalId', None), }) update_individual_from_json(individual, record, allow_unknown_keys=True, user=user) if record.get(JsonConstants.FAMILY_NOTES_COLUMN): update_family_from_json(family, {'analysis_notes': record[JsonConstants.FAMILY_NOTES_COLUMN]}) updated_individuals.add(individual) families[family.family_id] = family for update in parent_updates: individual = update.pop('individual') update_individual_from_json(individual, update, user=user) updated_families = list(families.values()) # update pedigree images update_pedigree_images(updated_families, project_guid=project.guid) return updated_families, list(updated_individuals)
def _deprecated_update_original_family_fields(project, family, fields): # also update base family base_family = BaseFamily.objects.filter( project__project_id=project.deprecated_project_id, family_id=family.family_id) base_family = base_family[0] update_family_from_json(base_family, fields)