Hapi Fhir query with AND / OR with map - hapi-fhir

Using Hapi Fhir, I try to write a query to use a map to pass in where condition, as follow:
Map<String, List<IQueryParameterType>> hmParameter = criteria.getMapForWhere();
Bundle bundle = fhirClientR4Configuration.clientFhihrR4().search().forResource(ServiceRequest.class)
.where(hmParameter).returnBundle(Bundle.class).execute();
My criteria object has a method getMapForWhere() where I populate this map with information inside my wrapper front end object as follow:
public Map<String, List<IQueryParameterType>> getMapForWhere() {
Map<String, List<IQueryParameterType>> hmOut = new HashMap<String, List<IQueryParameterType>>();
// Adding STATUS
if (this.status != null && !this.status.equals("")) {
StringParam sp = new StringParam();
sp.setValue(this.status);
List<IQueryParameterType> lst = new ArrayList<IQueryParameterType>();
lst.add(sp);
hmOut.put(ServiceRequest.SP_STATUS, lst);
}
// Adding INTENT
if (this.intent != null && !this.intent.equals("")) {
StringParam sp = new StringParam();
sp.setValue(this.intent);
List<IQueryParameterType> lst = new ArrayList<IQueryParameterType>();
lst.add(sp);
hmOut.put(ServiceRequest.SP_INTENT, lst);
}
return hmOut;
}
This code works fine when I want to wirte a query with all AND.
But if I want to add another condition as follow:
List<IQueryParameterOr> lstOr = new ArrayList<IQueryParameterOr>();
StringOrListParam lstServices = new StringOrListParam();
StringParam sp = new StringParam();
StringParam sg = new StringParam();
sp.setValue(MEDICAL_SERVICE_PAI);
sg.setValue(SOCIAL_SERVICE_PAI);
lstServices.addOr(sp);
lstServices.addOr(sg);
lstOr.add(lstServices);
hmOut.put(ServiceRequest.SP_CATEGORY, lstOr);
Obviously hmOut goes in error because definition of that map is different. But I don't know how to convert IParameterOr with IParameterType.

Related

How to iterate over two Maps in Apex?

In salesforce Apex, I have a below String and facing issues how we can iterate over two maps at a time ?? Can somebody please guide me ... how we can do this ?
String values = 'Auth Group:true,HR Group:false';
Auth Group:true,HR Group:false
I have two Maps
// Map of GroupId and GroupName
Map<Id, String> mapGrpIdAndName = new Map<Id, String>();
mapGrpIdAndName.put('Auth Group','111');
mapGrpIdAndName.put('HR Group','222');
// Map of GroupName and Indicator
Map<String, String> mapGrpNameAndIndicator = new Map<String, String>();
mapGrpNameAndIndicator.put('Auth Group','false');
mapGrpNameAndIndicator.put('HR Group','true');
Assume I am in for loop of case already
for(payment_2__c mysi2 : newSI2){
Boolean f_indicator = // True or False ==> This value is dynamic........
if(caseMap.get(mysi2.Case__c).RecordType.DeveloperName != 'ELC_DraftCase'){
if(caseMap.get(mysi2.Case__c).OwnerId != mysi2.OwnerId){
if(caseMap.get(mysi2.Case__c).RecordType.DeveloperName == 'AAA_HR'){
for(Id grpId : mapGrpIdAndName.keySet()){
//// HERE I need to check dynamicallt if value of
/// if f_indicator == false and Auth Group == false, then only give apex sharing
// How to iterate over two map at a time ???????
////
ELC_Service_Information_2__Share gsiShare2 = new ELC_Service_Information_2__Share();
gsiShare2.ParentId = mysi2.Id;
gsiShare2.RowCause = 'Manual';
gsiShare2.AccessLevel = 'Edit';
gsiShare2.UserOrGroupId = grpId;
si_2ShareList.add(gsiShare2);
}
}
}
}
}
Does this compile? Your first Map (mapGrpIdAndName) is instantiated to store an Id and a String; however, you are storing two Strings in it.
Also, if you are looping through the cases already, you don't need to be retrieving the values from caseMap.
It's difficult to understand why you are creating a map only to store two true/false values. I guess you're omitting the real code so we don't use it.
This is how you can do it without looping through the second map:
for(Id grpId : mapGrpIdAndName.keySet()){
if(f_indicator == false && mapGrpNameAndIndicator.get(mapGrpIdAndName.get(grpId)) == 'false'){
//do whatever
}
}
Since Group is an sObject, you can use something like this instead:
Map<Id, Group> mpGroups = new Map<Id, Group>([SELECT Id, Name FROM Group]);
for(Id grpId : mpGroups.keySet()){
if(f_indicator == false && mpGroups.get(grpId).Indicator__c == 'false'){
//do whatever
}
}
Or:
Map<Id, Group> mpGroups = new Map<Id, Group>([SELECT Id, Name FROM Group]);
for(Group grp : mpGroups.values()){
if(f_indicator == false && grp.Indicator__c == 'false'){
//do whatever
}
}

