Casting a List into a Map<Id, String> - salesforce

I want to save the below query into a Map<Id, String> like in the sentence below:
Map<Id, String> queuesMap = new Map<Id, String> ([SELECT Id, DeveloperName
FROM Group
WHERE Type = 'Queue' ]);
But, for some reason (?), when testing this in "Execute Anonymous Window", I am getting this error:
Line: 1, Column: 29
Invalid initializer type List<Group> found for Map<Id,String>: expected a Map with the same key and value types, or a valid SObject List
While doing some trial/error, I have tried the following, which does not return any error:
Map<Id, Group> queuesMap = new Map<Id, Group> ([SELECT Id, DeveloperName
FROM Group
WHERE Type = 'Queue' ]);
I need to end up having a Map<Id, String> because, eventually, my code has an apex method returning the key paired with a provided String (provided to the method).
How can I store the result of the above query (a List) into a Map<Id, String>?
Thank you.

Map<Id, String> queuesMap = new Map<Id, String>();
for(Group g : [SELECT Id, DeveloperName FROM Group WHERE Type = 'Queue']){
queuesMap.put(g.Id, g.DeveloperName);
}

Related

salesforce update trigger on serviceterritory object

I have below requirement and I'm new to SF development, need assistance if my approach is correct or not.
When any update happens on ServiceTerritory object, if the Time_Zone__c field of ServiceTerritory is not matching with User Object TimeZoneSidKey field, then update ServiceTerritory object Time_Zone__c field with User Object TimeZoneSidKey field.
ServiceTerritory object : has Center_Instructor_Contact__c field tagged to ID field in Contact object.
Contact object : has ID field and AccountId field
User Object : has AccountId field
public static void afterUpdate(List<ServiceTerritory> serviceTerritories, Map<Id, ServiceTerritory> oldRecords) {
Set<Id> recIds = new Set<Id>();
for (ServiceTerritory record : serviceTerritories) {
recIds.add(record.Id);
}
Set<Id> STMembers = new Set<Id>();
for (ServiceTerritory member : [SELECT Id, Center_Instructor_Contact__c FROM ServiceTerritory WHERE Id IN :recIds]) {
STMembers.add(member.Center_Instructor_Contact__c);
}
//Contact object : has ID field and AccountId field
Set<Id> ContactIDs = new Set<Id>();
for (Contact Cnt : [SELECT AccountId FROM Contact WHERE Id IN :STMembers]) {
ContactIDs.add(Cnt.AccountId);
}
//User Object : has AccountId field
Set<Id> UserIDs = new Set<Id>();
for (User Cnt : [SELECT AccountId, TimeZoneSidKey FROM User WHERE AccountId IN :ContactIDs]) {
UserIDs.add(Cnt.AccountId);
}
}
and here how to compare and update ServiceTerritory object if the timezone is not matching between the objects.
Not many Salesforce instances will have access to "Field Service Lightning" which is where ServiceTerritory table is used. If you sign up for free Salesforce Developer Edition it probably won't exist there. So it's bit hard to understand the question and help. Plus if you wrote "User Object : has AccountId field" it sounds like you're using Experience Cloud (formerly known as communities), that narrows down the specialists even more.
So it's Service Territory -> "up" to -> Contact -> "down" to (community) -> User?
If you're using community users they'll have AccountId and ContactId in them, no need going via Account (and in fact you could get stupid results that way... What if not all contacts in account are community-enabled, what if they are but have different timezones...)
Try something like that but you'll have to experiment a lot. And change your code to run "before update", you'll get save to database for free
List<ServiceTerritory> serviceTerritories; // passed to your function
Set<Id> contactIds = new Set<Id>();
for (ServiceTerritory st : serviceTerritories) {
contactIds.add(st.Center_Instructor_Contact__c);
}
System.debug(contactIds);
// Grab all these Contacts and their community users (it's a related list so it'll be a subquery but really there will be at most one user
Map<Id, Contact> contacts = new Map<Id, Contact>([SELECT Id,
(SELECT TimezoneSidKey FROM Users)
FROM Contact
WHERE Id IN :contactIds AND Id IN (SELECT ContactId FROM User)]);
// Loop again and check against "reference data"
for (ServiceTerritory st : serviceTerritories) {
if(contacts.containsKey(st.Center_Instructor_Contact__c)){
Contact c = contacts.get(st.Center_Instructor_Contact__c);
System.debug(c);
System.debug('comparing ' + st.Time_Zone__c + ' and ' + c.Users);
if(st.Time_Zone__c != c.Users[0].TimezoneSidKey){
System.debug('fixing ' + st.Id);
st.Time_Zone__c = c.Users[0].TimezoneSidKey;
}
}
}

Get a field value from a SObject List (Apex)

I'm facing with the current problem.
I have the following code which is a list of SObject and I want to get "CreatedDate" field.
I really appreciate ur time and comments, thanks.
public static Object testMeth() {
List<SObject> leadsAndOpps = new List<SObject>();
List<Lead> lstLead = [Select Id, Name, CreatedDate FROM Lead];
List<Opportunity> lstOpp = [Select Id, Name, CreatedDate FROM Opportunity];
//Assign first and second List to Sobject List
leadsAndOpps.addAll(lstLead);
leadsAndOpps.addAll(lstOpp);
for(SObject lstExa : leadsAndOpps) {
String getName = (String)lstExa.get('Name'); = This example works cool
DateTime getDateVal = (DateTime)lstExa.get(CreatedDate); = Variable doesn't exists
}
return leadsAndOpps;
}
The SObject.get() method is expecting a string representing the field API Name. If you put 'CreatedDate' in quotes, it should be fine. What you are passing in now is perceived as an undeclared variable named CreatedDate.

