Ashok Kumar T · Oct 6, 2023 go to post

Generally we can't execute the macros directly in terminal, studio output. The Macro preprocessor aka MPP do converts the marcos into the expression or function at the time of compilation. So, You can open and use the .int file for the specific code. 

Test.mac
macromac
 write$$$EnsMajorVersion; 
Test.int
macromac
 write$system.Version.GetMajor() ; 

Get the relevant value of macros and execute it in terminal or output window.

Ashok Kumar T · Oct 5, 2023 go to post

Hello @Colin Brough 

I Believe, There is no functional difference between rule 1 and rule 2 except the invoking the DTL twice and finally call the Target. By default it has the feature to call multiple targets once the transformation completed. You utilized the feature in rule 2. That's the exact way to call multiple target unless different message and different transformation required. There will be a performance difference should be there. Because it executes the DTL first every time and eventually call the targets asynchronously(Whether it's asynchronous or synchronous It depends on the configuration in production Business process).

Ashok Kumar T · Oct 5, 2023 go to post

xData block data's are basically stored the as a stream object in the class definition. If this is a property oriented then create a stream property %Stream.GlobalCharacter and store the values.

Ashok Kumar T · Oct 4, 2023 go to post

You can do $Name for the global and use your subscript runtime

set gbl= $NA(^ABC)
write @gbl@(1,2)
set sub=1write @gbl@(sub)
Ashok Kumar T · Oct 3, 2023 go to post

%GetSwizzleObject - is basically belongs from the %Persistent Class. The HS.FHIR.DTL.vR4.Model.Resource.Practitioner is extending from the %Library.RegisteredObject class. For the store error you can try increasing the process memory allocation programmatically to maximum by set $zstorage=-1 for the specific process.

Ashok Kumar T · Sep 27, 2023 go to post

Use string functions to get the values in your query. If your OBS_Value  value is already a list then you can take from query $listget(a) as No_Urut instead List(a) as No_Urut. Or if it's a string $PIECE((a,",",1) as No_Urut

Ashok Kumar T · Sep 26, 2023 go to post

Hi @RKumar

You need to set the properties SSLConfiguration and UseSTARTTLS for enabling SSL configuration

set smtp=##class(%Net.SMTP).%New()
set smtp.SSLConfiguration="TestSSL";your SSL configured name in System Management Portalset smtp.UseSTARTTLS=1/*
 ... Additional required property set
*/
Ashok Kumar T · Sep 25, 2023 go to post

The syntax of $$$LOGINFO won't allow you make it in multiple lines. Instead you can set it in local variable and pass the variable in LOGINFO for better visibility 

set log= "object: 'This is a try'"
    		_"this is the second line with an example parameter: "_$get(x,1)
    		_"this is the third line with an example parameter: "_$get(y,5)
    
$$$LOGINFO(log)
Ashok Kumar T · Sep 25, 2023 go to post

Hi @Lingnan Zhang 

You can use %File API class to create a directory. This result will be 1 if directory is created else 0. Refer the sample code below

set directory="c:\Test"write##class(%File).CreateDirectory(directory) ; result will be 1 if create else 0
Ashok Kumar T · Sep 23, 2023 go to post

I agree with Mr @Mihoko Iijima mentioned points. If Interoperability production need to be executed as part of the FHIR REST call configure HS.FHIRServer.Interop.Service this class in both Production and FHIR server configuration page. No need do it for using the direct Intersystems FHIRServer storage.

Ashok Kumar T · Sep 23, 2023 go to post

You need to pass the subscripts also part of the $NAME itself to make it dynamic instead start from the beginning

USER>s subscript="a" ;your dynamic subscript 
 
USER>set GlobalVar=$NAME(^["IRISMYDEV"]TEST(subscript)) ; pass the subscript into $NAME
 