How to get a Fact creating BRL in Guvnor and querying Drools Server

I'm stuck with BRL rules in Guvnor.. I'm trying to execute rules from my application using Drools Server (this solution because in production I can use more server and maybe improve performance.. Not sure about this as it's the first time that in my company we are using Drools)..
So basically the rule is .. Given an object Route setting the property "selectedOutboundJourney" that I uploaded in guvnor in a jar, I'd like to get another object with the property "selectedReturnJourney" set.. (but Is it possible to get the same object??)
Actually I get a Route object where the selectedReturnJourney is null.
I'm not sure if using BRL is a good solution given the troubles that I'm having.. It seems easy to use for non technical people that may want to change the rules or creating new ones.
Anyway..
This is the BRL that I created in Guvnor:
rule "Selected Return for Dover - Calais"
dialect "mvel"
when
Route( selectedOutboundJourney == "DOCA" )
then
Route fact0 = new Route();
fact0.setSelectedReturnJourney( "CADO" );
insertLogical( fact0 );
end
This is the code I'm using:
final List<Command> commands = new ArrayList<Command>();
final Command insertObjectCommand = CommandFactory.newInsert(input, RESULT, true, "default");
final Command getObjectCommand = CommandFactory.newGetObjects();
final Command fireAllRulesCommand = CommandFactory.newFireAllRules();
commands.add(insertObjectCommand);
commands.add(getObjectCommand);
commands.add(fireAllRulesCommand);
final ExecutionResults executionResults = droolsHttpClient.callDroolsServer(commands);
return executionResults.getValue(RESULT);
The class DroolsHttpClient is:
public ExecutionResults callDroolsServer(final List<Command> commands) throws DroolsException
{
PostMethod postMethod = null;
try
{
final HttpClient httpClient = new HttpClient();
final String droolsServerHost = Config.getString(PoferriesrulesengineConstants.DROOLS_SERVER_HOST, "");
final int droolsServerPort = Config.getInt(PoferriesrulesengineConstants.DROOLS_SERVER_PORT, 0);
httpClient.getHostConfiguration().setHost(droolsServerHost, droolsServerPort);
final String droolsServerUrl = Config.getString(PoferriesrulesengineConstants.DROOLS_SERVER_URL, "");
postMethod = new PostMethod(droolsServerUrl);
final BatchExecutionCommand command = CommandFactory.newBatchExecution(commands, PoferriesrulesengineConstants.DROOLS_SESSION);
final XStream xStreamMarshaller = BatchExecutionHelper.newXStreamMarshaller();
final String xmlCommand = xStreamMarshaller.toXML(command);
final StringRequestEntity request = new StringRequestEntity(xmlCommand, MediaType.TEXT_PLAIN_VALUE, CharEncoding.UTF_8);
postMethod.setRequestEntity(request);
httpClient.executeMethod(postMethod);
if (postMethod.getStatusCode() != 200)
{
throw new RuntimeException("Drools Communication Error, code: " + postMethod.getStatusCode());
}
final String response = postMethod.getResponseBodyAsString();
final ExecutionResults executionResults = (ExecutionResults) xStreamMarshaller.fromXML(response);
return executionResults;
}
catch (final Exception e)
{
throw new DroolsException(e.getMessage());
}
finally
{
postMethod.releaseConnection();
}
}
If I use a DRL like below it words perfectly without using the getObjectCommand:
rule "Selected Return Routes for Dover Calais"
when
r : Route(selectedOutboundJourney == "DOCA")
then
r.setSelectedReturnJourney("CADO")
end
Can anyone help me out, please?
Assuming you only have one fact in your Knowledge Session at the start, after the execution of the following rule
rule "Selected Return for Dover - Calais"
dialect "mvel"
when
Route( selectedOutboundJourney == "DOCA" )
then
Route fact0 = new Route()
fact0.setSelectedReturnJourney( "CADO" )
insert( fact0 )
end
you will have two Route facts in your session, since you just have inserted the second one.
Route: selectedOutboundJourney = "DOCA", selectedReturnJourney=null
Route: selectedOutboundJourney = null, selectedReturnJourney="DACO"
If you want to modify the original fact use the following rule:
rule "Selected Return Routes for Dover Calais"
when
$r : Route(selectedOutboundJourney == "DOCA")
then
modify ($r) {
selectedReturnJourney = "CADO"
}
end

salesforce mobile sdk create related object

I have Sample_Product__c custom object, and wanted to create object with relational field's external id:
final Map<String, Object> prod = new HashMap<String, Object>();
prod.put("External_ID__c", obj.getString("medicineName"));
final Map < String, Object > sample = new HashMap < String, Object > ();
sample.put("Product__r", prod);
sample.put("LotNumber__c", obj.getString("medicineSerialNo"));
sample.put("GivenDate__c", format.format(givenDate));
sample.put("ExpiredDate__c", format.format(expireDate));
sample.put("GivenNumber__c", obj.getString("medicineQuantity"));
sample.put("Call__c", callid);
RestRequest.getRequestForCreate(getString(R.string.api_version), "Sample_Product__c", sample);
This gives error as, Product__r should be SObject...
In PHP, I was doing this like so:
$sfobject = new stdclass();
$sfobject->External_ID__c = "...";
$sample->Product__r = $sfobject;
But have no idea how to achieve this with salesforce mobile SDK... hope someone knows, thanks!

How to force the Plugin on Post-Operation to Submit?

I have a plugin in post-operation witch need to create a folder on sharepoint via webservice, to do that, my plugin calls a webservice to execute a FechXML to get the info from the entity, but the problem is that entity still not exist, and it give me Null.
How do i force the plugin to submit/save the data to my FechXml to work?
PLUGIN CODE:
try
{
Entity entity;
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName != "fcg_processos")
{
throw new InvalidPluginExecutionException("Ocorreu um erro no PlugIn Create Folder.");
}
}
else
{
throw new InvalidPluginExecutionException("Ocorreu um erro no PlugIn Create Folder.");
}
processosid = (Guid)((Entity)context.InputParameters["Target"])["fcg_processosid"];
string processoid2 = processosid.ToString();
PluginSharepointProcessos.ServiceReference.PrxActivityResult result = log.CreateFolderSP("Processo", processoid2);
string resultado = result.xmlContent;
if (result.retCode > 0)
{
throw new InvalidPluginExecutionException("Ocorreu um erro na criação do Folder do Processo.");
}
WEBSERVICE CODE:
{
//WEBSERVICE TO CALL XML FROM ENTITY
PrxActivityResult Processo = ProcessoFetch2("", "", guid);
string stxml;
stxml = Processo.XmlContent;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(stxml);
XmlNodeList nodeList = xmlDoc.SelectNodes("resultset/result");
List<string[]> lista = new List<string[]>();
string[] strs = new string[7];
if (nodeList.Count != 0)//verificar o numero de registos
{
foreach (XmlNode xmlnode in nodeList)
{
if (xmlnode.SelectSingleNode("//fcg_numero") != null)
strs[2] = xmlnode.SelectSingleNode("//fcg_numero").InnerText;
else
strs[2] = "";
if (xmlnode.SelectSingleNode("//Concurso.fcg_numero") != null)
strs[3] = xmlnode.SelectSingleNode("//Concurso.fcg_numero").InnerText;
else
strs[3] = "";
}
}
IwsspClient FmwSharepoint = new IwsspClient();
PrxActivityResult folderresult = new PrxActivityResult();
List<ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave> arrayfields = new List<ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave>();
ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave nprocesso = new ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave();
nprocesso.Key = "FCG_Numero_Processo";
nprocesso.value = strs[2];
arrayfields.Add(nprocesso);
ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave npconcurso = new ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave();
npconcurso.Key = "FCG_Numero_Concurso";
npconcurso.value = strs[3];
arrayfields.Add(npconcurso);
ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave npguid = new ws.fcg.sipp.svc.ServiceReferenceSharePoint.PareChave();
npguid.Key = "FCG_Guid_CRM";
npguid.value = guid;
arrayfields.Add(npguid);
folderresult = FmwSharepoint.CreateFolder("http://localhost/folder", "Processos", strs[2], arrayfields.ToArray());
res = folderresult;
}
When a plugin runs on the Post-Operation, it is still within the database transaction, and it hasn't actually been committed to the database. Any calls done with the service reference passed in as a part of the Plugin Context will be executed within the context on the database transaction and you will be able to retrieve the newly created/updated values. If you create a brand new OrganizationServiceProxy (Which I'm guessing is what you're doing), it will execute outside of the database transaction, and will not see the newly created / updated values.
As #AndyMeyers suggests in his comment (which really should be an answer IMHO), grabbing the data from the plugin context either via a pre/post image or the target is ideal since it eliminates another database call. If you're having to lookup records that may have been created by another plugin that fired earlier, you'll need to use the IOrganizationService that is included in the plugin context.
I had no option and I used this code to run webservice based on image and forget the FecthXml, as mentioned, i get all info from the Image on the post operation and send back to the WebService. Thanks, here is the code:
entity = (Entity)context.InputParameters["Target"];
concursid = (Guid)entity.Attributes["fcg_concursid"];
guid = concursid.ToString();
string npconcurs = (string)entity.Attributes["fcg_numer"];
nconcurs= npconcurs;
EntityReference nprograma = (EntityReference)entity.Attributes["fcg_unidadeorganica"];
program = nprogram.Name;
if (entity.LogicalName != "fcg_concurs")

