How to iterate over two Maps in Apex? - 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
}
}

Related

Hapi Fhir query with AND / OR with map

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.

salesforce compare standard obj and custom object and assign value

I have custom obj "A" and Standard obj Case. Case standard obj has lookup to custom obj "A". there is a field between the two objects called Customer_ID__c. I wrote a Trigger (before Insert, Before Update) to associated the case record to the correct existing custom obj "A" record if "Case.Custom_Id__c" match the one in the Custom obj "A". Unfortunate it is not happening and I'm not sure where to look.
trigger IAACaseRelateASAP on Case (before insert, before update) {
Id recordtypes = [Select Id, name
From RecordType
Where SobjectType = 'Case'
AND Name = 'I Buy'
LIMIT 1].Id;
Set<String> casId = new Set<String>();
for(Case cs : Trigger.new)
{
if(cs.RecordtypeId == recordtypes && cs.Type == 'Contact Me')
{
if(cs.custm_Obj_A_Name__lookupfield__c == null && (cs.Customer_ID__c != null || cs.Customer_ID__c !='0'))
{
casId.add(cs.Customer_ID__c);
}
}
}
system.debug('Case Set Ids' + casId);
List<A__c> aList = [Select Customer_ID__c, Id
From A__c
Where Customer_ID__c IN: casId
AND
A__c != 'Provider'];
System.Debug('equals' + aList);
Map<String, A__c> aMapId = new Map<String, A__c>();
for(A__c aAcct : aList)
{
aMapId.put(aAcct.Customer_ID__c, aAcct);
}
for(Case cas : Trigger.new)
{
if(cas.RecordtypeId == recordtypes && cas.Type == 'Contact Me')
{
if(cas.custm_Obj_A_Name__lookupfield__c == null && (cas.Customer_ID__c != null || cas.Customer_ID__c !='0'))
{
if(aMapId.containsKey(cas.Customer_ID__c))
{
A__c aAcct = aMapId.get(cas.Customer_ID__c);
System.Debug('Case IAA ASAP Account value: ' + asapAcct);
}
}
}
}
}
It might be best when looping through your cases to build your set of Customer_ID__c ids to also build a List of cases with customer ids so that you don't have to loop through the entire new list a second time. There are a couple other issues with the trigger in general but I'll ignore those and just focus on what you asked. Think your issue is that you don't actually set the case field in this area:
if(aMapId.containsKey(cas.Customer_ID__c))
{
A__c aAcct = aMapId.get(cas.Customer_ID__c);
System.Debug('Case IAA ASAP Account value: ' + asapAcct);
}
It should be :
if(aMapId.containsKey(cas.Customer_ID__c))
{
cas.custm_Obj_A_Name__lookupfield__c = aMapId.get(cas.Customer_ID__c).Id;
}

How to configure query by example to include null values?

I have the following matcher:
Example.of(
user,
ExampleMatcher.matching()
.withMatcher("name", contains().ignoreCase())
.withMatcher("phoneNumber", contains())
)
It works fine except null values. For example, it doesn't return the users whose phone number is NULL.
I have tried to following to include the NULL values but it didn't work:
Example.of(
user,
ExampleMatcher.matching()
.withMatcher("name", contains().ignoreCase())
.withIncludeNullValues()
.withMatcher("phoneNumber", contains())
.withIncludeNullValues()
)
The generated SQL is the following:
select
user0_.id as id1_9_,
user0_.document_expiry_date as document2_9_,
user0_.document_type as document3_9_,
user0_.document_url as document4_9_,
user0_.email as email5_9_,
user0_.name as name6_9_,
user0_.phone_number as phone_nu7_9_
from
user user0_
where
(lower(user0_.name) like ?)
and (user0_.id is null)
and (user0_.document_type is null)
and (user0_.document_url is null)
and (user0_.email is null)
and (user0_.phone_number like ?)
and (user0_.document_expiry_date is null)
How can I configure it to include rows with NULL columns as well?
Confronted the same problem, but I think there is no way to accomplish this goal. Here is the source code of method withMatcher:
public ExampleMatcher withMatcher(String propertyPath, ExampleMatcher.GenericPropertyMatcher genericPropertyMatcher) {
Assert.hasText(propertyPath, "PropertyPath must not be empty!");
Assert.notNull(genericPropertyMatcher, "GenericPropertyMatcher must not be empty!");
ExampleMatcher.PropertySpecifiers propertySpecifiers = new ExampleMatcher.PropertySpecifiers(this.propertySpecifiers);
ExampleMatcher.PropertySpecifier propertySpecifier = new ExampleMatcher.PropertySpecifier(propertyPath);
if (genericPropertyMatcher.ignoreCase != null) {
propertySpecifier = propertySpecifier.withIgnoreCase(genericPropertyMatcher.ignoreCase);
}
if (genericPropertyMatcher.stringMatcher != null) {
propertySpecifier = propertySpecifier.withStringMatcher(genericPropertyMatcher.stringMatcher);
}
if (genericPropertyMatcher.valueTransformer != null) {
propertySpecifier = propertySpecifier.withValueTransformer(genericPropertyMatcher.valueTransformer);
}
propertySpecifiers.add(propertySpecifier);
return new ExampleMatcher(this.nullHandler, this.defaultStringMatcher, propertySpecifiers, this.ignoredPaths, this.defaultIgnoreCase, this.mode);
}
this method returns a ExampleMatcher with the 'global' nullHandler which applied to all the fields. That means, you can't specify a different nullHander for some special fields.
You can implements JpaSpecificationExecutor<T> in your repository and use findAll(Specification specification), and set like param:
//My solution, create a specification with predicate and add example.
public Specification<MaestroPlasticoTebca> specificationAttributeNull(boolean isNull, Example<MaestroPlasticoTebca> example, String attributeName) {
return (root, query, builder) -> {
final List<Predicate> predicates = new ArrayList<>();
if (isNull) {
predicates.add(builder.isNull(root.get(attributeName)));
} else {
predicates.add(builder.isNotNull(root.get(attributeName)));
}
predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));
return builder.and(predicates.toArray(new Predicate[0]));
};
}
And use it:
Example example = Example.of(
user,
ExampleMatcher.matching()
.withMatcher("name", contains().ignoreCase())
);
repository.findAll(specificationAttributeNull(true, example, "phoneNumber"));

