def get_last_message_on_masterrecord(jtrace: Session, errorsdb: Session, record_id: int, user: UKRDCUser) -> Optional[Message]: """ Return a summary of the most recent file recieved for a MasterRecord, within the last year Args: errorsdb (Session): SQLAlchemy session jtrace (Session): SQLAlchemy session record_id (int): MasterRecord ID user (UKRDCUser): User object Returns: MasterRecord: MasterRecord """ record: MasterRecord = get_masterrecord(jtrace, record_id, user) msgs = (get_messages_related_to_masterrecord( errorsdb, jtrace, record.id, user, statuses=None, since=datetime.datetime.utcnow() - datetime.timedelta(days=365), ).filter(Message.facility != "TRACING").filter( Message.filename.isnot(None))) return msgs.order_by(Message.received.desc()).first()
async def unlink_person_from_master_record( person_id: int, master_id: int, comment: Optional[str], user: UKRDCUser, jtrace: Session, mirth: MirthAPI, redis: Redis, ) -> LinkRecordSchema: """Unlink a particular Person record from a Master Record""" # Get records to assert user permission person = get_person(jtrace, person_id, user) master = get_masterrecord(jtrace, master_id, user) # Build and send the unlink message await safe_send_mirth_message_to_name( "Unlink", build_unlink_message(master.id, person.id, user.email, description=comment), mirth, redis, ) await sleep(0.5) # Wait for the message to be processed (complete guess) # Find the new Master Record first_link_related_to_person = (jtrace.query(LinkRecord).filter( LinkRecord.person_id == person.id).first()) return LinkRecordSchema.from_orm(first_link_related_to_person)
def get_auditevents_related_to_masterrecord( audit: Session, ukrdc3: Session, jtrace: Session, record_id: int, user: UKRDCUser, since: Optional[datetime.datetime] = None, until: Optional[datetime.datetime] = None, ) -> Query: """ Get all audit events related to a master record or any of its patient records. Args: audit (Session): AUDITDB SQLAlchemy session jtrace (Session): JTRACE SQLAlchemy session ukrdc3 (Session): UKRDC SQLAlchemy session record_id (str): MasterRecord ID user (UKRDCUser): User object Returns: Query: SQLAlchemy query """ # Get the main record and check permissions record = get_masterrecord(jtrace, record_id, user) # Get all related master records master_records = get_masterrecords_related_to_masterrecord( jtrace, record.id, user, exclude_self=False) # Get all related patient records patient_records = get_patientrecords_related_to_masterrecord( ukrdc3, jtrace, record_id, user) conditions = [ and_( AuditEvent.resource == Resource.MASTER_RECORD.value, AuditEvent.resource_id.in_([str(mr.id) for mr in master_records]), ), and_( AuditEvent.resource == Resource.PATIENT_RECORD.value, AuditEvent.resource_id.in_([str(pr.pid) for pr in patient_records]), ), ] query = audit.query(AuditEvent).join(AccessEvent).filter(or_(*conditions)) # Only show top-level events in the query. Child events are attached to parents query = query.filter(AuditEvent.parent_id.is_(None)) if since: query = query.filter(AccessEvent.time >= since) if until: query = query.filter(AccessEvent.time <= until) return query
async def merge_master_records( superseding_id: int, superseded_id: int, user: UKRDCUser, jtrace: Session, mirth: MirthAPI, redis: Redis, ) -> MirthMessageResponseSchema: """Merge a pair of MasterRecords""" superseding: MasterRecord = get_masterrecord(jtrace, superseding_id, user) superseded: MasterRecord = get_masterrecord(jtrace, superseded_id, user) return await safe_send_mirth_message_to_name( "Merge Patient", build_merge_message(superseding=superseding.id, superseded=superseded.id), mirth, redis, )
def master_record_detail( record_id: int, user: UKRDCUser = Security(auth.get_user()), jtrace: Session = Depends(get_jtrace), audit: Auditer = Depends(get_auditer), ): """Retreive a particular master record from the EMPI""" record = get_masterrecord(jtrace, record_id, user) audit.add_event(Resource.MASTER_RECORD, record.id, AuditOperation.READ) return record
def master_record_statistics( record_id: int, user: UKRDCUser = Security(auth.get_user()), jtrace: Session = Depends(get_jtrace), errorsdb: Session = Depends(get_errorsdb), audit: Auditer = Depends(get_auditer), ): """Retreive a particular master record from the EMPI""" record: MasterRecord = get_masterrecord(jtrace, record_id, user) errors = get_messages_related_to_masterrecord( errorsdb, jtrace, record.id, user, statuses=["ERROR"] ) related_records = get_masterrecords_related_to_masterrecord(jtrace, record.id, user) related_ukrdc_records = related_records.filter( MasterRecord.nationalid_type == "UKRDC" ) workitems = get_workitems( jtrace, user, master_id=[record.id for record in related_records.all()] ) audit.add_event( Resource.STATISTICS, None, AuditOperation.READ, parent=audit.add_event(Resource.MASTER_RECORD, record.id, AuditOperation.READ), ) return MasterRecordStatisticsSchema( workitems=workitems.count(), errors=errors.count(), # Workaround for https://jira.ukrdc.org/browse/UI-56 # For some reason, if you log in as a non-admin user, # related_ukrdc_records.count() returns the wrong value # sometimes, despite the query returning the right data. # I truly, deeply do not understand why this would happen, # so I've had to implement this slightly slower workaround. # Assuming the patient doesn't somehow have hundreds of # UKRDC records, the speed decrease should be negligable. ukrdcids=len(related_ukrdc_records.all()), )
async def master_record_memberships_create_pkb( record_id: int, user: UKRDCUser = Security(auth.get_user()), jtrace: Session = Depends(get_jtrace), mirth: MirthAPI = Depends(get_mirth), audit: Auditer = Depends(get_auditer), redis: Redis = Depends(get_redis), ): """ Create a new PKB membership for a master record. """ record = get_masterrecord(jtrace, record_id, user) # If the request was not triggered from a UKRDC MasterRecord if record.nationalid_type != "UKRDC": # Find all linked UKRDC MasterRecords records = get_masterrecords_related_to_masterrecord( jtrace, record_id, user, nationalid_type="UKRDC", ).all() if len(records) > 1: raise HTTPException( 500, "Cannot create PKB membership for a patient with multiple UKRDC IDs", ) if len(records) == 0: raise HTTPException( 500, "Cannot create PKB membership for a patient with no UKRDC ID", ) # Use the UKRDC MasterRecord to create the PKB membership record = records[0] audit.add_event( Resource.MEMBERSHIP, "PKB", AuditOperation.CREATE, parent=audit.add_event(Resource.MASTER_RECORD, record_id, AuditOperation.READ), ) return await create_pkb_membership(record, mirth, redis)
def test_get_masterrecord_denied(jtrace_session, test_user): with pytest.raises(PermissionsError): masterrecords.get_masterrecord(jtrace_session, 2, test_user)
def test_get_masterrecord_user(jtrace_session, test_user): record = masterrecords.get_masterrecord(jtrace_session, 1, test_user) assert record assert record.id == 1