Ashok Kumar T · Jul 4, 2024 go to post

Hello @Sylvie Greverend

The sample swagger for produces "image/jpeg" and consumes "application/json" and "application/xml" for sample. Once the spec.cls. Once it's complied it creates a "DownloadImg" classmethod in .disp.cls

swagger

{
	"swagger": "2.0",
	"info": {
		"title": "test",
		"version": "1.0.0"
	},
	"paths": {
		"/Test": {
			"get": {
				"summary": "Test download",
				"operationId": "DownloadImg",
				"produces": [
					"image/jpeg"
				],
				"consumes": [
					"application/json",
					"application/xml"
				]
			}
		}
	}
}

Generated class method

ClassMethod DownloadImg() As%Status
{
    Try {
        Do##class(%REST.Impl).%SetContentType("image/jpeg")
        If '##class(%REST.Impl).%CheckAccepts("image/jpeg") {
            Try {
                Do##class(MyLearn.LearnREST.Swag.impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts))
            } Catch {
                Do##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts))
            }
            Quit
        }
        Set response=##class(MyLearn.LearnREST.Swag.impl).DownloadImg()
        Do##class(MyLearn.LearnREST.Swag.impl).%WriteResponse(response)
    } Catch (ex) {
        Try {
            Do##class(MyLearn.LearnREST.Swag.impl).%ReportRESTError(..#HTTP500INTERNALSERVERERROR,ex.AsStatus(),$parameter("MyLearn.LearnREST.Swag.impl","ExposeServerExceptions"))
        } Catch {
            Do##class(%REST.Impl).%ReportRESTError(..#HTTP500INTERNALSERVERERROR,ex.AsStatus(),$parameter("MyLearn.LearnREST.Swag.impl","ExposeServerExceptions"))
        }
    }
    Quit$$$OK
}

Some useful links 

HTH.

Ashok Kumar T · May 29, 2024 go to post

Hello @Scott Roth 

Did you get a chance to check the ^ISCLOG global for Http request logging. Because configuration done int ^%ISCLOG and logging was written in ^ISCLOG

^FSLOG for internal FHIR server logging 

Thanks!

Ashok Kumar T · May 1, 2024 go to post

I don't have any granular level samples right now. Generally speaking, it depends on our code implementation how we get the payload data from the system/upstream stream. There are certain validation based on the requirements. So, I hope there is no general mapping to convert our information into SDA. 

Thanks!

Ashok Kumar T · Apr 25, 2024 go to post

Hello @isabella Barnes 

I'd create some custom container. Check, modify and validate all the fields in payload by using some additional DTL's and Code from the and mapped into the custom container. Then I created a DTL mapping and map the custom container with the InterSystems intermediary format HS.SAD3.Container 

Finally use the container object to generate the FHIR resource.

/// custom conatiner classClass Test.project.CustomContainer Extends (Ens.Request, %JSON.Adaptor)
{

/// (Custom Persistent class with HS.SDA3.Medication)Property Medication As Medication;Property Procedure As Procedure;/// (Custom Persistent class with HS.SDA3.Procedure)Property Referral As Referral;/// (Custom Persistent class with HS.SDA3.Referral)Property Appointment As Appointment;/// (Custom Persistent class with HS.SDA3.Appointment)Property Immunization As Immunization;/// (Custom Persistent class with HS.SDA3.Vaccination)Property Diagnosis As Diagnosis;/// (Custom Persistent class with HS.SDA3.Diagnosis)
    
}

/// additional support classClass Test.project.Medication Extends (Ens.Request, %JSON.Adaptor)
{

/// Add your fields/// Property Context As%String(MAXLEN = 250);/// Relevant to Medication Requests, this represents whether a  request is a proposal, /// plan, or an original order./// VIEWERLIB: Not storedProperty RequestIntent As HS.SDA3.CodeTableDetail.MedicationRequestIntent;/// Indicates if this record was captured as a secondary 'reported' record rather than /// as an original primary source-of-truth record. /// VIEWERLIB: Not storedProperty IsReported As HS.SDA3.Boolean;/// etc........

}
Class Test.project.Procedure Extends (Ens.Request, %JSON.Adaptor)
{

/// Add your fields/// Property EnteredOn As HS.SDA3.TimeStamp;/// HL7:  PR1-19.1 : ProcedureIdentifier.EntityIdentifier<br>/// VIEWERLIB: User.HS.MRProcedures(PROCExternalId)Property ExternalId As%String(MAXLEN = 220);/// etc........
}

DTL Mapping