Map<String ,String[]> Converts to Map<String, Object[])

I have a map
Map<String, String[]> newMetaData = new LinkedHashMap();
which I populate with data like this:
newMetaData.put(
((String) elm.get("companyName")).trim(),
new String[]{
this.storeFile( "logo", (String) elm.get("logoLink") ),
this.storeFile( "profile", (String) elm.get("companyProfile") ),
this.storeFile( "action", (String) elm.get("drash") ),
(String) elm.get("fwtografies")
}
);
StoreFile is a function that returns string. I save this map to the storage as
Storage.getInstance().writeObject("MetaData", newMetaData);
Later on the code I retrive the above map as:
Map<String, String[]> metaData = (Map)Storage.getInstance().readObject("MetaData");
But instead of getting a Map of <String, String[] & gt; I get Map of <String, Object[] >
any help is appreciated
Generics in Java are syntax sugar. They are erased by the compiler and ignored by Codename One for the most part. This:
Map<String, String[]> newMetaData = new LinkedHashMap<>();
Is equivalent to this as far as the generated code is concerned:
Map newMetaData = new LinkedHashMap();
There are some caveats because the first version will also add casts when you use methods like set/put which could trigger a class cast exception in some cases. The thing is that this works in reverse as well so this should work just fine:
Map<String, String[]> metaData = (Map<String, String[]>)Storage.getInstance().readObject("MetaData");

How to get query covered in apex test class for salesforce

I'm having a tough time trying to get all code covered in my test class for an apex class.
Apex class:
public with sharing class myclass {
**public List<CustomObject1> listvar {get;set;}**
public myclass(ApexPages.StandardController sc){
CustomObject2 var = [SELECT Id, Field1__c FROM CustomObject2 WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
**listvar = [SELECT Id,Name,Field1__c,Field2__c,Field3__c,Field4__c,Field5__c,CreatedDate,CreatedById FROM CustomObject1 WHERE Field2__c = :var.Field1__c ORDER BY CreatedDate DESC];**
}
}
Test Class:
#isTest
public class myclass_Test {
static testmethod void dosomething(){
Account a = new Account();
a.Name = 'Test acct';
insert a;
CustomObject4__c v = new CustomObject4__c();
v.Field1__c = '123 ABC';
v.Name = 'test name';
v.Field2__c = True;
v.Account__c = a.Id;
insert v;
... more record creates including ones for the object being queried...
PageReference pageref = Page.myVFpage;
Test.setCurrentPageReference(pageref);
ApexPages.StandardController sc = new ApexPages.StandardController(v);
myclass myPageCon = new myclass(sc);
}
}
I've tried creating a new list for the underneath the last line in the test class and populating the list, but I cannot get 100% code coverage. I marked the lines that I'm not getting any coverage from the test class with. Any suggestions?
You should put some asserts into your test Class. Something like
System.assertEquals(5, yourListsize)
I figured out that the listvar list for CustomObject1 wasn't getting populated because an Id wasn't being passed to var for CustomObject2. In the test class I had to put the record Id using ApexPages.currentPage().getParameters().put('Id', something.id);
with the Id for the record created in the test class for that object. Thanks anyways guys :-)

Merge field value is not showing in email template when it send by apex

I have an email template which I want to send by apex class.I am getting an Email notification but merge field's value is not showing.I tried many solutions but not getting the result.Please, can anyone help me?
Here is the snap of my email template
Email template
And apex code:-
global class sampleBatch implements Database.Batchable<sObject>{
global Database.QueryLocator start(Database.BatchableContext bc) {
String query = 'Select id,Name from book__c;
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<book__c> books){
Map<Id, List<Case>> associatedCases = CaseHelperClass.getCase(new Map<Id,book__c>(books).keySet());
Map<Id,book__c> bookMap= new Map<Id,book__c>(books);
EmailTemplate emailTemplate = [SELECT Id,Subject,Description,HtmlValue,DeveloperName,Body FROM EmailTemplate WHERE DeveloperName =: 'sameple_template'];
if(associatedCases <> null){
for(Id bookId : associatedCases.keySet()){
String headerAndAssociatedCases = 'CaseNumber,Type,Status,Subject,Description,CreatedDate\n';
for(Case c : associatedCases.get(bookId)){
headerAndAssociatedCases += c.CaseNumber+','+c.Type+','+c.Status+','+c.Subject+','+c.Description+','+c.CreatedDate+'\n';
}
Messaging.EmailFileAttachment csvAttachment = new Messaging.EmailFileAttachment();
blob csvBlob = Blob.valueOf(headerAndAssociatedCases);
csvAttachment.setFileName('Case.csv');
csvAttachment.setBody(csvBlob);
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
list<string> toAddresses = new list<string>{name#test.com};
email.setSubject(emailTemplate.Subject);
email.setTemplateId(emailTemplate.Id);
email.setPlainTextBody(emailTemplate.Body);
email.setToAddresses(toAddresses);
email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvAttachment});
Messaging.SendEmailResult [] result = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
}
}
}
global void finish(Database.BatchableContext bc){
system.debug('Apex Job Done');
}}
Any help will be highly appreciable.
Thank you!
Please refer to the requirements of the SingleEmail method:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_single.htm
Specifically refer to the below:
setTargetObjectId(targetObjectId)
Required if using a template, optional otherwise. The ID of the contact, lead, or user to which the email will be sent. The ID you specify sets the context and ensures that merge fields in the template contain the correct data.
setWhatId(whatId)
If you specify a contact for the targetObjectId field, you can specify an optional whatId as well. This helps to further ensure that merge fields in the template contain the correct data.
I don't see either of these methods in your code.

Resources