Map and List values from APEX SALESFORCE - salesforce

I have question on my Salesforce WebService and Apex Code.
In a relationship, we have one Notice and multiple attachments in my salesforce. But I don't know how to fix below requirements:
when "GET" webservices incoming thru specific URL API, it supposed to return with JSON format
JSON Format should {Notice1 : attach1{link},attach2{link} , etc }
#RestResource(urlMapping='/API/V1/notice/*')
global with sharing class API_Notice {
#HttpGet(UrlMapping='/API/V1/notice/all')
global static List<String> getNotice(){
Set<Id> NoticeIds = new Set<Id>();
Set<Id> VersionIds = new Set<Id>();
String compares;
List<String> returnJSON = new List<String>();
List<Notice__c> reConts = [select Id, ClosingDate__c ,Name, Contents__c from notice__c];
Map<Id,Notice__c> addMap = new Map <Id,Notice__c>();
Map<Map<Id,Notice__c>,Map<Id,contentdistribution>> addsMap = new Map<Map<Id,Notice__c>,Map<Id,contentdistribution>>();
//SET NOTICE ID
if(!reConts.isEmpty()){
for(Notice__c nc : reConts){
NoticeIds.add(nc.Id);
addMap.put(nc.id,nc);
}
}
//GET public Image URL
if(!NoticeIds.isEmpty()){
Map<Id,ContentDocumentLink> contentMap = new Map<Id,ContentDocumentLink>([
select contentDocumentid,LinkedEntityId from ContentDocumentLink where LinkedEntityId IN:NoticeIds
]);
for(ContentDocumentLink Key : contentMap.values()){
VersionIds.add(Key.ContentDocumentId);
}
if(!VersionIds.isEmpty()){
Map<Id, contentdistribution> cdb = new Map <Id, contentdistribution> ([
select DistributionPublicUrl from contentdistribution where contentDocumentid IN:VersionIds
]);
addsMap.put(addMap,cdb);
}
}
return null;
}
}

Related

Can someone help in Bulkifying the below Apex code. The purpose here is to Remove Product Sharing When user is removed from AccountTeamMember

The purpose here is to Remove Product Sharing When user is removed from AccountTeamMember.
List<AccountTeamMember> acctmListProd = [Select id,UserId, AccountId, TeamMemberRole FROM
AccountTeamMember WHERE Id In:acctmList and
TeamMemberRole IN:Roles]
Map<Id,Id> accToUserIdList = new Map<Id,Id>();
for(AccountTeamMember At: acctmListProd)
{
accToUserIdList.put(At.AccountId, At.UserId);
}
List<Product__Share> DelProdShareRecords = new List<Product__Share>();
Set<Id> productIds = new Set<Id>();
for(Id accId: accToUserIdList.keySet())
{
List<Product__c> prodList = [Select id,Account__c from Product__c where
Account__c=accId];
for(Product__c prod: prodList)
{
productIds.add(prod.Id);
}
List<Product__Share> prodShareRecords = [Select id,ParentId,UserOrGroupId from
Product__Share where ParentId IN:productIds AND
UserOrGroupId=accToUserList.get(accId)
];
DelProdShareRecords.addAll(prodShareRecords);
}
if(!DelProdShareRecords.isEmpty())
{
Database.deleteResult[] result = Database.delete(DelProdShareRecords, false);
}
https://ideas.salesforce.com/s/idea/a0B8W00000GdgUVUAZ/allow-global-security-and-sharing-rules-settings-on-products
Product__Share isn't a thing. This code looks like it was never compiled or tested in an org.

Store the signed version docusign in salesforce

