Get a field value from a SObject List (Apex) - salesforce

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.

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;
}
}
}

How To Understand #TestClass Apex code with List embedded in Map

I am trying to understand this code ,this seems to be a test class,but i am having hard time to understand the code,i know conceptually how List and Map collection works in Sales force,but this seems to be little difficult to understand,
.In brief to me this seems to test a method which browses a list of CollaborationGroupMember.
For that, CollaborationGroup has been created and code tried to add one User.
can some one please take some time to make me understand the below code line by line?
Thanks in advance
#isTest
public class TestGroupFactory {
public static Map<CollaborationGroup, List<CollaborationGroupMember>> groupWithMember() {
CollaborationGroup groupe = new CollaborationGroup(Name = 'Test1', CollaborationType = 'Public');
insert groupe;
groupe = [SELECT Id, Name FROM CollaborationGroup WHERE Name = 'Test1'];
List<User> users = [SELECT Id, Name, Numero_de_plaque__c, SenderEmail
FROM User
WHERE Name = 'User User'];
List<CollaborationGroupMember> cgms = new List<CollaborationGroupMember>();
for (User u : users) {
CollaborationGroupMember cgm = new CollaborationGroupMember();
cgm.CollaborationGroupId = groupe.Id;
cgm.MemberId = u.Id;
cgms.add(cgm);
}
insert cgms;
return new Map<CollaborationGroup, List<CollaborationGroupMember>>{groupe => cgms};
}
}
It is technically a test class, but it does not perform any tests. Its purpose is to create test data for other test classes that contain test methods. The reason it has the #isTest annotation is so that it is only accessible in test context and does not count against the total test coverage of the organization.
The method shown creates a Chatter Group and adds Users to the group if they have the name "User User".
The code below inserts the Chatter Group and then retrieves it so the Id is available. I don't think the retrieval is necessary in this instance, but I'd have to test it.
CollaborationGroup groupe = new CollaborationGroup(Name = 'Test1', CollaborationType = 'Public');
insert groupe;
groupe = [SELECT Id, Name FROM CollaborationGroup WHERE Name = 'Test1'];
The next section retrieves the Users (presumably created in another test class)
List<User> users = [SELECT Id, Name, Numero_de_plaque__c, SenderEmail
FROM User
WHERE Name = 'User User'];
Then, a list of CollaborationGroupMembers is instantiated. A loop begins that iterates over every User. For each user, a new CollaborationGroupMember is instantiated and added to the list.
List<CollaborationGroupMember> cgms = new List<CollaborationGroupMember>();
for (User u : users) {
CollaborationGroupMember cgm = new CollaborationGroupMember();
cgm.CollaborationGroupId = groupe.Id;
cgm.MemberId = u.Id;
cgms.add(cgm);
}
The group members are inserted
insert cgms;
The group and group members are added to a map and returned
return new Map<CollaborationGroup, List<CollaborationGroupMember>>{groupe => cgms};

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.

Salesforce Apex :- Getting error as static can only be used on methods of a top level type

On developer console ,Getting error as static can only be used on methods of a top level type
Static method which take DML statements input
public class InvoiceHandler {
public static APEX_Invoice__c insertNewinvoice(date today) {
List invoiceList = [SELECT id, Name, APEX_Status__c, createdDate FROM APEX_Invoice__c WHERE createdDate = today];
return invoiceList;
}
}
This method takes name date parameter and makes a new invoice.It will return that invoiceList.
if i execute only below
List invoiceList = [SELECT id, Name, APEX_Status__c, createdDate FROM APEX_Invoice__c WHERE createdDate = today];
code is successfully executed ,butmy intention is to execute via class and static method
It would help if you indented your code correctly..
public class InvoiceHandler
{
public static List<APEX_Invoice__c> insertNewinvoice(date today)
{
List<APEX_Invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c, createdDate FROM APEX_Invoice__c WHERE createdDate = today];
return invoiceList;
}
}

Can we Cast SObject dynamically in Salesforce(apex)?

Is it possible to Cast SObject dynamically?
Example :
I know we can do this :
(Account) Sobject
But I want to do this as the return type of sObject changes based on certain parameters.
(Dynamically Passing the Name) SObject
Any Kind of way around will be helpful... Thanks in advance :)
Yes, you can do it. For example -
Class ABC {
public static List<Object> method1(String sObjectType){
List<Object> records = new List<Object>();
if(sObjectType == 'Account'){
records = [SELECT Id, Name FROM Account];
} else if(sObjectType == 'Account'){
records = [SELECT Id, Name FROM Contact];
}
return records;
}
}
You can check the sObject Type of List -
if(records instanceof List<Account>){
// your code here
} else if(records instanceof List<Contact>){
// your code here
}
Unfortunately, no. I ran into this recently while writing a TestFactory class. The best I could do was cast the responses back into the expected type in the code that was calling the TestFactory's methods.

Resources