USER>write GlobalVar
^["IRISMYDEV"]TEST("a")
USER>set sub="" write $o(@GlobalVar@(sub),1,data) ; next subscript of "a"
b
USER>write @GlobalVar
Test
USER>write GlobalVar
^["IRISMYDEV"]TEST("a")
Ashok Kumar T · Sep 22, 2023 go to post

You could add $char(13,10) or $$$NL ( this also refer $c(13,10) ) macro to make a new line

$$$LOGINFO("object: 'This is a try'"_$$$NL_"this is the second line with an example parameter: "_$get(x)_$$$NL_"this is the third line with an example parameter: "_$get(y))
Ashok Kumar T · Sep 22, 2023 go to post

Hi @Ryan Pflughaupt

You need to use the $NAME function set the global variable into local variable to process global names extended global reference dynamically. There is no problem with setting global name in local variable if it's belongs from the current namespace. Use indirection( @ )  operator to do $query,$order,$data string functions and get values from it(Suggest to use $NAME for current namespace global as well) . 

USER>set GlobalVar=$NAME(^["IRISMYDEV"]TEST)
 
USER>zwrite @GlobalVar
^["IRISMYDEV"]TEST("a")="Test"
^["IRISMYDEV"]TEST("a","b")="66739,34774"
^["IRISMYDEV"]TEST("a","b","c")="Apple\Orange-Peach#ball\1#0#1#1"

USER>set sub=$query(@GlobalVar) for  quit:sub=""  write sub,! set sub=$Query(@sub)
^["IRISMYDEV"]TEST("a")
^["IRISMYDEV"]TEST("a","b")
^["IRISMYDEV"]TEST("a","b","c")
 

by using this you can take the values. Check last global reference by using the $zreference function.

Ashok Kumar T · Sep 20, 2023 go to post

Have you tried to pass the provider as a host variable in the query

SELECT ID FROM TestTable WHERE ProviderName = :PROVIDER AND IDType= 'BPI'
Ashok Kumar T · Sep 20, 2023 go to post

Hello @Muhammad Waseem 

Maybe you can try extract the patient resource from bundle or use if it's already resource. Load into FHIR model patient class  HS.FHIR.DTL.vR4.Model.Resource.Patient with the extracted resource. Then you can convert the Birthdate and validate the Age. You can use the same logic in your code DTL in your FHIR process in between FHIR service (HS.FHIRServer.Interop.Service) to FHIR operation (HS.FHIRServer.Interop.Operation)

ClassMethod VaidatePatientResource(patientResourceStreram As%Stream.Object)
{
	#dim patient As HS.FHIR.DTL.vR4.Model.Resource.Patient
	try {
		set patient = ##class(HS.FHIR.DTL.vR4.Model.Resource.Patient).FromJSON(patientResourceStreram)
		Set age = $horolog - $ZdateH(patient.birthDate,3)\360if age<18$$$ThrowStatus($$$ERROR($$$GeneralError, "Age is less than 18"))
	}
	catch ex {
		w ex.DisplayString()
	}
}

Ashok Kumar T · Sep 20, 2023 go to post

Hello @Padmaja Konduru 

The certificate and private key is configured for the your SSL/TLS connection.  You can try  executing the below code to get some certificates of the certificate

I have attached my sample "test" SSL/TLS which is included the sample certificate and private key (x509)

Call the SSLDetails method with your SSL name. This method will return an local array with some basic details like expire date , subject and so on.  SSL configuration name was taken from the   System > Security Management > SSL/TLS Configurations 

/// Call this method with your ssl nameClassMethod SSLDetails(SSLName As%String = "") As%Status
{
	new$namespaceset$namespace="%SYS"set ssl=##class(Security.SSLConfigs).%OpenId("test")
	set privateKeyFile = ssl.CertificateFile
	set file = ##class(%FileCharacterStream).%New()
	do file.LinkToFile(privateKeyFile)
	set str=file.Read($$$MaxLocalLength)
	do..certificateDetails(str,.fields)
	zw fields
	return$$$OK
}