declare variable to store linq entity for conditional statements

I am trying to look up record using if I have the key then use Find if not use Where
private ApplicationDbContext db = new ApplicationDbContext();
public bool DeactivatePrice(int priceId = 0, string sponsorUserName = "")
{
var prices = db.BeveragePrices;
// if we have an id then find
if (priceId != 0)
{
prices = prices.Find(priceId);
}
else
{
prices = prices.Where(b => b.UserCreated == sponsorUserName);
}
if (prices != null)
{
// do something
}
return true;
I get the following error for
prices = prices.Find(priceId);
Cannot convert app.Model.BeveragePrices from system.data.entity.dbset
I am copying the pattern from this answer but something must be different.
Seems you forgot to put a predicate inside the Find function call. Also you need to do ToList on the collection. The second option is a lot more efficient. The first one gets the whole collection before selection.
Another note commented by #Alla is that the find returns a single element. So I assume another declaration had been made for 'price' in the first option I state down here.
price = prices.ToList.Find(b => b.PriceId == priceId);
Or
prices = prices.Select(b => b.PriceId == priceId);
I assume the field name is PriceId.

The 'ArrayIndex' LINQ expression node type is not supported by LINQ to Entities - using interface & ReportViewer

a quick question really.
I'm struggling to implement Linq2Entities statement that could take more than one value for a particular "field". I'm passing a number of strings to the getClientsProjected() I can easily compare single value. But I've got on my page multiple dropdown and out of that I get string separated with coma I then later use to split it to string[] e.g. __ACCOUNT_SITE = "1234,5678" (see the code below) I've tried for/foreach/contains none of which worked...
public IQueryable<ClientViewModel> getClientsProjected(string __ACCOUNT_SITE, string __ACCOUNT)
{
var projectedClients = from c in getClosedSRs()
select new ClientViewModel
{
_ACCOUNT_ID_CSR = c.ACCOUNT_ID_CSR,
_ACCOUNT = c.ACCOUNT,
_ACCOUNT_FAMILY = c.ACCOUNT_FAMILY,
...
...
_ACCOUNT_SITE = c.ACCOUNT_SITE
};
if (String.IsNullOrEmpty(__ACCOUNT) != true && __ACCOUNT != "ALL")
{
//this works fine as an __ACCOUNT is of a single value
projectedClients = projectedClients.Where(c => c._ACCOUNT == __ACCOUNT);
}
if (String.IsNullOrEmpty(__ACCOUNT_SITE) != true && __ACCOUNT_SITE != "ALL")
{
String[] splitSites = __ACCOUNT_SITE.Split(',');
//????????????????????????????????????????????????
}
return projectedClients;
}
Now, to most of you this will make complete sense. I've read many articles but did not find a proper answer. I however can't use Linq2SQL as already built my entire site using L2E, interface and ReportViewer.
Any workaround?
If you are trying to filter projectedClients based on the values in splitSites, then use:
if (String.IsNullOrEmpty(__ACCOUNT_SITE) != true && __ACCOUNT_SITE != "ALL")
{
String[] splitSites = __ACCOUNT_SITE.Split(',');
projectedClients = projectedClients.Where(x => splitSites.Contains(x._ACCOUNT);
}