I have written the code to the send the envelope but i need to store the signed version in salesforce record.
public class SendDocusignCondController {
#AuraEnabled
public static Opportunity getOpportunityDetails(String recordId){
Opportunity objOpportunity = [SELECT id,Group_HR_Name__c,Group_HR_Email__c,Group_Type__c FROM Opportunity WHERE id =:recordId ];
String message = 'Hi'+objOpportunity.Group_HR_Name__c+'\nPlease DocuSign the Producer Compensation Disclosure Notice.pdf,\nThank You, IU Health Plans';
dfsle.Recipient myEmployer = dfsle.Recipient.fromSource(objOpportunity.Group_HR_Name__c, objOpportunity.Group_HR_Email__c, null,'Employer',new dfsle.Entity(objOpportunity.id));
dfsle.UUID myTemplateId = dfsle.UUID.parse(SYSTEM.Label.VTY_Docusign_Commission_Template);
dfsle.Document templateDocument = dfsle.Document.fromTemplate(myTemplateId,'Procedure Comission Employee Notification');
List<dfsle.Document> allDocumentList = new List<dfsle.Document>();
if(!Test.isRunningTest()){
allDocumentList.add(templateDocument);
dfsle.CustomField myCustomField1 = new dfsle.CustomField('text','##SFOpportunity', objOpportunity.id, null, true, true);
dfsle.Envelope myEnvel = new dfsle.Envelope(null,null,null,null,new List<dfsle.Document> {templateDocument},null,null,null,'Please DocuSign: Producer Compensation Disclosure Notice.pdf',message,null,null);
myEnvel = myEnvel.withCustomFields(new List<dfsle.CustomField> { myCustomField1 });
myEnvel = myEnvel.withRecipients(new List<dfsle.Recipient> { myEmployer });
myEnvel = dfsle.EnvelopeService.sendEnvelope(myEnvel,true);
}
return objOpportunity;
}
}
Please let me know
DocuSign has an out of the box feature that does this for you automatically without code: https://support.docusign.com/articles/DocuSign-for-Salesforce-Adding-Completed-Documents-to-the-Notes-and-Attachments-New

How to test contentdocumentlink trigger for Salesforce Prod deployment

I am trying to deploy a trigger to prod on salesforce. I was hoping someone could help me with an example of tests for this trigger.
Here is my trigger. It does its purpose, which is to update a bool field when a new contentNote (or anything of content type) that then has collateral effects through process builder.
trigger NewNote on ContentDocumentLink (before insert) {
Set<Id> setParentId = new Set<Id>();
List<Client_Relationships__c> crlst = new List<Client_Relationships__c>();
for (ContentDocumentLink cdl : trigger.new ) {
setParentId.add(cdl.LinkedEntityId);
}
crlst = [select Id , newNote__c from Client_Relationships__c where Id IN :setParentId];
For(Client_Relationships__c e : crlst)
{
e.newNote__c = True;
}
update crlst;
}
The trigger you wrote can be more efficient by omitting the SOQL query as seen below:
trigger NewNote on ContentDocumentLink (before insert) {
List<Client_Relationships__c> crlst = new List<Client_Relationships__c>();
for (ContentDocumentLink cdl : trigger.new ) {
if(cdl.LinkedEntityId.getSObjectType().getDescribe().getName() == 'Client_Relationships__c'){
crlst.add(
new Client_Relationships__c(
Id = cdl.LinkedEntityId,
newNote__c = true
)
);
}
}
update crlst;
}
The best practice would be to add your code to a handler or utility class and to only have one trigger per object. The name of this trigger could be changed to "ContentDocumentLinkTrigger" if you adopt that practice.
The test class for that trigger is below. I could not test the compilation because I don't have the same custom object.
#IsTest
private class ContentDocumentLinkTriggerTest {
#TestSetup
static void setupTest() {
insert new ContentVersion(
Title = 'Test_Document.txt',
VersionData = Blob.valueOf('This is my file body.'),
SharingPrivacy = 'N',
SharingOption = 'A',
Origin = 'H',
PathOnClient = '/Test_Document.txt'
);
List<Client_Relationships__c> relationships = new List<Client_Relationships__c>();
for(Integer i = 0; i < 300; i++){
relationships.add(
new Client_Relationships__c(
//add required field names and values
)
);
}
insert relationships;
}
static testMethod void testInsertTrigger() {
//prepare data
List<ContentVersion> contentVersions = new List<ContentVersion>([
SELECT Id, ContentDocumentId FROM ContentVersion
]);
System.assertNotEquals(0, contentVersions.size(), 'ContentVersion records should have been retrieved');
List<Client_Relationships__c> relationships = getAllClientRelationships();
System.assertNotEquals(0, relationships.size(), 'Client Relationship records should have been retrieved.');
List<ContentDocumentLink> documentLinks = new List<ContentDocumentLink>();
for(Integer i = 0; i < 252; i++){
documentLinks.add(
new ContentDocumentLink(
ContentDocumentId = contentVersions[0].ContentDocumentId,
LinkedEntityId = relationships[i].Id,
ShareType = 'I'
)
);
}
//test functionality
Test.startTest();
insert documentLinks;
Test.stopTest();
//assert expected results
List<Client_Relationships__c> relationshipsAfterProcessing = getAllClientRelationships();
for(Client_Relationships__c relationship : relationshipsAfterProcessing){
System.assert(relationship.newNote__c, 'The newNote__c field value should be true.');
}
}
private static List<Client_Relationships__c> getAllClientRelationships(){
return new List<Client_Relationships__c>([
SELECT Id, newNote__c FROM Client_Relationship__c
]);
}
}
For setting up test data, it is helpful to have a utility class that centralizes the creation of well-formed records. This is extremely useful when your code base gets large and a validation rule affects the insertion of new data in many test classes. With a centralized method, the inserted data only needs to be altered once.

