Ejemplo n.º 1
0
        public async SystemTasks.Task <Resource> ValidateConditionalUpdate(FhirRequest request)
        {
            if (!request.Resource.ResourceType.Equals(ResourceType.DocumentReference))
            {
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo"));
            }

            var document = request.Resource as DocumentReference;

            if (document.RelatesTo == null || document.RelatesTo.Count == 0)
            {
                return(null);
            }

            var relatesTo = _fhirValidation.GetValidRelatesTo(document.RelatesTo);

            if (relatesTo.element == null)
            {
                return(OperationOutcomeFactory.CreateInvalidResource(relatesTo.issue));
            }

            //Subject already validated during ValidateCreate
            //relatesTo Identifier already validated during ValidateCreate => validPointer
            var subjectNhsNumber = _fhirValidation.GetSubjectReferenceId(document.Subject);
            var pointerRequest   = NrlsPointerHelper.CreateMasterIdentifierSearch(request, relatesTo.element.Target.Identifier, subjectNhsNumber);
            var pointers         = await _fhirSearch.Find <DocumentReference>(pointerRequest) as Bundle;

            if (pointers.Entry.Count != 1)
            {
                //Cant find related document
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target"));
            }

            //Custodian already validated against incoming ASID during ValidateCreate
            var custodianOdsCode = _fhirValidation.GetOrganizationReferenceId(document.Custodian);

            var oldDocument = pointers.Entry.First().Resource as DocumentReference;

            if (oldDocument.Custodian == null || string.IsNullOrEmpty(oldDocument.Custodian.Reference) || oldDocument.Custodian.Reference != $"{FhirConstants.SystemODS}{custodianOdsCode}")
            {
                //related document does not have same custodian
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target"));
            }

            if (oldDocument.Status != DocumentReferenceStatus.Current)
            {
                //Only allowed to transition to superseded from current
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.code"));
            }

            return(oldDocument);
        }
        public async SystemTasks.Task <Resource> ValidateConditionalUpdate(FhirRequest request)
        {
            if (!request.Resource.ResourceType.Equals(ResourceType.DocumentReference))
            {
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo"));
            }

            var document = request.Resource as DocumentReference;

            var relatesTo = _fhirValidation.GetValidRelatesTo(document.RelatesTo);

            if (document.RelatesTo.Count == 0)
            {
                //skip checks, request is just a standard create
                return(null);
            }
            else if (relatesTo.element == null)
            {
                return(OperationOutcomeFactory.CreateInvalidResource(relatesTo.issue));
            }

            //Subject already validated during ValidateCreate
            //relatesTo Reference/Identifier already validated during ValidateCreate => validPointer

            var isRelatesToReference = !string.IsNullOrWhiteSpace(relatesTo.element.Target.Reference);

            FhirRequest       pointerRequest = null;
            DocumentReference oldDocument    = null;

            if (isRelatesToReference)
            {
                var pointerId = _fhirValidation.GetReferenceId(relatesTo.element.Target);
                pointerRequest = NrlsPointerHelper.CreateReferenceSearch(request, pointerId);
                oldDocument    = await _fhirSearch.Get <DocumentReference>(pointerRequest);
            }
            else
            {
                var subjectNhsNumber = _fhirValidation.GetSubjectReferenceId(document.Subject);
                pointerRequest = NrlsPointerHelper.CreateMasterIdentifierSearch(request, relatesTo.element.Target.Identifier, subjectNhsNumber);
                var pointers = await _fhirSearch.Find <DocumentReference>(pointerRequest);

                //There should only ever be zero or one
                oldDocument = pointers.Entry.FirstOrDefault()?.Resource as DocumentReference;
            }

            if (oldDocument == null)
            {
                //Cant find related document
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target", "Referenced DocumentReference does not exist."));
            }

            //related document does not have same patient
            if (string.IsNullOrEmpty(oldDocument.Subject.Reference) || oldDocument.Subject.Reference != document.Subject.Reference)
            {
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target", "Resolved DocumentReference is not associated with the same patient."));
            }

            //Reference type checks
            if (isRelatesToReference)
            {
                //related document does not have masterIdentifier or masterIdentifier does not match new
                var docRelatesToIdentifier = document.RelatesTo.First().Target.Identifier;
                if (docRelatesToIdentifier != null)
                {
                    var oldDocRelatesToIdentifier = oldDocument.MasterIdentifier;

                    if (oldDocRelatesToIdentifier == null)
                    {
                        return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target", "Resolved DocumentReference does not have an MasterIdentifier."));
                    }

                    if (string.IsNullOrWhiteSpace(docRelatesToIdentifier.System) || string.IsNullOrWhiteSpace(docRelatesToIdentifier.Value) ||
                        docRelatesToIdentifier.Value != oldDocRelatesToIdentifier.Value || docRelatesToIdentifier.System != oldDocRelatesToIdentifier.System)
                    {
                        return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target", "Resolved DocumentReference does not have a matching MasterIdentifier."));
                    }
                }
            }

            //Custodian already validated against incoming ASID during ValidateCreate
            var custodianOdsCode = _fhirValidation.GetOrganizationReferenceId(document.Custodian);

            if (oldDocument.Custodian == null || string.IsNullOrEmpty(oldDocument.Custodian.Reference) || oldDocument.Custodian.Reference != $"{FhirConstants.SystemODS}{custodianOdsCode}")
            {
                //related document does not have same custodian
                return(OperationOutcomeFactory.CreateInvalidResource("relatesTo.target", $"Resolved DocumentReference is not associated with custodian {custodianOdsCode}"));
            }

            if (oldDocument.Status != DocumentReferenceStatus.Current)
            {
                //Only allowed to transition to superseded from current
                return(OperationOutcomeFactory.CreateInactiveDocumentReference());
            }

            return(oldDocument);
        }