none
GetMeaningfulUseVDTReport function always returns empty list when using the child application in ppe environment RRS feed

  • Question

  • Hi,

    We are using the Master-Child application with "Record Authorization" method.

    GetMeaningfulUseVDTReport works good with the given sample code, but when I tried to integrate the changes to our current implementation with the following required changes the GetMeaningfulUseVDTReport gives always a empty list.

    1. "Application requires access to Meaningful Use reports" option is selected in the Child App settings.

    2. All the required permission is given to some types including CCD and CDA. 

    3. The appropriate certificate is uploaded.

    4. On uploading the CCD/CDA the extension is added as done in the sample application, with patient id.

    The only difference of our implementation from the sample code is the application id is a generated id from a Master application id.

    Please help me on this to location what I am missing.

    Or is there any special thing to do for Child Application to access the   Meaningful Use reports?

    Thanks,

    Robert


    Wednesday, February 12, 2014 11:51 PM

All replies

  • Robert,

    MU2 reports are always associated with the application ID that contributes the CCDA. Make sure your CCDA upload process is using the child app ID (and associated private key on your end), and when you're requesting the report, you're using the child app ID (and associated private key).

    Another thing to be aware of is that setting the "Application requires access to Meaningful Use reports" in the Child App settings of the ACC portal, specifies that the master app may provision child apps with this access. When you create the child application, you must specify the methods the child app can invoke. If you're using the .NET SDK, you will use AddApplication to create the child app, and set the callable methods using the CallableMethods property to values in the HealthVaultMethods enum.

    Ali


    Friday, February 14, 2014 4:41 AM
  • Ali,

    Thankyou for your advice.

    I found that the I am not setting the CallableMethods when I create the child application.

    In order to set the callable methods I did the following  

    • applicationInfo.CallableMethods.Add(HealthVaultMethods.GetMeaningfulUseVDTReport);
    • OfflineWebApplicationConnection offlineConn = HealthVaultConnectionManager.CreateConnection(_applicationId);
    • childAppID = Microsoft.Health.ApplicationProvisioning.Provisioner.AddApplication(offlineConn, applicationInfo);

    The child app id is created successfully.

    But I am getting HealthServiceAccesDenied exception with a message 'The application does not have permission to call the specified method.' when I call Authenticate(). which is for patient connect.

    Code:

    OfflineWebApplicationConnection offlineConn = new OfflineWebApplicationConnection(applicationId, 
                    WebApplicationConfiguration.HealthServiceUrl, Guid.Empty);
    offlineConn.Authenticate();

    Kindly correct me if my code is wrong or if you have a link to a similar sample code, kindly provide me .

    Thanks,

    Robert 

    Tuesday, February 18, 2014 11:16 PM
  • Hi,

    Can any one answer my question?

    Thanks,

    Robert

    Tuesday, February 25, 2014 8:19 PM
  • Hi Robert,

    The child app will need access to methods other than the meaningful use ones in order to do things like authenticate against HealthVault, query data, write data, etc.

    As indicated above, you specify the list of methods in the "CallableMethods" property.

    I'm including here a list of "base" HealthVault methods that are commonly used by applications. You can include these on the CallableMethod property when creating the child app:

    CreateAuthenticatedSessionToken, GetServiceDefinition, GetPersonInfo, GetAuthorizedRecords, QueryPermissions, GetApplicationInfo, GetApplicationSettings, SetApplicationSettings, PutThings, GetThingType, GetVocabulary, SearchVocabulary, CreateConnectRequest, DeletePendingConnectRequest, GetAuthorizedConnectRequests, UpdateExternalId, GetUpdatedRecordsForApplication, RemoveApplicationRecordAuthorization, GetValidGroupMembership, BeginPutBlob, GetAuthorizedPeople, SelectInstance, GetThings, RemoveThings


    Tuesday, February 25, 2014 10:50 PM
  • Hi Ali,

    Thanks for the help.

    When I added all of the callable methods as you have mentioned, the HealthServiceAccesDenied exception disappeared but still  I am getting an empty list when I call GetMeaningfulUseVDTReport.

    I am adding my code snippets. Please advice me.

    This is how I added my MU extension and upload

    public void UploadCCDAWithMUExtension(XmlDocument ccdDocument, Guid personId, Guid recordId,   DateTime eventTime, string patientID)
    {  
      StringBuilder stringBuilder = new StringBuilder(150);
    
      string extSource = "hv-meaningfuluse";
    
      using (XmlWriter writer = XmlWriter.Create(stringBuilder, new XmlWriterSettings() { OmitXmlDeclaration = true }))
      {
        writer.WriteStartElement("extension");
        writer.WriteAttributeString("source", extSource);
        if (eventTime != DateTime.MinValue)
        {
          writer.WriteElementString("event-date", eventTime.ToString());
        }
        if (!string.IsNullOrEmpty(patientID))
        {
           writer.WriteElementString("patient-id", patientID);
        }
        writer.WriteEndElement();
     }
    
      HealthRecordItemExtension ext = new HealthRecordItemExtension(extSource);
      ext.ExtensionData.CreateNavigator().InnerXml = stringBuilder.ToString();
      // HealthRecordItem ccda = new HealthRecordItem(CDA.TypeId, ccdDocument); // I tried both CCD and CDA
      HealthRecordItem ccda = new HealthRecordItem(CCD.TypeId, ccdDocument);
      ccda.CommonData.Extensions.Add(ext);
      HealthRecordAccessor accessor = new HealthRecordAccessor(HealthVaultConnectionManager.CreateConnection(_applicationId, personId), recordId);
      accessor.NewItem(ccda);
    } 
    
    //The below code is how I get the VDT Report.
    
    GetVDTReports(DateTime.Now.AddDays(-180), DateTime.Now); // Test code 
    
    // Calls HealthVault to a 'View, Download, Transmit' report
    private string GetVDTReports(DateTime reportStart, DateTime reportEnd)
    {
      Guid appId = new Guid();
      DateRange dateFilter = new DateRange(reportStart, reportEnd);
      _healthVaultModel.GetHealthVaultApplicationID(out appId);
      OfflineWebApplicationConnection offlineConnection = HealthVaultConnectionManager.CreateConnection(appId);
      IEnumerable<PatientActivity> resultActivities = offlineConnection.GetMeaningfulUseVDTReport(dateFilter);
    
      StringBuilder sb = new StringBuilder();
      sb.AppendLine(string.Join(",", "Report Start = " + reportStart.ToString(), "Report End = " + reportEnd.ToString()));
      sb.AppendLine(string.Join(",", "Source", "PatientID", "Organization"));
      foreach (PatientActivity p in resultActivities)
      {
        sb.AppendLine(string.Join(",", p.Source, p.PatientId, p.OrganizationId)); // I am not hitting here 
    }
      
      // test code
      System.IO.File.WriteAllText(@"C:\PACSLogs\HealthVaultVDTReport.txt", sb.ToString());
    
      return sb.ToString();
     }

    Please advice me

    Thanks,

    Robert

    Wednesday, February 26, 2014 4:36 PM
  • Can you confirm that when you step through the code the appID is the child appID, and its the same between the following lines:

    HealthRecordAccessor accessor = new HealthRecordAccessor(HealthVaultConnectionManager.CreateConnection_applicationId, personId), recordId);

    AND

    OfflineWebApplicationConnection offlineConnection = HealthVaultConnectionManager.CreateConnection(appId);

    Between contributing the CCDA and querying for the report, make sure you visit the CCD view page in Shell to actually view/download the CCDA.

    Also, can you try taking the MU2 sample app and in the web.config specify the child appID and file location to a PFX file for the child app? This will allow you to use your child app ID with the sample app and compare where there might be an issue with your code. Similar to the above, make sure you view/download the CCDA before querying for the report.

    Ali

    Wednesday, February 26, 2014 7:32 PM
  • Hi Ali,

    I ensured the app id I passed is the child app id, as you mentioned and I also tested with the sample app by providing the child app ID and PFX and password.

    I could upload CCDA and I could view the CDA by logging in the healthVault ppe account (http://account.healthvault-ppe.com/). Unfortunately download is not working (page not found error is seen)

    And the GetVDTReport is returning empty list even in the sample app. (tested with my child app id).

    Kindly advice me what else I should be aware of.

    Thanks,

    Robert 


    Wednesday, February 26, 2014 8:19 PM
  • Does the eventTime you're specifying for the CCDA fall into the date range used to query the report?

    Also, there's a commented line where you used the CDA type instead of the CCD type id. Can you confirm you used the CCD type ID to contribute the CCDA and you performed a view in Shell after using this type ID?

    If those suggestions don't help, please reply with your child app ID as well as the recordID and personID used to contribute the CCDA.

    Wednesday, February 26, 2014 8:43 PM
  • Ali,

    I don't know what I changed, When I tested with the sample app today by provide the child Id and Pfx, surprisingly it works good.

    (immediately after I upload the CCDA, I am getting the result in the GetVDTReport(), even before viewing the document using the shell)- The result is the same if I upload the document of type CCD or CDA.

    But everything the same, when I tested with our regular application, the document uploaded and viewed are not reflected in the GetVDTReport list. But the list shows the events of upload I did using the sample app.

    I started comparing the code between the sample app and our implementation on the contribution of CCDA, the only difference I could find it in the usage of OfflineWebApplicationConnection

    Our way of connection:

    public static OfflineWebApplicationConnection CreateConnection(Guid applicationId,                                          Guid personId)
    {
       OfflineWebApplicationConnection offlineConn = new OfflineWebApplicationConnection(applicationId,               WebApplicationConfiguration.HealthServiceUrl, personId);
                offlineConn.Authenticate();
                return offlineConn;
    }

    Sample code way of connection:

    OfflineWebApplicationConnection connection = new OfflineWebApplicationConnection(pi.PersonId);

    But when I tried to connect using the way of sample code I get the following exception when I call accessor.NewItem(ccda);

    "The unique identifier f6d416f0-eb4e-4ea6-a2ab-15ea4dab831a for the person cannot be found."

    Please find the following details you requested.

    Person ID  {f6d416f0-eb4e-4ea6-a2ab-15ea4dab831a}
    Record ID  {091bdd00-7ad3-4e1a-8ca3-1262f53883eb}

    Master App ID {7e8f1836-ba6c-43b0-8e7f-784806b8d88e}

    Child App ID {de7a1359-0a72-4ed0-aa93-4cef17057265}

    I tested using both the type CCD and CDA. but now I understand from your suggestion that we need to set only CCD for MU. Am I right? 

    I believe I am close to resolve this issue of us.

    Thanks for all the support so far.

    Please suggest me further.

    Thanks,

    Robert


     

    Thursday, February 27, 2014 10:43 PM
  • Ali,

    Do you have any suggestions for me?

    Thanks,

    Robert

    Wednesday, March 5, 2014 4:52 PM
  • Robert,

    The error you're seeing:

    "The unique identifier f6d416f0-eb4e-4ea6-a2ab-15ea4dab831a for the person cannot be found."

    occurs when the person ID isn't recognized. Where are you getting the personID from in your code?

    Note that personIDs and recordIDs can't be shared between AppIDs. You will need to ensure that the the person / record ID combo is authorized for each application.

    Yes, you only need to use the CCD type.

    Ali

    Thursday, March 6, 2014 2:15 AM