I need to fetch the name of objects from custom setting and based on the name I need to create a dynamic Sooql for getting child objects id in order to share them with specific users.
Please see below part of trigger code that I am trying in order to achieve this.
SubQ =',(select id from ' + CustomMap.get(objName).API_Field__c + ')';
String queryStr=' select id '+ SubQuery + ' from Account where id in:accId';
List<Account> objdata =Database.query(queryStr);
for(String objName : CustomMap.keyset()) {
// Here custom map contains object name as key.
// objdata is the Account List created from sooql.
for(Account ac : objdata){
for(objName obj : ac.objName ){
if(recordIdsMap.containsKey('ObjName')){
List<String> recordIds = recordIdsMap.get('ObjName');
recordIds.add(obj.Id);
system.debug('recordIds' + recordIds);
recordIdsMap.put('ObjName',recordIds);
}
else{
system.debug('Recordid' + obj.id);
recordIdsMap.put('ObjName', new List<String> {obj.id});
}
but its giving typecasting errors here at line:
for(objName obj : ac.objName ){
because objname is string and not object here and even if I try to convert it to sobject it won't work because soject id supermost object and won't be able to call it from account.
If I hardcode the object here like so:
for(cases obj : ac.cases){
it will work but my requirement is to make it generic.
Related
I've been stuck for 18 hours on this apex class. I would really appreciate some help to figure out what's wrong. Basically this code should match the fields between two objects and I don't know why I'm receiving the following errors:
Missing return statement required return type: String - Line 2
Expecting '}' but was: 'for' - Line 26
The output should show that when location and position title from Candidate object matches location and title from Position object then it will just show those values that match on a data table in a lightning web component I made on Visual Studio.
I'd like some help improving this code so I can run it on the dev console.
public class Matchposition {
public static String matchPositionsWithCandidate() {
Set<String> statuses = new Set<String> {'New', 'Open'};
List<Position__c> openPositions = [SELECT Id, Name, Location__c, Status__c FROM Position__c WHERE Status__c IN :statuses];
//system.debug(openPositions);
Set<String> openPositionAndLocation = new Set<String>();
Map<String, Position__c> openPositionMap = new Map<String, Position__c>();
for (Position__c position : openPositions) {
openPositionMap.put(position.Name + '-' + position.Location__c, position);
openPositionAndLocation.add(position.Name + '-' + position.Location__c);
}
}
//for(String key : openPositionMap.keySet()) {
// system.debug('*** Start ***');
// system.debug('key :' + key);
// system.debug('value :' + openPositionMap.get(key));
// system.debug('*** End ***');
//}
Map<String, List<Candidate__c>> candidatesMap = new Map<String, List<Candidate__c>>();
List<Candidate__c> candidates = [SELECT Position__c, Location__c, Mobile__c, First_Name__c, Last_Name__c, Email__c FROM Candidate__c];
for (Candidate__c candidate : candidates) {
if(candidatesMap.containsKey(candidate.Position__c + '-' + candidate.Location__c)) {
candidatesMap.get(candidate.Position__c + '-' + candidate.Location__c).add(candidate);
} else {
candidatesMap.put(candidate.Position__c + '-' + candidate.Location__c, new List<Candidate__c> {candidate});
}
}
system.debug('*************** OPEN POSITIONS ***************');
for (String key : openPositionAndLocation) {
system.debug('====> ' + openPositionMap.get(key).Name);
if(candidatesMap.containsKey(key)) {
system.debug('***** Candidates *****');
for(Candidate__c candidate : candidatesMap.get(key)) {
system.debug('------- Name : ' + candidate.First_Name__c + ' ' + candidate.Last_Name__c);
system.debug('------- Email : ' + candidate.Email__c);
system.debug('------- Mobile : ' + candidate.Mobile__c);
}
} else {
system.debug('********* No Candidates');
}
}
One issue you certainly have, apropos of nothing else, is overall structure. Removing the actual lines of code, here's how your class is laid out now:
public class Matchposition {
public static String matchPositionsWithCandidate() {
// Code here
}
// more code here - problem!
}
You have much of your logic loose in the body of your class, which is not valid in Apex. Additionally, the code in the class body references variables declared inside the method matchPositionsWithCandidate(), which are scoped (visible) to that method.
matchPositionsWithCandidate() is also declared to return a string, but in fact returns nothing at all.
Since you're not returning any data anywhere, one step you can take to try to get this code running is to ensure that all of your logic is inside the scope (the curly braces) of the method matchPositionsWithCandidate(), and declare that method to return void, not String.
You may also have unbalanced braces - it looks like there is one missing after the final else - if it wasn't simply omitted in the copy and paste.
I'm not sure why this code exists. While much of the logic is correct, it makes far more sense to model your data with a relationship between Candidate__c and Position__c, rather than just storing a name in both positions. Then, you don't need any "matching" code at all - just a simple SOQL relationship query.
I want to get values in my code from a static resource file.
I am using an excel file in a static resource, I want to know how I can map fields in an excel file to salesforce fields in my code. for example Account.Name etc
Lead l = new Lead();
l.Company = $Resource.EMailServicesLead.EmailServiceStaticResourceData.csv;
\ Not Working
EMailServicesLead - Name of the static resource.
EmailServiceStaticResourceData - csv file with fields {FirstName, LastName, Email, Company, Status, LeadSource}
/**
* #File Name : myHandler.cls
* #Description :
* #Author : ChangeMeIn#UserSettingsUnder.SFDoc
* #Group :
* #Last Modified By : ChangeMeIn#UserSettingsUnder.SFDoc
* #Last Modified On : 7/10/2019, 3:54:01 PM
* #Modification Log :
* Ver Date Author Modification
* 1.0 7/10/2019 ChangeMeIn#UserSettingsUnder.SFDoc Initial Version
**/
global with sharing virtual class myHandler implements Messaging.InboundEmailHandler
{
global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope)
{ Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
//Lead l= (Lead)ListofLeadsStaticRes[0];
// List<SObject> ListofLeadsStaticRes = {!URLFOR($Resource.EMailServicesLead, 'EmailServiceStaticResourceData.csv')};
Integer j=0;
String myPlainText= '';
staticResource sr = new staticResource();
List<sObject> ls = Test.loadData(Lead.sObjectType, 'myResource');
// {!URLFOR($Resource.EMailServicesLead,EMailServicesLead/EmailServiceStaticResourceData.csv)}
Lead l = new Lead();
l.FirstName=email.fromName.substring(0,email.fromName.indexOf(''));
l.LastName=email.fromName.substring(email.fromName.indexOf(''));
l.Email = envelope.fromAddress;
myPlainText = email.plainTextBody;
l.Company = $Resource.EMailServicesLead.EmailServiceStaticResourceData.csv;
l.Status = $Resource.EMailServicesLead.EmailServiceStaticResourceData.csv;
l.LeadSource = $Resource.EMailServicesLead.EmailServiceStaticResourceData.csv;
l.Description = 'Mr.' + l.FirstName + l.LastName + ' enquired about the product Fin' + ' via' + ' Ă‹mail' + 'with body '+myPlainText;
Task[] newTask = new Task[0];
try { // Add a new Task to the Lead record we just found above.
List<Lead> vLed = [SELECT Id, Name, Email FROM Lead WHERE Email = :email.fromAddress LIMIT 1];
if(vLed.size()>0)
{ newTask.add(new Task(Description = myPlainText,
Priority = 'Normal',
Status = 'Inbound Email',
Subject = email.subject,
IsReminderSet = true,
ReminderDateTime = System.now()+1,
WhoId = vLed[0].Id));
insert newTask;
System.debug('New Task Object: ' + newTask );
}
else
{
insert l;
System.debug('Lead Created'+ l.Id);
}
}
catch (QueryException e) { System.debug('Query Issue: ' + e); }
return result;
}
}
You will need to parse the CSV to extract the data from it. To make this easier you can use this simple CSV parser class written by Nicolas Galler. Have a look through the code so you get how it works but all you will use is the constructor and the readLine() method that returns the list of values from each row of your CSV as Strings. You'll have to copy and paste the code from that link into an apex class named "SSSCsvReader" to be able to use it then in your code you will...
1. get your static resource CSV as a String
StaticResource sr = [SELECT ID, body FROM StaticResource WHERE Name = 'EMailServicesLead' LIMIT 1];
String csvData = sr.body.toString();
2. Create an instance of SSSCsvReader by calling the constructor passing in the CSV string as the argument(and optionally, the second argument of a delimiter but the comma is the default)
SSSCsvReader csvR = new SSSCsvReader(csvData);
3. Use the readLine() on your SSSCsvReader object to get CSV field values in a String list. (if Your file has a header row on it don't forget to remove this first by calling readLine() once before getting your data list).
csvR.readLine() //Removing header (optional)
String[] line = csvR.readLine();
if(line == null){return null} //No line in the file or there was no header so return
4. Assign each field in the returned list from readLine() to the corresponding field in your salesforce object.
Lead l = new Lead();
l.firstName = line[0]; //If your file is laid out like you said FirstName will be index [0]
l.lastName = line[1]; //LastName will be index [1]
.... //And so on
....
....
And there you have it a Lead object with fields from your CSV static resource file. If you have more rows on you CSV and want to create many leads than just set up a while loop that gets each line from the CSV using readLine(), create a new lead from this line and add it to a list.
I have 2 objects, say object 1 and object 2.
I first iterate over a collection of object 1 records.
Id Object2Id = 'Some Id';
for (Object1 obj1 : objectOneCollection ) {
String query = 'SELECT Id FROM Object2 WHERE Id =:' + Object2Id + ' AND ' + obj1.SOQLClause__c;
List<Object2> list = Database.query(query);
//do some processing with list
}
Hope my code says it all. I know having this Database.query() inside the above for loop is a bad practice. In other words, having SOQL inside for loops is something we are not supposed to do.
Can you help me to find a way to take this Database.query() out of the for loop making sure it still matches my requirement ?
Because, there is a field in Object1 containing a string to be matched in the where clause of object2.
I need to create a condition when insert into DocumentDB table.
I'm using .NET SDK.
When I use the insert operation I would like to compare the document to the rest of the documents and approve the insertion only if there is no other document containing the same value in a specific field.
Other option is to define a column as unique, only that in my case it is two columns that should be unique.
Here the trigger I made, for some reason it is not preventing the INSERT operation.
the fields to compare are "ApplicationSession" and "OperationCounter"
function UniqueAppSessionAndCounter() {
var collection = getContext().getCollection();
var request = getContext().getRequest();
var docToCreate = request.getBody();
if (!docToCreate.ApplicationSession || docToCreate.ApplicationSession == ""
|| !docToCreate.OperationCounter || docToCreate.OperationCounter == 0) {
throw new Error('Application session and Counter is a must');
}
var filterQuery = 'SELECT * FROM r WHERE r.ApplicationSession = "'
+ docToCreate.ApplicationSession + '" AND r.OperationCounter = '
+ docToCreate.OperationCounter;
collection.queryDocuments(collection.getSelfLink(), filterQuery
, function (err, docs, options) {
if (docs.length > 0) {
throw new Error('Application session and Counter must be unique');
}
});}
Are you sure that you are executing the Trigger when you call CreateDocumentAsync?
In DocumentDB, trigger execution is not automatic like you might expect.
This is because you often have different documents going in to a single collection and you might want different triggers for different types of documents.
To execute the document when creating the document make sure you specify to include the trigger as follows:
CreateDocumentAsync(coll_link,
new {foo: "bar"},
new RequestOptions {IncludePreTrigger = "TriggerName"});
I require a separate object which contains the related fields of a child object.
Currently I do it like this:
Opportunity opp = [SELECT Id, Name, Account.Id, Account.Name FROM Opportunity LIMIT 1];
Account acc = new Account(
Id = opp.Account.Id,
Name = opp.Account.Name
);
When working with a large related object I have to initialise many more fields than this and the script becomes very large and ugly.
What is the quickest way to initialise the related field data into a separate object?
You must define the all fields in your SOQL query (mor info here).
But it is not necessary if you want to clone the object:
Opportunity opp = [SELECT Account.Id, Account.Name
FROM Opportunity
LIMIT 1];
Account acc = opp.Account;
Example with Custom Object:
Contract__c c = [ Select Account__r.FirstName
From Contract__c
Where Account__r.FirstName != null
Limit 1];
Account a = c.Account__r;