Found my issue, I had the execute query command in the code twice. Found that and resolved the issue.
- Log in to post comments
Found my issue, I had the execute query command in the code twice. Found that and resolved the issue.
this might help. How to create a business service for reading JSON input into the Ensemble (intersystems.com)
got it to work, but there might be a better solution, if so, please comment
ClassMethod EditSurgery() As %Status
{
S EditData={}.%FromJSON(%request.Content)
w !,EditData.SurgeryCase,!
#Dim otherProc As %DynamicObject
s otherProc=EditData.OtherProcedures
s iterator=otherProc.%GetIterator()
while iterator.%GetNext(.key, .OtherProcedure) {
set type = otherProc.%GetTypeOf(key)
s name=otherProc.%Get(key).OtherProcedure
s cpt=otherProc.%Get(key).PlannedOtherProcCPTCode
s comment=otherProc.%Get(key).ProcedureCodeComments
w !," name= ",name," cpt= ",cpt," comments= ",comment
}
q 200
}
OtherProcedures is a dynamic abstract object. I parse it out of the main JSON message. In the class definition for the JSON message:
Property OtherProcedures As list Of OtherProcedures;
Class REST.SwitchLane.Periopt.OtherProcedures Extends (%JSON.Adaptor, %Persistent)
{
Property OtherProcedure As %String;
Property PlannedOtherProcCPTCode As %String;
Property ProcedureCodeComments As %String;
}
Sorry, got pulled away before I finished the post to add my code. This code is a REST API. The pInput is the JSON message in the original post. this code does write out the key and type but I need to get the values for each procedure. Not sure how to get that data.
ClassMethod fileSurgery1(pInput As REST.SwitchLane.Periopt.SurgeryData, Output pOutput As %String) As %Status
#Dim obj As %DynamicAbstractObject
s obj =pInput.OtherProcedures
s iterator = obj.%GetIterator()
while iterator.%GetNext(.key, .value)
{
set type = obj.%GetTypeOf(key)
write !,"key= ",key,!,"Type= ",type
}
q 200
I created classes to define my JSON message. Then used a transform to transform HL7 to JSON and JSON to HL7
Thanks. I need this to help build an export. Is there a way to filter a class namespace? Or is that something I would need to add?
This fixed it. Thanks Ashok.
code is in my last reply
this is the class:
Class REST.Test.Sample.AllItems Extends (%JSON.Adaptor, Ens.Response)
{ Property ItemtId As %String;
Property itemName As %String(MAXLEN = 100);
Property itemStockNumber As %String(MAXLEN = 150);
Property itemType As %String;
Property itemPriority As %String;
Property itemDetailData As %String(MAXLEN = 10000);
}
ClassMethod getItemData() As %Status [ PublicList = (U, ItemDetails, RESULTS) ]
{
Set tSC = $$$OK
s results=""
s AllItems=##class(REST.Test.Sample.ItemDetails).%New()
S (STATUS,XX)=0 F S STATUS=$O(^GMR(123,"D",STATUS)) Q:STATUS'>0 f s XX=$O(^GMR(123,"D",STATUS,XX)) Q:XX'>0 d
.s CONERR=""
.d GETS^DIQ(123,XX,"*","IE","ItemDetails","CONERR")
.Q:"5,6"'[STATUS
.Q:$P(^GMR(123,XX,0),"^",5)'=9
.s Item=..%New()
.s Item.ItemId=XX
.s CONID=XX_","
.s itemId=$g(ItemDetails(123,CONID,.02,"I"))
.s ien=XX_","
.s Item.ItemName=$g(ItemDetails(123,CONID,.02,"E"))
.s Item.itemStockNumber=$G(ItemDetails(123,CONID,10,"I"))
.s Item.itemType=$G(ItemDetails(123,CONID,10,"I"))
.s Item.itemPriorty=$G(ItemDetails(123,CONID,11,"I"))
.S X2=0 F S X2=$O(ItemDetails(123,CONID,20,X2)) q:X2'>0 D
..s results=$g(results)_"|"_ItemDetails(123,CONID,20,X2)
..s Item.ItemData=$g(results)
.;d Item.Consult.SetAt(XX,XX)
.s AllItems.ItemId=XX
.d AllItems.Item.SetAt(Item.ItemName,"ItemName")
d AllItems.%JSONExport()
q 200
I set the parameter and am still not see the list of the items. in my code, I am looping thru the table and when I find an item that needs to be added to the JSON message, I set the properties in the AllItems JSON message then I am trying to add the data from that object to the ItemDetails object so the ItemDetails has all the table entries that are in the AllItems object.
so I collect and build the AllItems object for each table entry and then want to put all the AllItems data into the ItemDetails and return this JSON to the user.
just discovered that it will always create the new class in the USER namespace and I can't change the name of the new class. Is there a way to resolve this?
Thanks David, that worked.
Thanks Muni Ganesh, this is just what I was looking for.
take a look at this post from last week or the week before: https://community.intersystems.com/post/how-create-business-service-rea…
Class TMP.AppointmentReqMsg Extends Ens.Request
{// ProcessingFlag property is used to determine if the appt is for Cerner, Cerner and VistA or just VistA.// This flag is used by the BPProperty ProcessingFlag As %String;Property MessageId As %String;Property ControlId As %String;Property LogicAppRunId As %String(MAXLEN = 150);Property AppointmentID As %String(MAXLEN = 150);Property AppointmentType As %String;Property StartTime As %String;Property Duration As %String;Property VisitStatus As %String;Property CancelCode As %String;Property CancelReason As %String;Property CancelRemarks As %String(MAXLEN = 160);Property ClinicallyIndicatedDate As %String;Property Comments As %String(MAXLEN = 160);Property VvdUrl As %String(MAXLEN = 500);Property SchedulerInfo As array Of SchedulerInfo;Property PatientInfo As TMP.PatientInfo;Property ProviderFacility As %String;Property PatientFacility As %String;// Property PatientResources As list Of AppointmentResources;Property PatientResources As TMP.AppointmentResources;Property ProviderResources As TMP.AppointmentResources;
this is one of my classes to define a JSON message
***Disclaminer, I consider myself to be a fairly new Cache Objectscript developer. If any developers with more experience have suggestions for how to do this easier, more efficient, etc. Please share. I am eager to learn more that will help me in the future. :)
I have done this in the past, I created a business service with the EnsLib.HTTP.InboundAdapter to receive the JSON message on a REST end point. I also created a class for the JSON message structure. In the business service, I receive the JSON message and pass it to a business operation. In the business operation I have a transform that transforms the JSON to HL7 message, then the business process passes the HL7 message to a business operation to send to a new HL7 end point. This code was created in Ensemble 2017. If you are using IRIS, there are more classes for JSON message handling you might be able to use.
My business service handles several different JSON messages, this is the one of the methods I have for one of the messages. In the method I convert the JSON object that was received into a new object of type TMP.AppointmentReqMsg. TMP.AppointmentReqMsg is the class that defines the JSON message structure.
The new JSON object is passed to a business process to process the message. In the business process, I have a transform that transforms the JSON object to HL7. Then the business process will call the business operation that sends the HL7 message on to an HL7 end point.
Hope this helps.
Method appointmentAction1(pInput As %Library.AbstractStream, Output pOutput As %Stream.Object, pAppointment As %Stream.Object) As %Status
{ $$$LOGWARNING("In processing appointments") #dim ApptArray As %List
#dim tSC,tSC1,tSC2 As %Status = $$$OK #dim processingFlag As %String
#dim patientFacility As %String
#dim providerFacility As %String
#dim pFlag,provFlag,patFlag AS %Numeric = 0
d pInput.Rewind()
s pJSON=pInput.Read() set sc=##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(pJSON,"TMP.AppointmentReqMsg",.pRequestBody,1)
s:##class(Ens.Util.FunctionSet).Lookup("CernerSites",pRequestBody.ProviderFacility)>0 provFlag=1
S:##class(Ens.Util.FunctionSet).Lookup("CernerSites",pRequestBody.PatientFacility)>0 patFlag=1
s pFlag=provFlag+patFlag ;pFlag=0;VistA only, pFlag=2;Cerner only, pFlag=1;Cerner and VistA
s pRequestBody.ProcessingFlag=(provFlag+patFlag)
$$$LOGWARNING("checking json")
s:##class(Ens.Util.FunctionSet).Lookup("CernerSites",pRequestBody.PatientResources.Facility)'>0 tSC2 = ..checkJSON(pRequestBody.PatientResources.Resources)
$$$LOGWARNING("checking json returned "_tSC2)
i $p(tSC2,"^",1)=2 s tSC=..ReturnJSONAckMsg(.pRequestBody,tSC2)
q:$p(tSC2,"^",1)=2 200
s:##class(Ens.Util.FunctionSet).Lookup("CernerSites",pRequestBody.ProviderResources.Facility)'>0 tSC2 = ..checkJSON(pRequestBody.ProviderResources.Resources)
$$$LOGWARNING("checking json returned "_tSC2)
i $p(tSC2,"^",1)=2 s tSC=..ReturnJSONAckMsg(.pRequestBody,tSC2)
q:$p(tSC2,"^",1)=2 200
s badResponse=##class(AppointmentResponseMsg).%New()
s badResponse.ControlId = pRequestBody.ControlId
s badResponse.MessageId = pRequestBody.MessageId
s badResponse.OrganizationName = "CVT15"
s badResponse.Status="AA"
s badResponse.FailureReason=""
if +$L(patientFacility)>0
{
s VistABO=##class(Ens.Util.FunctionSet).Lookup("TMP_VistA_Systems",patientFacility),^zzphil("p1")=VistABO
s:$g(VistABO)="" badResponse.FailureReason="Patient Site is not configured in HealthConnect"
}
if $L(providerFacility)>0
{
s VistABO1=##class(Ens.Util.FunctionSet).Lookup("TMP_VistA_Systems",providerFacility)
s:##class(Ens.Util.FunctionSet).Lookup("CernerSites",providerFacility)>0 provprocessingFlag="Cerner"
s:$g(VistABO1)="" badResponse.FailureReason="Provider Site is not configured in HealthConnect"
}
if badResponse.FailureReason'=""
{
set tSC=..SendRequestSync("ProcessBadApptRequest",.badResponse,.pResponse) Quit:$$$ISERR(tSC)
}
else
{
if pFlag=0
{
s tSC1 = ..SendRequestSync("ProcessVistAAppointments",.pRequestBody,.pResponse)
}
if pFlag=1
{
s tSC1 = ..SendRequestSync("ProcessCernerAndVistAAppointments",.pRequestBody,.pResponse)
}
if pFlag=2
{
s tSC1 = ..SendRequestSync("ProcessCernerOnlyAppointments",.pRequestBody,.pResponse)
} }
Quit tSC1
}
I created a class for the JSON message and then used a data transformation in Ensemble/IRIS to transform the JSON message to an HL7 message.
Thanks David. Giving this a try.
you can define a message class for your JSON message. then set up your transform to transform the data from the HL7 message to the JSON message. then in your business process use the built in SQL commands to store the JSON string in SQL Server.
Thanks for the help Vic, Ben and Evgeny,
You have provide some good information and I am going to try both the Project in Studio deployment and also try the Ens.Deployment,Utils to see which one works best for our needs.
Thanks Evgeny,
Not sure if that ZPM Package Manager is available on the version of Ensemble our client is running. They are not ready to upgrade to IRIS on this project yet. But I will take a look at it. Never know when I might need it in the future.
Thanks Vic, the problem is we are one of two teams updating the production. Fortunately, both teams are working in separate efforts and are not working in the same classes in the production. The work our team is doing is creating new business services, process and operations and message classes. but the deployment happens by another team so I am looking to create a simple deployment package they would run to add our new components to the production. I am trying not to have to write a step by step deployment guide that tells them to create this business service with this class, this business process with this bpl, etc.
Thanks Vic and Ben. it looks like what you and Ben Spead are saying is to build a new project that contains just my code to be deployed and then use the Ens.Deployment.Utils class to deploy that project. But does it set up the business operations, services and processes in the production so that they don't have to be set up and configured manually to use the classes? Trying to make it as simple and automated as possible.