ClassMethod certificateDetails(str As%String, ByRef fields)
{
	#;getting some basic  detailsfor field="SerialNumber","Issuer","ValidityNotAfter","ValidityNotBefore","Subject","SubjectKeyIdentifier" {
		set fields(field) = $SYSTEM.Encryption.X509GetField(str,field)
	}
}

output

verify the local array fields("ValidityNotAfter") value for the expired date

IRISMYDEV>do ##class(Sample.NewClass1).SSLDetails("test")
fields("Issuer")="L=test,CN=test,O=test,ST=test,C=us"
fields("SerialNumber")=0
fields("Subject")="L=test,CN=test,O=test,ST=test,C=us"
fields("SubjectKeyIdentifier")=$c(144)_"¾&p"_$c(28)_"áÁZÀ"_$c(140)_"Ô4OÜ"_$c(24)_"º""=B"_$c(137)
fields("ValidityNotAfter")="2023-09-21 06:13:50"
fields("ValidityNotBefore")="2023-09-20 06:13:50"
 
Ashok Kumar T · Sep 19, 2023 go to post

Basically Summary Document Architecture aka SDA is an intersystems intermediary format to convert the HL7 Messages to FHIR or create an FHIR resource form custom data. vR4 is representing FHIR version.

So I guess. You may need to upgrade the instance to get vR4 packages

Ashok Kumar T · Sep 19, 2023 go to post

Hello @Michael Wood,

The line property is actually a list of string in address object property. So You should use direct Insert action instead of Set for that property when doing mapping in DTL for single values. If it's list/collection the you should foreach the list property and insert the values to the line() property. Refer the screenshots below for both scenarios.

Direct single Insert

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='CSVtoHL7.Inputfile.Record' targetClass='HS.FHIR.DTL.vR4.Model.Resource.Location' create='new' language='objectscript' >
<assign value='source.FirstName' property='target.address.line' action='insert' key='1' />
</transform>
}

List 

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='CSVtoHL7.Inputfile.Record' targetClass='HS.FHIR.DTL.vR4.Model.Resource.Location' create='new' language='objectscript' >
<foreach property='source.AddressLine()' key='k1' >
<assign value='source.AddressLine.(k1)' property='target.address.line' action='insert' key='k1' />
</foreach>
</transform>
}

result

Ashok Kumar T · Sep 19, 2023 go to post

Hello @Jimmy Christian 

You can use the foreach element instead of code block if it's direct set to target and no code logic required. I have attached the sample codes below.  You can refer mr. @Sylvain Guilbaud samples as well.

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='CSVtoHL7.Inputfile.Record' targetClass='CSVtoHL7.Test.NewClass2' targetDocType='2.5:ADT_A01' create='new' language='objectscript' >
<foreach property='source.EmailList()' key='k1' >
<assign value='source.EmailList.(k1)' property='target.ListOfEmails.(k1)' action='set' />
</foreach>
</transform>
}

DTL

output

Ashok Kumar T · Sep 18, 2023 go to post

You can use code block in DTL to write the iterate code fo the list or general loop iteration 

for item=1,3,4,5/// code 
}
Ashok Kumar T · Sep 15, 2023 go to post

You can add sql from the add action and place your embedded sql query and get the values in host variable. Then set the sql return value to the field directly like below.

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='EnsLib.HL7.Message' targetClass='EnsLib.HL7.Message' sourceDocType='2.3.1:ADT_A01' targetDocType='2.3.1:ADT_A01' create='new' language='objectscript' >
<assign value='source.{PV1:SetIDPV1}' property='target.{PV1:SetIDPV1}' action='set' disabled='1' />
<sql>
<![CDATA[ select count(id) INTO :value from Sample.Person]]></sql>
<assign value='value' property='target.{PV1:AdmissionType}' action='set' />
</transform>
}
Ashok Kumar T · Sep 12, 2023 go to post

May be you can try to take a clone of the object by %ConstructClone() I know it increments the reference count. However you can keep the old object for validation.