How to retrieve field from custom master object?

I am trying to write a custom object and have to retrieve one custom related field from custom object Course Master(master) to detail object Training deals. This code is showing error
List<List<String>> strList = new List<List<String>>();
List<Training_deal__c> td = [select name, Course_master__r.course__c from Training_deal__c];
for(Training_deal__c t : td){
List<String> tempList = new List<String>();
tempList.add('Training Deals');
tempList.add(t.name);
tempList.add(t.course__c);
strList.add(tempList);
}
Try This
tempList.add(t.Course_master__r.course__c);
I tried to like this and it is working properly
List<List<String>> strList = new List<List<String>>();
List<Training_deal__c> td = [select name, Course_master__r.course__c from Training_deal__c];
for(Training_deal__c t : td){
List<String> tempList = new List<String>();
tempList.add('Training Deals');
tempList.add(t.name);
tempList.add(t.Course_master__r.course__c);
strList.add(tempList);
}

Compare two different SOQL queries

I am new to salesforce and I am stuck with a situation here.
I have a class which is scheduled every hour. I hit an account with the below code and an email is sent out to MAROPOST (Marketing automation tool). When this happen I want to track the Account and create a case or a log which says Welcome Email is sent so that I don't hit the same Account again.
Please help. Below is the working class. Please help
public class PD_WelcomeMaroPost {
public static string sendEmailThroughMaro(string myInpEmail) {
string successContacts = '';
string failureContacts = '';
// SQL to fetch FBO who Joined Today
list<Account> conts = new list<Account> ([SELECT name, Email_FLP_com__c,
(SELECT Id
FROM Stripe_Subscriptons__r
WHERE Start_Date__c= TODAY
AND Status__c='active'
AND Welcome_Email__C = false
LIMIT 1)
from account
where ID IN (
select Distributor__c
from Stripe_Subscripton__c
where Start_Date__c= TODAY
AND Status__c='active'
AND Welcome_Email__C = false)
AND Email_FLP_com__c != NULL
LIMIT 100]);
system.debug('>>>>>>>>>>' + conts);
overallEmail myEmail = new overallEmail();
List<Stripe_Subscripton__c> subsToUpdate = new List<Stripe_Subscripton__c>();
for(Account c : conts){
myEmail.email.campaign_id = 172;
myEmail.email.contact.Email = c.Email_FLP_com__c;
myEmail.email.contact.first_name = c.name;
/**MAp<String, String> tags = new Map<String, String>();
tags.put('firstName', c.name);
myEmail.email.tags = tags;**/
system.debug('#### Input JSON: ' + JSON.serialize(myEmail));
try{
String endpoint = 'http://api.maropost.com/accounts/1173/emails/deliver.json?auth_token=j-V4sx8ueUT7eKM8us_Cz5JqXBzoRrNS3p1lEZyPUPGcwWNoVNZpKQ';
HttpRequest req = new HttpRequest();
req.setEndpoint(endpoint);
req.setMethod('POST');
req.setHeader('Content-type', 'application/json');
req.setbody(JSON.serialize(myEmail));
Http http = new Http();
system.debug('Sending email');
HTTPResponse response = http.send(req);
system.debug('sent email');
string resultBodyGet = '';
resultBodyGet = response.getBody();
system.debug('Output response:' + resultBodyGet);
maroResponse myMaroResponse = new maroResponse();
myMaroResponse = (maroResponse) JSON.deserialize(resultBodyGet, maroResponse.class);
system.debug('#### myMaroResponse: ' + myMaroResponse);
if(myMaroResponse.message == 'Email was sent successfully')
successContacts = successContacts + ';' + c.Email_FLP_com__c;
else
failureContacts = failureContacts + ';' + c.Email_FLP_com__c;
}
catch (exception e) {
failureContacts = failureContacts + ';' + c.Email_FLP_com__c;
system.debug('#### Exception caught: ' + e.getMessage());
}
c.Stripe_Subscriptons__r[0].Welcome_Email__c = true;
subsToUpdate.add(c.Stripe_Subscriptons__r[0]);
}
Update subsToUpdate;
return 'successContacts=' + successContacts + '---' + 'failureContacts=' + failureContacts;
}
public class maroResponse {
public string message {get;set;}
}
public class overallEmail {
public emailJson email = new emailJson();
}
public class emailJson {
public Integer campaign_id;
public contactJson contact = new contactJson();
// Public Map<String, String> tags;
}
public class contactJson {
public string email;
public string first_name;
}
}
You're making a callout in a loop, there's governor limit of max 100 callouts. See Limits class to obtain current & max numbers programatically rather than hardcoding it.
Other than that it should be pretty simple change. First add your filter to the query and add a "subquery" (something like a JOIN) that pulls the related list of subscriptions
list<Account> conts = new list<Account> ([SELECT name, Email_FLP_com__c,
(SELECT Id
FROM Stripe_Subscriptions__r
WHERE Start_Date__c= TODAY
AND Status__c='active'
AND Welcome_Email__C = false
LIMIT 1)
from account
where ID IN (
select Distributor__c
from Stripe_Subscripton__c
where Start_Date__c= TODAY
AND Status__c='active'
AND Welcome_Email__C = false)
AND Email_FLP_com__c != NULL
LIMIT 100]);
Then it's just few lines more
List<Stripe_Subscription__c> subsToUpdate = new List<Stripe_Subscription__c>();
for(Account a : conts){
// do your maropost code here
a.Stripe_Subscriptions__r[0].Welcome_Email__c = true;
subsToUpdate.add(a.Stripe_Subscriptions__r[0]);
}
update subsToUpdate;
Of course you might want to set that checkbox to true only if callout went OK ;)
After reading your code, I don't see where you tried to accomplish this. If you post your attempt I'd be glad to help fix it.
Instead I'll give you different logic for what you are trying to do.
1.) create new checkbox field
2.) in batch query where box is not checked
3.) send email
4.) check checkbox
to answer your comment here is some sample code, you will need to fix it yourself, i am just making temp names
for(sobjectname gg:[your query]){
Send email;
gg.checkbox = checked;
update gg;
}
it'd be better to make it bulkified though
list<yourSObject> tobeupdated = new list<yourSObject>([Your query]);
for(yourSObject gg: tobeupdated){
send email;
gg.checkbox = true;
}
update tobeupdated;

Resources