Cannot create/update a Rally TestCaseResult with a reference to a specified TestSet

With Rally, I need to
Update a TestCaseResult with a new TestSet Ref.
OR
Create a new TestCaseResult by copying everything from a previous TestCaseResult and just changing the TestSet Ref.
I am trying to do the same through the Java REST toolkit from Rally. It uses the JSON REST API internally, it seems.
When I try to do this with CreateRequest or UpdateRequest, I get an error from the API "Could not set value for Test Set: null"
Is it not possible to update the TestSet of a TestCaseResult (whether existing or newly created)?
Here's some sample code I am using (showing create testcaseresult from existing by changing testset).
//get testcaseresult object
GetRequest tcrReq = new GetRequest("/testcaseresult/12345.js");
tcrReq.setFetch(new Fetch("FormattedID", "Name"));
GetResponse tcrResponse = restApi.get(tcrReq);
//update testcaseresult object with new testset
JsonObject tsRef = new JsonObject();
tsRef.addProperty("_ref", "https://rally1.rallydev.com/slm/webservice/1.39/testset/1029348.js");
tcrResponse.getObject().add("TestSet",tsRef);
tcrResponse.getObject().remove("_ref");
//Create API for new testcaseresult object
CreateRequest createRequest = new CreateRequest("testcaseresult", tcrResponse.getObject());
CreateResponse createResponse = restApi.create(createRequest);
if(createResponse.wasSuccessful()){
System.out.println(createResponse.getObject());
}else{
String[] ss = createResponse.getErrors();
for(int i=0; i<ss.length; i++){
System.out.println(ss[i]);
}
}
Can you please help to understand whether I am doing something wrong or is this a Rally limitation?
I believe the reason that you are getting the "Could not set value for Test Set: null" error message is that there is an "invisible" constraint on TestCaseResults whereby the TestCase to which they are associated must be scheduled into the TestSet of interest, before the TestCaseResult can be assigned that TestSet as an attribute.
Unfortunately, there's no TestSet attribute on TestCases, so you have to query the TestCases collection off of the TestSet, and then loop through that collection to check and see if the parent TestCase is a member of that collection. Once verified that the TestCase is in that TestSet's collection of TestCases, then you can proceed to successfully update a member TestCaseResult with that TestSet attribute of interest. I tested the below and it works as expected.
Here's a code snippet illustrating how to accomplish this:
// Create and configure a new instance of RallyRestApi
// Connection parameters
String rallyURL = "https://rally1.rallydev.com";
String wsapiVersion = "1.38";
String applicationName = "RestExample_UpdateTestSetOnTestCaseResult";
// Credentials
String userName = "user#company.com";
String userPassword = "password";
RallyRestApi restApi = new RallyRestApi(
new URI(rallyURL),
userName,
userPassword);
restApi.setWsapiVersion(wsapiVersion);
restApi.setApplicationName(applicationName);
// Ref to Test Case Result of Interest
String testCaseResultRef = "/testcaseresult/1234567891.js";
GetRequest testCaseResultRequest = new GetRequest(testCaseResultRef);
GetResponse testCaseResultResponse = restApi.get(testCaseResultRequest);
JsonObject testCaseResultObj = testCaseResultResponse.getObject();
// Get the Test Case Result's Parent Test Case
JsonObject testCase = testCaseResultObj.get("TestCase").getAsJsonObject();
String testCaseRef = testCase.get("_ref").getAsString();
GetRequest testCaseRequest = new GetRequest(testCaseRef);
GetResponse testCaseResponse = restApi.get(testCaseRequest);
JsonObject testCaseObj = testCaseResponse.getObject();
System.out.println(testCaseRef);
// Ref to Test Set of Interest
String testSetRef = "/TestSet/12345678910.js";
// Get the Test Set of interest
GetRequest testSetRequest = new GetRequest(testSetRef);
GetResponse testSetResponse = restApi.get(testSetRequest);
JsonObject testSetObject = testSetResponse.getObject();
// Grab the Test Cases in this Test Set
JsonArray testCasesInTestSet = testSetObject.get("TestCases").getAsJsonArray();
// Loop through and see if our Test Case of interest is a member
boolean testCaseIsInSet = false;
for (int i=0; i<testCasesInTestSet.size(); i++) {
JsonObject thisTestCase = testCasesInTestSet.get(i).getAsJsonObject();
String thisTestCaseRef = thisTestCase.get("_ref").getAsString();
if (thisTestCaseRef.equals(testCaseRef)) {
testCaseIsInSet = true;
}
}
if (testCaseIsInSet) {
// Update Test Set on Existing Test Case Result
try {
//Add Test Set
System.out.println("\nUpdating Existing Test Case Result's Test Set attribute...");
testCaseResultObj.addProperty("TestSet", testSetRef);
UpdateRequest updateExistTestCaseResultRequest = new UpdateRequest(testCaseResultRef, testCaseResultObj);
UpdateResponse updateExistTestCaseResultResponse = restApi.update(updateExistTestCaseResultRequest);
if (updateExistTestCaseResultResponse.wasSuccessful()) {
System.out.println("Updated Test Case Result with new Test Set");
String[] updateExistTestCaseResultWarnings;
updateExistTestCaseResultWarnings = updateExistTestCaseResultResponse.getWarnings();
System.out.println("Warning(s) occurred updating Test Case Result: ");
for (int i=0; i<updateExistTestCaseResultWarnings.length;i++) {
System.out.println(updateExistTestCaseResultWarnings[i]);
}
} else {
String[] updateExistTestCaseResultErrors;
updateExistTestCaseResultErrors = updateExistTestCaseResultResponse.getErrors();
System.out.println("Error occurred updating Test Case Result: ");
for (int i=0; i<updateExistTestCaseResultErrors.length;i++) {
System.out.println(updateExistTestCaseResultErrors[i]);
}
}
} catch (Exception e) {
System.out.println("Exception occurred while updating Tags on existing Test Case: ");
e.printStackTrace();
}
finally {
//Release all resources
restApi.close();
}
} else {
System.out.println("Unable to Update Test Case Result with specified Test Set");
System.out.println("Parent Test Case is not a member of this Test Set");
}
}
When updating the TestSet you can just set the value as its ref- you don't need the wrapper object.
tcrResponse.getObject().add("TestSet", "/testset/1029348.js");