Class Test.project.DTL.CustomToFHIRMapping Extends Ens.DataTransformDTL [ DependsOn = (Test.project.CustomContainer, HS.SDA3.Container) ]
{

Parameter IGNOREMISSINGSOURCE = 1;Parameter REPORTERRORS = 1;Parameter TREATEMPTYREPEATINGFIELDASNULL = 0;

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='Test.project.CustomContainer' targetClass='HS.SDA3.Container' create='new' language='objectscript' >
<assign value='source.Medication' property='target.Medications.(1)' action='set' />
<assign value='source.Procedure' property='target.Procedures.(1)' action='set' />
<assign value='source.Referral' property='target.Referrals.(1)' action='set' />
<assign value='source.Appointment' property='target.Appointments.(1)' action='set' />
<assign value='source.Diagnosis' property='target.Diagnoses.(1)' action='set' />
</transform>
}

}

screenshot of DTL

This is how I approach the conversion.

Thanks!

Ashok Kumar T · Apr 13, 2024 go to post

Hello @Parameshwaran Muthaiyan 

The current approach you have implemented is the exact approach. because, You have to execute the query every time if we are modify the conditional values. Otherwise the results will remine the same.

Ashok Kumar T · Feb 6, 2024 go to post

Usually you will get a serialization JSON (string)  in result. You can do deserialization by using %DynamicObject.

Ashok Kumar T · Feb 4, 2024 go to post

Hi @Pierre LaFay 

Define a Method instead of  ClassMethod and Instantiate the object for that class and call the required method. It will work

Class Bna.Utils.Sql Extends%RegisteredObject
{

ClassMethod RemoveIrisTestUsers() As%Status
{
    set obj = ..%New()
    New$NameSpaceSet$NameSpace="%SYS"// Get test users by login beginingSet query = "select * from Security.Users "_
                "where "_
                    "ID like LOWER('ARS%') or"_
                    "ID like LOWER('CHERCHEUR%') or"_
                    "ID like LOWER('CS%') or"_
                    "ID like LOWER('DGOS%') or"_
                    "ID like LOWER('CENTRE%')"Set sc =obj.SelectFirstColsInArray(query, .userIds)
    if 'sc Return sc
    zw userIds

    Return$$$OK
}

Method SelectFirstColsInArray(query, test)
{
    zwrite query,test
    return$$$OK
}

}
Ashok Kumar T · Jan 26, 2024 go to post

Useful SQL JSON functions. I would like to include one more Aggregate function SQL JSON_ARRAYAGG into this list.

Create JSON object and push into JSON array based on condition or entire rows

select JSON_ARRAYAGG(JSON_OBJECT('Id':Id,'Name':Name,'phoneNumber':Phone,'State':state)) As JSON from Sample.Person

Ashok Kumar T · Jan 24, 2024 go to post

Thanks @Julius Kavay ,

Ok. Yes, both global and private global storage at the first time of initialization.  Why does it consumes minimum 8 byte(seems default and Is this Default byte size) regardless of single character(1 byte) in $storage. It consumes same or more than same byte when store in to global. Is this actual physical storage size(bytes) for the global.

 LEARNING>Set^TEST="a"
 LEARNING>d^%GSIZE
Global ^TEST
directory: c:\intersystems\irishealth\mgr\learning\
Page: 1                           GLOBAL SIZE                        24 Jan 202411:26 AM
      Global        Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------
      TEST               1120 %         0
      TOTAL         Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------
                         1120 %         0
                                        <RETURN> to continue or '^' to STOP:
Ashok Kumar T · Jan 21, 2024 go to post

Hello @Andy Stobirski 

Have you created a web application? If not, You have to create a web application. Configure the necessary details such as namespace, url add your PCRest.disp in dispatch class and assign roles. Save the application and call your RESTFul api from postman.

/// Says HelloClassMethod Hello() As%Stream.Object
{
	return {"status":"ok","message":"working"}
}

Ashok Kumar T · Jan 21, 2024 go to post

Hello @Andy Stobirski 

The property "swagger" is an mandatory field and the value  should be string value "2.0" not even integer 2 or anything other than "2.0". If you defined the mandatory fields then it should work.

Ashok Kumar T · Dec 22, 2023 go to post

Yes Of course, We can store the object id's directly to the list of object property by using ( ex: $lb($lb("1"),$lb("2")) )  it. However we stored the values through objects. Basically the basic behaviour of storing the primary object automatically stores it's reference objects by default(DeepSave).So, I don't need to save multiple objects manually. Eventually it revokes both primary and reference object in failure state. No transactions involved in the code logic. If I save the secondary objects before storing the primary creates discrepancy in my data, Incase of failure. I thought to implement the same flow via SQL if possible.