• Hermann Ouré
  • NEWBIE
  • 170 Points
  • Member since 2019

  • Chatter
    Feed
  • 1
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 63
    Questions
  • 48
    Replies
Hello, 
I wrote a trigger to prevent duplicate records but now I am not even able to create new records.

Anytime I try to create a new record, I have the following error
[AccountRelationsTrigger: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A relation already exists between the 2 Accounts: [Related_Account__c] Class.AccountRelationHandler.createAccountRelation: line 20, column 1 Trigger.AccountRelationsTrigger: line 6, column 1]

here is the trigger
trigger AccountRelationsTrigger on Account_Relation__c (before insert, after insert) {
    
    
    if(Trigger.isAfter) {
       if(!AccountRelationHandler.isRecursion)
    	AccountRelationHandler.createAccountRelation(Trigger.New); 
    }
    
    if(Trigger.isBefore && Trigger.isInsert) {
        Set<Id> relatedAccIds = new Set<Id>();
        for(Account_Relation__c ar : Trigger.New) {
            relatedAccIds.add(ar.Related_Account__c);
        }
        List<Account_Relation__c> arList = [SELECT Related_Account__c FROM Account_Relation__c WHERE Related_Account__c = :relatedAccIds];
                                           
        
        for(Account_Relation__c relAcc : Trigger.New) {
            if(arList.size() > 0) {
                relAcc.Related_Account__c.addError('A relation already exists between the 2 Accounts');
            }
        }
     	
    }
    
}



here is the class:
public class AccountRelationHandler {
    
    public static Boolean isRecursion = false;
    public static void createAccountRelation(List<Account_Relation__c> accRelationList) {
        // We are creating the inverse records, so return now
        if(isRecursion) {
            return;
        }
        isRecursion = true;
        
        Map<Id, Account> accRelatedToAccount = new Map<Id, Account>(
        [SELECT Id, Name, (SELECT Account__c, Related_Account__c FROM Account_Relations__r) 
         FROM Account]);
        
        Account_Relation__c[] newRelations = new Account_Relation__c[0];
        for(Account_Relation__c acc : accRelationList) {
            newRelations.add(new Account_Relation__c(Name=acc.Name, Account__c=acc.Related_Account__c, Related_Account__c=acc.Account__c));
        
        }
        insert newRelations;
        isRecursion = false;
        
    }
}
Thanks for any help
 

Hello,
I am trying to write a trigger to stop user creating contact with the same email address. But I keep getting an error
 System.NullPointerException: Attempt to de-reference a null object
on line 8 for:

conMap.get(c.Id).Email
How can I fix this error
Thanks
 
trigger ContactDuplicate on Contact (before insert) {
    
    Map<Id, Contact> conMap = new Map<Id, Contact>([SELECT Id, Email FROM Contact WHERE Email != null]);
    System.debug('Map ' +conMap);
      
    if(Trigger.isBefore && Trigger.isInsert) {
        for(Contact c : Trigger.New) {
            if(c.Email != null && c.Email == conMap.get(c.Id).Email) {
                c.Email.addError('Duplicate Contact');
            }
        }
    }
}

 

Hello,
I wrote a batch and I am trying to reference a Set<Id> in the WHERE clause but I have an error:
System.QueryException: expecting a colon, found '{kA09E0000005mCySAI}'

How can I fix the error and reference my Set kesIds in the Dynamic SOQL?
Thanks

global class BatchArticleEmail implements Schedulable, Database.Batchable<SObject> {
    
    global string query;
    
    // To schedule batch 
    global void execute(SchedulableContext sc) {
		Id batchProcessId = Database.executeBatch(this);
	}

    // Constructor to query articles
    global BatchArticleEmail() {
        
        Set<Id> kesIds = new Set<Id>();
       
        List<Known_Error_Subscription__c> kesList = [SELECT KnowledgeKA__c FROM Known_Error_Subscription__c];
        for(Known_Error_Subscription__c kes : kesList) {
            kesIds.add(kes.KnowledgeKA__c);
        }
        
        query = 'Select Id, KnowledgeArticleId, Known_Error_Status__c FROM Knowledge__kav WHERE PublishStatus=\'Online\'' + 
                ' AND KnowledgeArticleId IN \''+kesIds+'\'';     
        System.debug('query BatchArticleEmail ' +query);
    }
Hello,

I have a child object called Known_Error_Subscription__c and anytime a client subscribe to an Article (parent object : Knowledge__kav), a record is automatically created on the child object Known_Error_Subscription__c
When the Article is archived, meaning when the PublishStatus is updated to 'Archived' on the parent object Knowledge__kav, I would like the related record on Known_Error_Subscription__c to be deleted.

I have created a Trigger but can't figure out what I am doing wrong.
Thanks
 
trigger Knowledge_kavTrigger on Knowledge__kav (after update) {
    
    List<Known_Error_Subscription__c> kesListToDelete = new List<Known_Error_Subscription__c>();
    
    for(Knowledge__kav kav : [SELECT KnowledgeArticleId, PublishStatus, (SELECT Knowledge__c FROM Known_Errors_Subscriptions__r) FROM Knowledge__kav 
             WHERE PublishStatus = 'Archived' AND Id IN :Trigger.New]) {
                 
        kesListToDelete.add(kav.Known_Errors_Subscriptions__r);
       
    }
    delete kesListToDelete;
    
}

 
Hello,
I am unable to fix the error 
System.NullPointerException: Attempt to de-reference a null object on my trigger.

Could someone help?
Thanks
 
trigger Knowledge_kavKnownErrorSubscription on Knowledge__kav (after insert, after update) {
    
    List<Known_Error_Subscription__c> kesList = new List<Known_Error_Subscription__c>();
    
    for(Knowledge__kav kav : [SELECT KnowledgeArticleId, Known_Error_Status__c, VersionNumber, (SELECT Knowledge__c FROM Known_Errors_Subscriptions__r)
                              FROM Knowledge__kav WHERE Id IN :Trigger.New]) {
                                                                              
            if(kav.KnowledgeArticleId != null && (Trigger.oldMap.get(kav.Id).LastPublishedDate != Trigger.newMap.get(kav.Id).LastPublishedDate)) {
            Known_Error_Subscription__c kes = kav.Known_Errors_Subscriptions__r;
            kes.Knowledge__c = kav.KnowledgeArticleId;
            kesList.add(kes);
            
        }
                                  
    }
    if(kesList.size() > 0) {
        update kesList;
    }
    

}

 
Hello,
I have created an aura component to allow client to follow /subscribe to an article.
When a user click on the button subscribe, a record is created in Salesforce
User-added image.
Until there the code behaves as expected.
The problem is when the user has subscribed, he needs to be able to unsubscribe by click on the same button
User-added imageBut when clicking the button I am not able to unsubscribe, the button remains to subscribed
User-added imageEven worst, anytime I click the button, a new record is created in salesforce.
The idea is to stop the client for subscribing more than once to the same article and be able to unsubscribe when clicking on the button

here is my code:
KnownErrorSubscription.comp
<aura:component controller="KnownErrorSubscriptionController" implements="forceCommunity:availableForAllPageTypes,flexipage:availableForAllPageTypes,force:hasRecordId" access="global">

<aura:attribute name="recordId" type="String"/>
    <aura:attribute name="isFollowed" type="Boolean" default="false"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
    <lightning:buttonStateful
        labelWhenOff="Subscribe"
        labelWhenOn="Subscribed"
        labelWhenHover="Unsubscribe"
        iconNameWhenOff="utility:add"
        iconNameWhenOn="utility:check"
        iconNameWhenHover="utility:close"
        state="{! v.isFollowed }"
        onclick="{! c.handleClick }"/>
	
</aura:component>
KnownErrorSubscriptionController.js
 
({
       doInit: function(component, event, helper) {
             let search = window.location.pathname;
             let result = search.substring(search.lastIndexOf("/") + 1);
             let action = component.get("c.isRecordExist");

             action.setParams({
                     urlNames : result
              });
              action.setCallback(this, function(data) {
                    let result = data.getReturnValue();
                     if(result){
                         component.set('v.isFollowed', 'true');
                      }
             });
             $A.enqueueAction(action);
         },

         handleClick : function(component, event, helper) {

              let search = window.location.pathname;
              let result = search.substring(search.lastIndexOf("/") + 1);
              let action = component.get("c.saveKnownIssue");
              
             action.setParams({
                  urlNames : result
             });

             action.setCallback(this, function(data) {
                  let result = data.getReturnValue();
                  if(result){
                        component.set('v.isFollowed', 'true');
                    }
              });
             $A.enqueueAction(action);
       }
})

KnownErrorSubscriptionController.apxc
 
public class KnownErrorSubscriptionController {
    
    @AuraEnabled
    public static Boolean isRecordExist(String urlNames) {
        List<User> userList = [SELECT Id, Name, ContactId, Contact.Name FROM User WHERE Id = :UserInfo.getUserId()];
        List<Knowledge__kav> kavList = new List<Knowledge__kav>();
        if(urlNames != null) {
            kavList = [SELECT Id, LastPublishedDate, Title, ArticleBody__c FROM Knowledge__kav WHERE UrlName =:urlNames];
        }
        
        if(userList.size() > 0 && kavList.size() > 0) {
        	List<Known_Error_Subscription__c> kESubscriptionList = [SELECT Contact__c, Knowledge__c FROM Known_Error_Subscription__c
                                                                    WHERE Contact__c =:userList[0].ContactId AND Knowledge__c =:kavList[0].Id];
            if(kESubscriptionList.size() > 0) {
            	return true;
            } else {
            	return false;
            }
                
        } else {
        	return false;
        }        
    } 
    
    @AuraEnabled
    public static Boolean saveKnownIssue(String urlNames, Boolean isFollowed) {
        List<User> userList = [SELECT Id, Name, ContactId, Contact.Name FROM User WHERE Id =:UserInfo.getUserId()];
        List<Knowledge__kav> kavList = new List<Knowledge__kav>();
        
        if(urlNames != null) {
            kavList = [SELECT Id, LastPublishedDate, Title, ArticleBody__c FROM Knowledge__kav WHERE UrlName =:urlNames];
        }
        Known_Error_Subscription__c kes = new Known_Error_Subscription__c();
        if(userList.size() > 0 && userList[0].ContactId != null) {
            kes.Contact__c = userList[0].ContactId;
        }
        
        if(kavList.size() > 0) {
            kes.Knowledge__c = kavList[0].Id;
            kes.Subscribed__c = true;
        }
        
        insert kes;
        return true;
        
    }
    

}





 
Hello,
I am trying to use the Ids that I store in a Set; in a String variable but I am unable to do so.
I have obviously an error: Variable Id does not exist. But I don't j=know how to fix it.
Could someone help?
Thanks

here is what I wrote:
public static String setSlackUserNickName(String businessUnit) {
        String channelName;
        Set<ID> headOfService_ids = new Set<ID>();
        
        Map<Id, Application_Parameters__c> headOfService = New Map<Id, Application_Parameters__c>(
            [SELECT Id, Head_of_Service__c FROM Application_Parameters__c WHERE Business_Unit__c = :businessUnit]);
     
        for(Application_Parameters__c app : headOfService.values()) {
            headOfService_ids.add(app.Head_of_Service__c);
        }
       
         
        channelName = ''+headOfService_ids.get(Id).CommunityNickname+'';

 
Hello,

I have an Apex class sending slack notification to a channel and I would like to update the code to send the notification to multiple slack channels.

Is Anyone familiar with Slack integration?

Here is my code
public without sharing class SlackNotificationSupport{
       
    public class slackRequest { 
        @InvocableVariable(label='caseNumber')
        public String caseNumber;
        @InvocableVariable(label='status')
        public String status;
        @InvocableVariable(label='nickName')
        public String nickname;
        @InvocableVariable(label='queue')
        public String queue;
        @InvocableVariable(label='accountTier')
        public String accountTier;
        @InvocableVariable(label='accountName')
        public String accountName;
        @InvocableVariable(label='subject')
        public String subject;
        @InvocableVariable(label='businessUnit')
    	public String businessUnit;
    } 
    

    public static String setChannelName(String queue) {

        String channelName;

        channelName = '#'+queue;
        channelName = channelName.toLowerCase('en');
        channelName = channelName.replaceAll('queue', 'bot');
        channelName = channelName.replaceAll('[_]', '-');
        return channelName;
    }

    @InvocableMethod(label='Publish to Slack')
    public static void publishToSlack(List<slackRequest> requests) {

        String webhookURL = system.label.Param_Slack_Token;
        String msg;
        String channelName;

        for(slackRequest r:requests){

            if (r.queue == 'internal'){
                System.debug('### SlackNotificationSupport new internal case');
                channelName = '#'+Label.Slack_Internal_Case_Channel;
                msg = 'A new internal case has been created : *'+r.caseNumber+'* - By User : (*'+r.accountName+'*) - Subject : (*'+r.subject+'*)';                
            }
            else if (r.queue == 'caseconcern'){
                System.debug('### SlackNotificationSupport new case concern');
                channelName = '#'+Label.Slack_Case_Concern_Channel;
                
                msg = 'A new Case Concern has been created : *'+r.caseNumber+'* - By User : (*'+r.nickName+' '+r.accountName+'* From *'+r.accountTier+'*) - Category : (*'+r.subject+'*)';
				msg += '\nLink to Case Concern : '+URL.getOrgDomainUrl().toExternalForm()+'/'+r.status;
                
            }
            // Team Leads
            else if (r.queue == 'Queue Team Leads') {
                channelName = setChannelName(r.queue);
                msg = 'A customer has opened a new case.\n>>>*'+
                    r.caseNumber+'* - '+r.subject;
                    System.debug('### SlackNotificationSupport Queue Team Leads');
            } // New Tier 1 Ticker
            else if (r.accountTier == 'Tier 1' && r.accountName != null && r.queue != null) {
                System.debug('### SlackNotificationSupport New Tier 1');
                channelName = setChannelName(r.queue);
                msg = 'The customer '+r.accountTier+' - *'+r.accountName+'* has opened a new case.\n>>>*'+
                    r.caseNumber+'* - '+r.subject;
            }// Assigned ticket, status to Open - Internal notification for awaiting feedback cases
            else if (r.nickname != null && r.status != null && r.caseNumber != null) {
                System.debug('### SlackNotificationSupport  Status x to Open');
                channelName = '@'+r.nickname;
                if(r.queue == 'internal_notification')msg = 'Salesforce Internal Case number *'+r.caseNumber+'* related to : *'+r.subject+'* - Status changed to : *'+r.status+'*.';
                else msg = 'Case number *'+r.caseNumber+'* has become '+r.status+'.';
            }

            // Generate JSON for request
            try {
                if (r.queue != null || r.nickname != null) {
                    System.debug('### SlackNotificationSupport Sending message');
                    JSONGenerator gen = JSON.createGenerator(true);
                    gen.writeStartObject(); //Inserts {
                    gen.writeStringField('text', msg);
                    gen.writeStringField('channel', channelName);
                    gen.writeStringField('username', 'bot-support');
                    gen.writeStringField('icon_emoji', ':smartplus:');
                    gen.writeEndObject(); //Inserts }
                    String body = gen.getAsString(); //Translates JSONGenerator to string to be passed to callout
                    System.debug('### SlackNotificationSupport body: '+ body);
                    System.enqueueJob(new qCallOut(webhookURL, 'POST', body)); // Send request
                }
                else {
                    System.debug('### SlackNotificationSupport Queue = '+ r.queue);
                    return;
                }
            } // try    
            catch (exception e){
                system.debug('### SlackNotificationSupport error:' + e);
            }
        } 
    }
   

    public class qCallOut implements System.Queueable, Database.AllowsCallouts {
         
        private final String url;
        private final String method;
        private final String body;
         
        public qCallOut(String url, String method, String body) {
            this.url = url;
            this.method = method;
            this.body = body;
        }
         
        public void execute(System.QueueableContext ctx) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint(url);
            req.setMethod(method);
            req.setBody(body);
            Http http = new Http();
            // to pass when process builder is invoked by another test class
            if(!Test.isRunningTest()){  
              HttpResponse res = http.send(req);
            }
        }
    }
}

 

Hello,
I am trying to include a Case Number of an email template for an email-to-case.
Basically, when a client sent an email to a closed case, he received an automatic email reply.
On the template I have added the merge field value {!Case.CaseNumber}
User-added imagebut the Case Number does not appear on the email reply sent to the client

User-added image

I believe that, to add the Case Number in the automatic email reply, I need to reference the CaseId somewhere in my code. But I have figured out how.
The tried to do 

mail.setTargetObjectId(c.Id);
But that does not work.
Here is my full code:
Apex class:
public class EmailManager {
    @future
    public static void sendEmailToCaseDeactivated(Set<Id> caseIds){
    
        List<Messaging.SingleEmailMessage> allmsg = new List<Messaging.SingleEmailMessage>();
        List<Case> lstCase = [SELECT Id, Status,ContactEmail FROM Case WHERE 
                              Status = 'Closed' AND
                              ContactEmail != Null AND
                              Id IN: caseIds];
        EmailTemplate templateId = [SELECT Id FROM EmailTemplate WHERE DeveloperName =:'Email_to_Case_Closed'];
       
        for(Case c : lstCase) {
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setTargetObjectId(UserInfo.getUserId());
            mail.setTemplateId(templateId.Id);
            String[] sendingTo = new String[]{c.ContactEmail}; 
            mail.setToAddresses(sendingTo); 
            mail.setSaveAsActivity(false);
            allmsg.add(mail);
        }               
        Messaging.sendEmail(allmsg, false);
    }
    
}
Apex Trigger: 
trigger IncomingEmailClosedCase on EmailMessage (before insert,after insert) {
    
    if(trigger.isBefore) { 
        Set<Id> sCaseIds = new Set<Id>();
        for(EmailMessage em: Trigger.New) {
            if (em.Incoming)
                 sCaseIds.add(em.parentId);   
        }
        if(!sCaseIds.isEmpty())
            EmailManager.sendEmailToCaseDeactivated(sCaseIds);
    }
    if(trigger.isAfter){
        Map<Id,Id> caseIdsToEmailMessageIds = new Map<Id,Id>();
        for(EmailMessage em: Trigger.New) {
            if (em.Incoming)
                caseIdsToEmailMessageIds.put(em.parentId,em.Id);   
        }
        set<Id> sMessageIdsToDelete = new Set<Id>();
        if(caseIdsToEmailMessageIds.isEmpty()) return;
        for(Case lstCase : [SELECT Id, Status,ContactEmail FROM Case WHERE 
                          Status = 'Closed' AND
                          ContactEmail != Null AND
                          Id IN: caseIdsToEmailMessageIds.keyset()]){
            if(caseIdsToEmailMessageIds.containsKey(lstCase.Id)){
                Id emId = caseIdsToEmailMessageIds.get(lstCase.Id);
                sMessageIdsToDelete.add(emId);
            } 
        } 
        if(!sMessageIdsToDelete.isEmpty())   delete [ select Id from EmailMessage where id in :sMessageIdsToDelete];
    }
}

 
Hello,
I have created a class and a trigger to be able to stop clients from sending email message on Closed Cases.
The code works as intended. We tend to communicate with Clients using the quick action Email under the Case Feed tab. But sometimes, clients try to communicate to us about new issues using an old email reply of a closed case.
Now, with the code I wrote, they receive an email informing them that the case is closed & that we are not communicating on the case anymore.
The code works as intended... But since I am still learning on the platform, I have the feeling that my code is cumbersome.
How can I optimise and make my code more efficient?
Thanks

Apex class:
 
public class EmailManager {
@future
public static void sendEmailToCaseDeactivated(Set<Id> caseIds){

    List<Messaging.SingleEmailMessage> allmsg = new List<Messaging.SingleEmailMessage>();
    List<Case> lstCase = [SELECT Id, Status,ContactEmail FROM Case WHERE 
                          Status = 'Closed' AND
                          ContactEmail != Null AND
                          Id IN: caseIds];
    EmailTemplate templateId = [SELECT Id FROM EmailTemplate WHERE DeveloperName =:'Smart_Community_Email_to_Case_Deactivated'];
   
    for(Case cas :  lstCase) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setTargetObjectId(UserInfo.getUserId());
        mail.setTemplateId(templateId.Id);
        String[] sendingTo = new String[]{cas.ContactEmail}; 
        mail.setToAddresses(sendingTo); 
        mail.setSaveAsActivity(false);
        allmsg.add(mail);
    }               
    Messaging.sendEmail(allmsg, false);
}

}

Apex Trigger: 
 
trigger IncomingEmailClosedCase on EmailMessage (before insert,after insert) {

if(trigger.isBefore) { 
    Set<Id> caseIds = new Set<Id>();
    for(EmailMessage em: Trigger.New) {
        if (em.Incoming)
             caseIds.add(em.parentId);   
    }
    if(!caseIds.isEmpty())
        EmailManager.sendEmailToCaseDeactivated(caseIds);
}
if(trigger.isAfter){
    Map<Id,Id> mapOfCaseVsEM = new Map<Id,Id>();
    for(EmailMessage em: Trigger.New) {
        if (em.Incoming)
            mapOfCaseVsEM.put(em.parentId,em.Id);   
    }
    set<Id> todeleteEM = new Set<Id>();
    if(mapOfCaseVsEM.isEmpty()) return;
    for(Case lstCase : [SELECT Id, Status,ContactEmail FROM Case WHERE 
                      Status = 'Closed' AND
                      ContactEmail != Null AND
                      Id IN: mapOfCaseVsEM.keyset()]){
        if(mapOfCaseVsEM.containsKey(lstCase.Id)){
            Id emId = mapOfCaseVsEM.get(lstCase.Id);
            todeleteEM.add(emId);
        } 
    } 
    if(!todeleteEM.isEmpty())   delete [ select Id from EmailMessage where id in :todeleteEM];
}
}

 
Hello,
I have created an aura component to be able to display the value of an account field (Tip To Smarties) on the related Case.
User-added imageBut the value of the field do not display when I put the component on the case page. It does work when I put the component on the Account page but that's not what I am looking for.

How can I display the value when putting the aura component on the Case page?
Thanks

aura component:
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    
    <aura:attribute name="recordId" type="Id"/>
    
    
     <lightning:recordViewForm recordId="{!v.recordId}" objectApiName="Account">
        <div class="slds-box slds-theme_default">
            <lightning:outputField fieldName="Tip_To_Smarties__c" />
        </div>
    </lightning:recordViewForm>
    
</aura:component>

 

Hello, 
I am trying to create a trigger to stop clients from sending emails on Case closed. But it doesn't work.
Could someone help?
Thanks,

Apex Class:

public class EmailManager {
    
    public static void sendEmailToCaseDeactivated(){
        
        //Use classic email template
        EmailTemplate templateId = [SELECT Id FROM EmailTemplate WHERE DeveloperName =:'Smart_Community_Email_to_Case_Deactivated'];
        List<Messaging.SingleEmailMessage> allmsg = new List<Messaging.SingleEmailMessage>();
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        
        mail.setTargetObjectId(UserInfo.getUserId());
        mail.setTemplateId(templateId.Id);
        mail.setSaveAsActivity(false);
        allmsg.add(mail);
        
        Messaging.sendEmail(allmsg, false);
        
    }
        
}
Apex Trigger:
trigger IncomingEmailClosedCase on EmailMessage (before insert) {
   
    Set<Id> caseIds = new Set<Id>();
    
    for(EmailMessage em: Trigger.New) {
        if (em.Incoming == true) caseIds.add(em.Id);   
    }
    
    List<Case> lstCase = new List<Case>([SELECT Id, Status FROM Case WHERE Status = 'Closed' AND Id In: caseIds]);
    
    if(lstCase.size() > 0) {
        EmailManager.sendEmailToCaseDeactivated();
    }
   
}


 

Hello,
I am trying to query Articles on the Knowledge__kav object related to Cases. But I have the following error
Didn't understand relationship 'Knowledge__kavs' in FROM part of query call. 
How can I make a subquery on Knowledge__kav?
Map<Id, Case> caseMap = new Map<Id, Case>([SELECT Id, First_JIRA_Issue_Number__c, (SELECT Id FROM Knowledge__kavs) FROM Case WHERE Id IN :caseIdJiraIssueId.keyset()]);


 

Hello,

I have a lookup field (First_JIRA_Issue_Number__c) on Case object that needs to be updated with the Jira Number when the related issue is created.

Basically from a Case, I have the possibility to create a Jira Issue (object: JIRA_Issue__c).
User-added image

When the Jira Issue is created, the field First_JIRA_Issue_Number__c needs to be updated with the Jira Number. In this example the field First Jira Issue Number on Case is updated with JIRA000692
User-added image

I have created a class and a trigger but it does work.
Could someone help.
Thanks

Apex Class

public class CaseManager {
    
    public static void updateJiraIssue(List<JIRA_Issue__c> lstJira) {
        Set<Id> jiraIds = new Set<Id>();
       
        for(JIRA_Issue__c jissue : lstJira){
            if(jissue.Case__c != null){
                jiraIds.add(jissue.Id);  
            }
        }
        
        List<Case> lstCase = new List<Case>([SELECT Id, First_JIRA_Issue_Number__c,(SELECT Id, Case__c FROM JIRA_Issues__r) FROM Case WHERE First_JIRA_Issue_Number__c IN: jiraIds]);
        System.debug('##### lstCase ' + lstCase.Size());
        
        if(lstCase.size()>0){
            for(Case c: lstCase){
                List<JIRA_Issue__c> lstJiraIssue = new List<JIRA_Issue__c>();
                lstJiraIssue = c.JIRA_Issues__r;
                if(lstJiraIssue.size() > 0){
                    for(JIRA_Issue__c ji: lstJiraIssue){
                        if(ji.Case__c == c.Id){
                            c.First_JIRA_Issue_Number__c = ji.Id;
                        }
                        
                    }
                    
                }
    
       		}
            update lstCase;
        }
        
      
    }

}
Apex Trigger:
 
trigger CaseJiraIssueNumber on JIRA_Issue__c (after insert) {
    if(trigger.isAfter){
        CaseManager.updateJiraIssue(Trigger.New);
    }

}

 
Hello,
For a particular case, I have the possibility to create a Jira issue (in custom object: JIRA_Issue__c)  and an Article for Known Errors (in object Knowledge__kav)

Jira Issue:
User-added image

known error Article:

User-added image


In this example I have create a Jira Issue (JIRA000659) and an Article for the case 00161455.

What I am struggling with is that the lookup field Jira Issue on the article (Knowledge__kav object) needs to be update with the Jira Number (JIRA000659). Only a Jira Issue can be created before an article is created. Alternatively a Jira Issue can also be created after an article has been created. In both case the field Jira Issue  on Knowledge has to be updated with the Jira Issue Number JIRA000659 associated to the case (00161455)

I have written a class and created a trigger on the custom object JIRA_Issue__c.
But nothing happens, I can't get the right logic.

Could someone help?
Thanks

Apex class
public class KnowledgeKavManager {
    
    public static void updateJiraIssue(List<JIRA_Issue__c> lstJira) {
        Set<Id> kavIds = new Set<Id>();
        //Id KnownErrorRecordTypeId = schema.SObjectType.Knowledge__kav.getRecordTypeInfosByName().get('Known_Error').getRecordTypeId();
        
        for(JIRA_Issue__c jissue : lstJira){
            if(jissue.Case__c != null){
                kavIds.add(jissue.Id);      
            }
        }
        
        //Get Articles where related problem Id = Jira case__c Id
        //Map<Id,Knowledge__kav> KavMap = new Map<Id,Knowledge__kav>([SELECT Id FROM Knowledge__kav WHERE Related_Problem__c IN: kavIds AND RecordTypeId =:KnownErrorRecordTypeId]);
        Map<Id,Knowledge__kav> KavMap = new Map<Id,Knowledge__kav>([SELECT Id FROM Knowledge__kav WHERE Related_Problem__c IN: kavIds]);
        
        List<Knowledge__kav> lstKav = new List<Knowledge__kav>();
        
        for(Knowledge__kav kav: KavMap.values()){
            System.debug('##### KavMap.values ' + KavMap.values() );
            
        	if(KavMap != null && KavMap.containskey(kav.Related_Problem__c)) {
            
                List<JIRA_Issue__c> lstJiraIssue = new List<JIRA_Issue__c>();
                for(JIRA_Issue__c ji: lstJiraIssue){
                    
                    if(ji.Case__c == kav.Related_Problem__c){
                        kav.JIRA_Issue__c = ji.Id;
                   		lstKav.add(kav);
                    }
                    
                }
            }
            update lstKav;           
        }
      
    }

}

Apex Trigger
trigger JiraLinkKnownErrorArticle on JIRA_Issue__c (after insert, after update) {
    if(trigger.isAfter){
        KnowledgeKavManager.updateJiraIssue(Trigger.New);
    }

}



 

Hello,
For a particular case, I have the possibility to create a Jira issue and an Article for Known Errors
Jira Issue:
User-added image

known error Article:
User-added imageIn this example I have create a Jira Issue and an Article for the case 00161455.

What I am struggling with is that the field Jira_Issue__c on the article (Knowledge object) needs to be update with the Jira Number (JIRA000659). Only a Jira Issue can be created before an article is created. Alternatively a Jira Issue can also be created after an article has been created. In both case the field Jira Issue on Knowledge has to be updated with the Jira Number associated to the case (00161455)

If someone could give me the logic?

Thanks

Hello,
I have an approval process on on Custom object. And I would like to update a custom field "Approver Name" with the name of the "Actual Approver"
So let's say the name the of Actual Approver is "Frank Karl" I would like the custom field "Approver Name" to be automatically updated with "Frank Karl"
User-added image
How can I do it with out of the box functionnality?
Thanks
 

Hello,
I would like to stop receiving clients email on closed cases.
Sometimes we communicate to clients through the Email action on Case Feed
But at time, even though the case is CLOSED, clients try to communicate to us by replying on old email feeds and we miss that.
I would like to be able to send an auto-response email to inform the client that the case is closed and that we are not communicating on the case anymore.

I tried to do a process builder on EmailMessage with 
[EmailMessage].Incoming equals boolean TRUE
[EmailMessage].Parent.Status equals picklist CLOSED
But with that I am unable to select email alerts as an action
User-added image

I also tried with a Workflow on Case Object 
Rule Criteria(Email Message: Is IncomingEQUALSTrue) AND (Case: StatusEQUALSClosed)
Workflow action: Email Alert.
But it doesn't work either
User-added image

How can I stop client for sending email a case closed and send an automatic email to inform them that they should open a new case through the right channel?

Can it be done via a process or do I need to create a trigger?

Thanks,
Hello,
How can I calclulate a Due Date / target date excluding business Days and Holidays?
I have a date/time field called "First_Reply_Date__c" and when its filled, I would like the "Target_Date__c" field to be updated with the next working day.
For example, let's say the "First_Reply_Date__c" field is filled on a Friday
First_Reply_Date__c : 25/10/2020 1:00 pm;
Then "Target_Date__c" will be on the Monday 28/10/2020 1:00pm

How could I do it using a code? 
Thanks,
Hello,

I have deployed a Node.js app to heroku but the "Update Contact Information Button" is not responding. When pressing the button, the contact in Salesforce should be updated. The app is based on the trailhead (Quick Start: Heroku Connect https://trailhead.salesforce.com/content/learn/projects/quickstart-heroku-connect) That I have updated to fit my requirement.

The integration with heroku connect was successful
User-added image

But when I press the update button on the app nothing happens!

User-added image
here are my codes:

server.js:
const express = require('express');
const bodyParser = require('body-parser');
const pg = require('pg');

const app = express();

app.set('port', process.env.PORT || 5000);

app.use(express.static('public'));
app.use(bodyParser.json());

app.post('/update', function(req, res) {
    pg.connect(process.env.DATABASE_URL, function (err, conn, done) {
        // watch for any connect issues
        if (err) console.log(err);
        conn.query(
            'UPDATE salesforce.Contact SET Phone = $1, MobilePhone = $1 WHERE LOWER(FirstName) = LOWER($2) AND LOWER(LastName) = LOWER($3) AND LOWER(Email) = LOWER($4)',
            [req.body.phone.trim(), req.body.firstName.trim(), req.body.lastName.trim(), req.body.email.trim()],
            function(err, result) {
                if (err != null || result.rowCount == 0) {
                  conn.query('INSERT INTO salesforce.Contact (Phone, MobilePhone, FirstName, LastName, Email) VALUES ($1, $2, $3, $4, $5)',
                  [req.body.phone.trim(), req.body.phone.trim(), req.body.firstName.trim(), req.body.lastName.trim(), req.body.email.trim()],
                  function(err, result) {
                    done();
                    if (err) {
                        res.status(400).json({error: err.message});
                    }
                    else {
                        // this will still cause jquery to display 'Record updated!'
                        // eventhough it was inserted
                        res.json(result);
                    }
                  });
                }
                else {
                    done();
                    res.json(result);
                }
            }
        );
    });
});

app.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});

index.html:
 
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>CRM AXG</title>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <style>
        body {
            padding-top: 60px;
        }
    </style>
    <script>
        $(function() {
            $("#phoneChangerForm").submit(function(event) {
                event.preventDefault();

                var errorMessage = $("#errorMessage");
                var error = $("#error");
                error.hide();

                $("#message").hide();

                var firstName = $("#firstName").val();
                var lastName = $("#lastName").val();
                var email = $("#email").val();
                var phone = $("#phone").val();

                if (firstName.length == 0 || lastName.length == 0 || email.length == 0 || phone.length == 0) {
                    errorMessage.text("All of the fields are required.");
                    error.show();
                }
                else {
                    $.ajax({
                        url: event.target.action,
                        method: event.target.method,
                        data: JSON.stringify({
                            firstName: firstName,
                            lastName: lastName,
                            email: email,
                            phone: phone
                        }),
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        success: function(data) {
                            $("#firstName").val("");
                            $("#lastName").val("");
                            $("#email").val("");
                            $("#phone").val("");
                            $("#messageMessage").text("Record updated!");
                            $("#message").show();
                        },
                        error: function(err) {
                            errorMessage.text(err.responseJSON.error);
                            error.show();
                        }
                    })
                }
            });
        });

    </script>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <a class="navbar-brand" href="/">Contact Information</a>
            </div>
        </div>
    </nav>

    <div class="container">
        <form id="phoneChangerForm" action="/update" method="post" style="width: 400px">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">Contact Information</h3>
                </div>
                <div class="panel-body">
                    <div class="form-group">
                        <label for="firstName">First Name</label>
                        <input type="text" class="form-control" id="firstName" placeholder="For verification" required>
                    </div>
                    <div class="form-group">
                        <label for="lastName">Last Name</label>
                        <input type="text" class="form-control" id="lastName" placeholder="For verification" required>
                    </div>
                    <div class="form-group">
                        <label for="email">Email</label>
                        <input type="email" class="form-control" id="email" placeholder="For verification" required>
                    </div>
                    <div class="form-group">
                        <label for="phone">Phone</label>
                        <input type="tel" class="form-control" id="phone" placeholder="New Phone Number" required>
                    </div>
                </div>
                <div class="panel-footer">
                    <div id="message" class="alert alert-info" role="alert" style="display: none;">
                        <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
                        <span id="messageMessage"></span>
                    </div>
                    <div id="error" class="alert alert-danger" role="alert" style="display: none;">
                        <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
                        <span class="sr-only">Error:</span>
                        <span id="errorMessage"></span>
                    </div>
                    <button type="submit" class="btn btn-primary">Update Contact Information</button>
                </div>
            </div>
        </form>
    </div>
</body>
</html>

package.json:
 
{
  "name": "heroku-crm-axg-app",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/hermy2/heroku-crm-axg-app.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/hermy2/heroku-crm-axg-app/issues"
  },
  "homepage": "https://github.com/hermy2/heroku-crm-axg-app#readme",
  "dependencies": {
    "app.json": "^1.3.0",
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "pg": "^8.3.3"
  }
}


​​​​​​​
Hello, 
I wrote a trigger to prevent duplicate records but now I am not even able to create new records.

Anytime I try to create a new record, I have the following error
[AccountRelationsTrigger: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, A relation already exists between the 2 Accounts: [Related_Account__c] Class.AccountRelationHandler.createAccountRelation: line 20, column 1 Trigger.AccountRelationsTrigger: line 6, column 1]

here is the trigger
trigger AccountRelationsTrigger on Account_Relation__c (before insert, after insert) {
    
    
    if(Trigger.isAfter) {
       if(!AccountRelationHandler.isRecursion)
    	AccountRelationHandler.createAccountRelation(Trigger.New); 
    }
    
    if(Trigger.isBefore && Trigger.isInsert) {
        Set<Id> relatedAccIds = new Set<Id>();
        for(Account_Relation__c ar : Trigger.New) {
            relatedAccIds.add(ar.Related_Account__c);
        }
        List<Account_Relation__c> arList = [SELECT Related_Account__c FROM Account_Relation__c WHERE Related_Account__c = :relatedAccIds];
                                           
        
        for(Account_Relation__c relAcc : Trigger.New) {
            if(arList.size() > 0) {
                relAcc.Related_Account__c.addError('A relation already exists between the 2 Accounts');
            }
        }
     	
    }
    
}



here is the class:
public class AccountRelationHandler {
    
    public static Boolean isRecursion = false;
    public static void createAccountRelation(List<Account_Relation__c> accRelationList) {
        // We are creating the inverse records, so return now
        if(isRecursion) {
            return;
        }
        isRecursion = true;
        
        Map<Id, Account> accRelatedToAccount = new Map<Id, Account>(
        [SELECT Id, Name, (SELECT Account__c, Related_Account__c FROM Account_Relations__r) 
         FROM Account]);
        
        Account_Relation__c[] newRelations = new Account_Relation__c[0];
        for(Account_Relation__c acc : accRelationList) {
            newRelations.add(new Account_Relation__c(Name=acc.Name, Account__c=acc.Related_Account__c, Related_Account__c=acc.Account__c));
        
        }
        insert newRelations;
        isRecursion = false;
        
    }
}
Thanks for any help
 

Hello,
I wrote a batch and I am trying to reference a Set<Id> in the WHERE clause but I have an error:
System.QueryException: expecting a colon, found '{kA09E0000005mCySAI}'

How can I fix the error and reference my Set kesIds in the Dynamic SOQL?
Thanks

global class BatchArticleEmail implements Schedulable, Database.Batchable<SObject> {
    
    global string query;
    
    // To schedule batch 
    global void execute(SchedulableContext sc) {
		Id batchProcessId = Database.executeBatch(this);
	}

    // Constructor to query articles
    global BatchArticleEmail() {
        
        Set<Id> kesIds = new Set<Id>();
       
        List<Known_Error_Subscription__c> kesList = [SELECT KnowledgeKA__c FROM Known_Error_Subscription__c];
        for(Known_Error_Subscription__c kes : kesList) {
            kesIds.add(kes.KnowledgeKA__c);
        }
        
        query = 'Select Id, KnowledgeArticleId, Known_Error_Status__c FROM Knowledge__kav WHERE PublishStatus=\'Online\'' + 
                ' AND KnowledgeArticleId IN \''+kesIds+'\'';     
        System.debug('query BatchArticleEmail ' +query);
    }
Hello,

I have a child object called Known_Error_Subscription__c and anytime a client subscribe to an Article (parent object : Knowledge__kav), a record is automatically created on the child object Known_Error_Subscription__c
When the Article is archived, meaning when the PublishStatus is updated to 'Archived' on the parent object Knowledge__kav, I would like the related record on Known_Error_Subscription__c to be deleted.

I have created a Trigger but can't figure out what I am doing wrong.
Thanks
 
trigger Knowledge_kavTrigger on Knowledge__kav (after update) {
    
    List<Known_Error_Subscription__c> kesListToDelete = new List<Known_Error_Subscription__c>();
    
    for(Knowledge__kav kav : [SELECT KnowledgeArticleId, PublishStatus, (SELECT Knowledge__c FROM Known_Errors_Subscriptions__r) FROM Knowledge__kav 
             WHERE PublishStatus = 'Archived' AND Id IN :Trigger.New]) {
                 
        kesListToDelete.add(kav.Known_Errors_Subscriptions__r);
       
    }
    delete kesListToDelete;
    
}

 
Hello,
I am unable to fix the error 
System.NullPointerException: Attempt to de-reference a null object on my trigger.

Could someone help?
Thanks
 
trigger Knowledge_kavKnownErrorSubscription on Knowledge__kav (after insert, after update) {
    
    List<Known_Error_Subscription__c> kesList = new List<Known_Error_Subscription__c>();
    
    for(Knowledge__kav kav : [SELECT KnowledgeArticleId, Known_Error_Status__c, VersionNumber, (SELECT Knowledge__c FROM Known_Errors_Subscriptions__r)
                              FROM Knowledge__kav WHERE Id IN :Trigger.New]) {
                                                                              
            if(kav.KnowledgeArticleId != null && (Trigger.oldMap.get(kav.Id).LastPublishedDate != Trigger.newMap.get(kav.Id).LastPublishedDate)) {
            Known_Error_Subscription__c kes = kav.Known_Errors_Subscriptions__r;
            kes.Knowledge__c = kav.KnowledgeArticleId;
            kesList.add(kes);
            
        }
                                  
    }
    if(kesList.size() > 0) {
        update kesList;
    }
    

}

 
Hello,
I have created an aura component to be able to display the value of an account field (Tip To Smarties) on the related Case.
User-added imageBut the value of the field do not display when I put the component on the case page. It does work when I put the component on the Account page but that's not what I am looking for.

How can I display the value when putting the aura component on the Case page?
Thanks

aura component:
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    
    <aura:attribute name="recordId" type="Id"/>
    
    
     <lightning:recordViewForm recordId="{!v.recordId}" objectApiName="Account">
        <div class="slds-box slds-theme_default">
            <lightning:outputField fieldName="Tip_To_Smarties__c" />
        </div>
    </lightning:recordViewForm>
    
</aura:component>

 

Hello,

I have a lookup field (First_JIRA_Issue_Number__c) on Case object that needs to be updated with the Jira Number when the related issue is created.

Basically from a Case, I have the possibility to create a Jira Issue (object: JIRA_Issue__c).
User-added image

When the Jira Issue is created, the field First_JIRA_Issue_Number__c needs to be updated with the Jira Number. In this example the field First Jira Issue Number on Case is updated with JIRA000692
User-added image

I have created a class and a trigger but it does work.
Could someone help.
Thanks

Apex Class

public class CaseManager {
    
    public static void updateJiraIssue(List<JIRA_Issue__c> lstJira) {
        Set<Id> jiraIds = new Set<Id>();
       
        for(JIRA_Issue__c jissue : lstJira){
            if(jissue.Case__c != null){
                jiraIds.add(jissue.Id);  
            }
        }
        
        List<Case> lstCase = new List<Case>([SELECT Id, First_JIRA_Issue_Number__c,(SELECT Id, Case__c FROM JIRA_Issues__r) FROM Case WHERE First_JIRA_Issue_Number__c IN: jiraIds]);
        System.debug('##### lstCase ' + lstCase.Size());
        
        if(lstCase.size()>0){
            for(Case c: lstCase){
                List<JIRA_Issue__c> lstJiraIssue = new List<JIRA_Issue__c>();
                lstJiraIssue = c.JIRA_Issues__r;
                if(lstJiraIssue.size() > 0){
                    for(JIRA_Issue__c ji: lstJiraIssue){
                        if(ji.Case__c == c.Id){
                            c.First_JIRA_Issue_Number__c = ji.Id;
                        }
                        
                    }
                    
                }
    
       		}
            update lstCase;
        }
        
      
    }

}
Apex Trigger:
 
trigger CaseJiraIssueNumber on JIRA_Issue__c (after insert) {
    if(trigger.isAfter){
        CaseManager.updateJiraIssue(Trigger.New);
    }

}

 
Hello,
For a particular case, I have the possibility to create a Jira issue (in custom object: JIRA_Issue__c)  and an Article for Known Errors (in object Knowledge__kav)

Jira Issue:
User-added image

known error Article:

User-added image


In this example I have create a Jira Issue (JIRA000659) and an Article for the case 00161455.

What I am struggling with is that the lookup field Jira Issue on the article (Knowledge__kav object) needs to be update with the Jira Number (JIRA000659). Only a Jira Issue can be created before an article is created. Alternatively a Jira Issue can also be created after an article has been created. In both case the field Jira Issue  on Knowledge has to be updated with the Jira Issue Number JIRA000659 associated to the case (00161455)

I have written a class and created a trigger on the custom object JIRA_Issue__c.
But nothing happens, I can't get the right logic.

Could someone help?
Thanks

Apex class
public class KnowledgeKavManager {
    
    public static void updateJiraIssue(List<JIRA_Issue__c> lstJira) {
        Set<Id> kavIds = new Set<Id>();
        //Id KnownErrorRecordTypeId = schema.SObjectType.Knowledge__kav.getRecordTypeInfosByName().get('Known_Error').getRecordTypeId();
        
        for(JIRA_Issue__c jissue : lstJira){
            if(jissue.Case__c != null){
                kavIds.add(jissue.Id);      
            }
        }
        
        //Get Articles where related problem Id = Jira case__c Id
        //Map<Id,Knowledge__kav> KavMap = new Map<Id,Knowledge__kav>([SELECT Id FROM Knowledge__kav WHERE Related_Problem__c IN: kavIds AND RecordTypeId =:KnownErrorRecordTypeId]);
        Map<Id,Knowledge__kav> KavMap = new Map<Id,Knowledge__kav>([SELECT Id FROM Knowledge__kav WHERE Related_Problem__c IN: kavIds]);
        
        List<Knowledge__kav> lstKav = new List<Knowledge__kav>();
        
        for(Knowledge__kav kav: KavMap.values()){
            System.debug('##### KavMap.values ' + KavMap.values() );
            
        	if(KavMap != null && KavMap.containskey(kav.Related_Problem__c)) {
            
                List<JIRA_Issue__c> lstJiraIssue = new List<JIRA_Issue__c>();
                for(JIRA_Issue__c ji: lstJiraIssue){
                    
                    if(ji.Case__c == kav.Related_Problem__c){
                        kav.JIRA_Issue__c = ji.Id;
                   		lstKav.add(kav);
                    }
                    
                }
            }
            update lstKav;           
        }
      
    }

}

Apex Trigger
trigger JiraLinkKnownErrorArticle on JIRA_Issue__c (after insert, after update) {
    if(trigger.isAfter){
        KnowledgeKavManager.updateJiraIssue(Trigger.New);
    }

}



 

Hello,
I have an approval process on on Custom object. And I would like to update a custom field "Approver Name" with the name of the "Actual Approver"
So let's say the name the of Actual Approver is "Frank Karl" I would like the custom field "Approver Name" to be automatically updated with "Frank Karl"
User-added image
How can I do it with out of the box functionnality?
Thanks
 

Hello,
How can I calclulate a Due Date / target date excluding business Days and Holidays?
I have a date/time field called "First_Reply_Date__c" and when its filled, I would like the "Target_Date__c" field to be updated with the next working day.
For example, let's say the "First_Reply_Date__c" field is filled on a Friday
First_Reply_Date__c : 25/10/2020 1:00 pm;
Then "Target_Date__c" will be on the Monday 28/10/2020 1:00pm

How could I do it using a code? 
Thanks,

Hello,
I am trying to stop clients from commenting on Closed Cases in client portal.

I am using a trigger on CaseComment. But the trigger does not work as clients can still comments on closed case.
Alternatively if someone has another suggestion that would stop clients from commenting on Closed Cases.
Please suggest alternatives.

Thanks
 

trigger ClosedCaseComment on CaseComment (before insert) {
    
    Set<Id> parentCase=new Set<Id>();
    
	Map<Id,Case> mapCase=new Map<Id,Case>();
	for (CaseComment t: Trigger.new) {
		parentCase.add(t.ParentId);
	}
    
	List<Case> lstCase=[Select Id,Status from case where Id in :parentCase ];
	for(case c: lstCase){
		mapCase.put(c.Id,c);
	}

	for (CaseComment t: Trigger.new){
		if(mapCase.containskey(t.ParentId)) {
        
			if(mapCase.get(t.ParentId).Status=='Closed' && System.Userinfo.getUserType() == 'Standard'){
				t.addError('You cannot add comments to closed cases.');		
			}
		}
	}

}
 



 

Hello,

I have created a trigger to update a custom date/time field (called First_Aircall_Logged__c).
Basically when a (aircall) task is created on a Case. The trigger should update the field First_Aircall_Logged__c with the task CreatedDate. 
But by trigger is not working.
A actually have an error 
System.ListException: List index out of bounds: 0
Trigger.AircallTaskTrigger: line 17, column 1: []

17: c.First_Aircall_Logged__c = c.tasks[0].CreatedDate;

How can I fix the trigger
Thank you
trigger AircallTaskTrigger on Task (after insert, after update) {
   
    Set<Id> caseIds = new Set<Id>();
   
    for(Task t: Trigger.New) {
        caseIds.add(t.WhatId);
    }
   
	//List<Case> toBeUpdateCase = [SELECT Id, First_Aircall_Logged__c, (SELECT Id, CreatedDate FROM Tasks) FROM Case WHERE Id IN: caseIds];
    Map<Id, Case> caseAircallTask = new Map<Id, Case> ([SELECT Id, First_Aircall_Logged__c, (SELECT Id FROM Tasks WHERE CallDisposition LIKE '%aircall%') 
                                                        FROM Case WHERE Id IN: caseIds]);
   
    if(caseAircallTask.size() > 0) { 
        for(Case c :caseAircallTask.values()) {
       
            System.debug('Cases with Aircall Task ' + caseAircallTask);
            c.First_Aircall_Logged__c = c.tasks[0].CreatedDate;
   	 	 }
    }
   
    update caseAircallTask.values();
}

 
Hello,

I am trying to create a trigger to uncheck a checkbox field on Account called "Active Order".
Basically when an Order has benn deleted from an account and there is no Order remaining for the Account, the trigger should uncheck Active Order. 

No Order:
User-added image
Uncheck Active Order on Account
User-added image

Can't get my trigger working properly
 
trigger AccountActiveOrderTrigger on Account (after delete) {
    
    List<Order> lstOrder = new List<Order>();
    
    //Get Accounts with orders 
    Map<Id, Account> accWithOrders = new Map<Id, Account>([SELECT Id, Name, Active_Order__c, (SELECT Id FROM Orders)
                                                          FROM Account WHERE Id IN: Trigger.old]);
    
    //Iterate through each Accounts
    for(account a : Trigger.old) {
        System.debug('Accounts with orders' +accWithOrders.get(a.Id).Orders.size());
        
        //Check if an Account has an order
        if(accWithOrders.get(a.Id).Orders.size() == 0) {
            a.Active_Order__c = False;
           	
        } 
        
     update a;
    }
 
}

Thank you
Hello,

I have a code coverage of 100% for my trigger but uploading my packages to production I have an error 
Code Coverage Failure
Your code coverage is 74%. You need at least 75% coverage to complete this deployment.

I really don't understand why when my code is covered 100%

User-added image

my Trigger:
 
trigger CaseConcernAircallDateTrigger on Task (after insert) {
   
    List<Case>  cList = new List<Case>();
    for(Task t: Trigger.New) {
        if(t.WhatId!=Null && t.whatId.getsObjectType() == Case.sObjectType){
            Case c = new Case();
            c.Id = t.whatId;
            c.Last_Aircall_Logged__c = t.CreatedDate;
            cList.add(c);
        }
    }
   
    if(cList.size() > 0) update cList;
}

my Test class:
 
@isTest
public class CaseConcernAircallDateTriggerTest {
    @isTest static void testAircallDateUpdate() {
        
        
        Contact con = new Contact (FirstName = 'First Name',LastName = 'Test');
        insert con;
        
        Case c = new Case(Status = 'New',ContactId = con.Id,Phone_Number__c = '123456789');
        insert c;
        
        Task t = new Task(Subject = 'Test', WhatId = c.Id);
        insert t;
       
        c.Id = t.WhatId;
        c.Last_Aircall_Logged__c = t.CreatedDate;
        update c;
       
    }
}

Thank you
 
Hello,

I have written a class for send Slack Notification anytime a Community Post or Answer is made in our client portal. But my test class only cover 54% of my code. I struggle to write a test for the JSON Generator as show on the pic

User-added image
How can I test JSON Generator in my class
Thanks!

here is my code:
 
public class SlackNotificationCommunityPost {
    
    /*
    -------------------------------------------------------------------------------------------------
    -- - Description   : Class to send Slack notification based on QuestionPost created on Community
    -- -----------  ----  -------  ------------------------------------------------------------------
     */
    
    public class slackRequest {
        //Use @InvocableVariable to call Process Builder
        @InvocableVariable(label='title')
        public String title; 
        
        @InvocableVariable(label='id')
        public String id; 
        
        @InvocableVariable(label='name')
        public String name;   
        
        //**H.O: (CODE UPDATE) Answer to Community Post 
        @InvocableVariable(label='type')
        public String type;
    }
    
    @InvocableMethod(label='Publish New Community posts to Slack')
    public static void publishNewCommunityPostsToSlack(List<slackRequest> requests) {

        //String webhookURL='https://hooks.slack.com/services/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';
        String webhookURL = system.label.Param_Slack_Token;
        String msg;
        String channelName;
        
        for(slackRequest r:requests){
            
            //check if the post has and Id, name, title
            if(r.id != null && r.name != null && r.title != null && r.type == 'QuestionPost') {
                System.debug('### SlackNotificationCommunityPosts new post');
                channelName = '#' +Label.Slack_Community_Channel;
                msg = 'A new community post has been created : *'+r.title+'* - By User : (*'+r.name+'*)';
                msg += '\nLink to Community post : '+Network.communitiesLanding().getUrl()+'question/'+r.id;
             
            //**H.O: (Statement Update) Answer to Community Post
            } else if (r.type != 'QuestionPost') {
                System.debug('### SlackNotificationCommunityPosts answers');
                channelName = '#' +Label.Slack_Community_Channel;
                msg = '(*'+r.name+'*) has written an answer to Community post : '+Network.communitiesLanding().getUrl()+'question/'+r.id;
                
            }
            
            //Generate JSON for request
            try {
                if (r.id != null && r.title !=null && r.name != null ) {
                   System.debug('### SlackNotificationCommunityPosts sending message');
                   JSONGenerator gen = JSON.createGenerator(true);
                    gen.writeStartObject(); //Inserts {
                    gen.writeStringField('text', msg);
                    gen.writeStringField('channel', channelName);
                    gen.writeStringField('username', 'bot-support');
                    gen.writeStringField('icon_emoji', ':smartplus:');
                    gen.writeEndObject(); //Inserts }
                    String body = gen.getAsString(); //Translates JSONGenerator to string to be passed to callout
                    System.debug('### SlackNotificationCommunityPosts body: '+ body);
                    System.enqueueJob(new qCallOut(webhookURL, 'POST', body)); // Send request
      
               	 } else {
                    System.debug('### SlackNotificationCommunityPosts Id = '+ r.id);
                    return; 
                }
                
            }
            catch (exception e) {
                System.debug('### SlackNotificationCommunityPosts error:' +e);
            }
            
        }
     
    }
    
     public class qCallOut implements System.Queueable, Database.AllowsCallouts {
         
        private final String url;
        private final String method;
        private final String body;
         
        public qCallOut(String url, String method, String body) {
            this.url = url;
            this.method = method;
            this.body = body;
        }
         
        public void execute(System.QueueableContext ctx) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint(url);
            req.setMethod(method);
            req.setBody(body);
            Http http = new Http();
            // to pass when process builder is invoked by another test class
            if(!Test.isRunningTest()){  
              HttpResponse res = http.send(req);
            }
        }
         
     }

}

here is my test class:
 
@isTest (seeAllData=true)
public class SlackNotificationCommunityPostTest {
    
    static testMethod void testPublishNewCommunityPostsToSlack() {
        Test.setMock(HttpCalloutMock.class, new mockCallout());
        List<SlackNotificationCommunityPost.slackRequest> requests = new List<SlackNotificationCommunityPost.slackRequest>();
        SlackNotificationCommunityPost.slackRequest r = new SlackNotificationCommunityPost.slackRequest();
        r.id= 'Test';
        r.name= 'Test';
        r.title= 'Test';
        r.type= 'Test';
        requests.add(r);
        SlackNotificationCommunityPost.publishNewCommunityPostsToSlack(requests);
        System.debug('check Post id: '+r.id);
    }
  
    static testmethod void testQueueable() {
        String url = 'https://hooks.slackTest.com';
        String method = 'Post';
        String body = 'body';
        
        SlackNotificationCommunityPost.qCallOut qCalloutTest = new SlackNotificationCommunityPost.qCallOut(url, method, body);
        Test.startTest();
        System.enqueueJob(qCalloutTest);
        Test.stopTest();
    }
    
    public class mockCallout implements HttpCalloutMock {
        public HttpResponse respond(HttpRequest request) {
            
            //Create a fake response
            HttpResponse res = new HttpResponse();
            res.setBody( '{"text":"value"}');
            res.setStatusCode(200);
            return res;
        }
    }

}

 
Hello,

I have created a Apex trigger on FeedComment. I have written a test class but I only cover 50%

User-added image

Could someone help me write the correct test for the part highlighted in red?
Thanks

Trigger:
 
trigger FeedCommentTriggerHandler on FeedComment (after insert) {
    
	System.Debug('FeedCommentTriggerHandler: Entering trigger');
    
    // GET LIST OF PARENT IDS
    List<Id> ParentIds = new List<Id>();
    for(FeedComment f:Trigger.new)ParentIds.add(f.ParentId);
    
    // CREATE LIST OF FEEDITEM FOR CREATEDBY TO BE POPULATED
    List<FeedComment> feedItems = new List<FeedComment>([SELECT Id,FeedItemId,CreatedById,CreatedBy.Name,CreatedBy.Profile.UserType,CreatedBy.Profile.Name,ParentId,CommentType FROM FeedComment WHERE Id in :Trigger.newMap.keyset()]);
    
    // INIT A MAP OF RELATED CASES WITH PARENT IDS
    Map<Id,Case> relatedCases = new Map<Id,Case>([SELECT id,Status,isClosed, OwnerId FROM Case WHERE Id in :ParentIds ]);
    
    // UPDATE CASE STATUS OF EACH CUSTOMER FEED RELATED CASE TO OPEN
    for(FeedComment feed:feedItems)
    {
        // IF FEED IS NOT CREATED BY SUPPORT MEMBERS
        System.debug('FeedCommentTriggerHandler: '+feed.CreatedBy.Profile.Name+' '+feed.ParentId.getSObjectType().getDescribe().getName()+' '+feed.CommentType);
        if( (feed.CreatedBy.Profile.Name != Label.Param_Support_Team_Profile && feed.CreatedBy.Profile.Name != Label.Param_Support_Lead_Profile ) && feed.ParentId.getSObjectType().getDescribe().getName() =='Case')
        {            
            // SET CASE TO OPEN UNLESS IT WAS CLOSED OR NEW
            if((relatedCases.get(feed.ParentId).isClosed==false)&&(relatedCases.get(feed.ParentId).Status!='New')&&(feed.CreatedById != relatedCases.get(feed.ParentId).OwnerId))relatedCases.get(feed.ParentId).Status = 'Open';
        }        
        
         //**H.O: To send Slack Notification when Answer is created on Community Post
        else if (feed.CommentType == 'TextComment' && feed.CreatedBy.Profile.UserType == 'PowerCustomerSuccess'){
            
            System.debug('FeedCommentTriggerHandler: feed parent :'+feed.ParentId+' Type : '+feed.CommentType);
            List<SlackNotificationCommunityPost.slackRequest> requests = new List<SlackNotificationCommunityPost.slackRequest>();
            SlackNotificationCommunityPost.slackRequest r = new SlackNotificationCommunityPost.slackRequest();
            r.id= feed.id;
            r.name= feed.CreatedBy.Name;
            r.title= feed.FeedItemId;
            r.type = feed.CommentType; 
            requests.add(r);
        	SlackNotificationCommunityPost.publishNewCommunityPostsToSlack(requests);                       
        }
    }
    
    if(relatedCases.values().size()>0)update relatedCases.values();
}

TestClass
 
@isTest
public class CaseFeedTrigger_Test {
    
    
   static testMethod void testCaseFeed()
   {
       
       User AdminUser = AP_TestDataFactory.CreateAdminUser('system.admin@test.com');
       
       Account a = AP_TestDataFactory.createAccount(AdminUser, 'TEST ACCOUNT', 'Tier 4', 'FRANCE');
       Contact con = AP_TestDataFactory.createAccountContact(a, 'TESTLASTNAME');         
       Case c = AP_TestDataFactory.createCase(AdminUser, a, con);
       
       
       test.startTest();
       
       System.runAs(AdminUser)
       { 
           c.Status='ScaleClient';
           update c;
       
           FeedItem fi = new FeedItem();
           fi.Body = 'test';
           fi.ParentId = c.Id;
           insert fi;
           
           FeedComment fc = new FeedComment();
           fc.CommentBody = 'test';
           fc.CommentType = 'TextComment';
           fc.FeedItemId = fi.Id;
           insert fc;
           
       }
        test.stopTest();
   }
}


 

Hi,

I have created a lightning button called "Raise a concern" but I would like to change the color of the text and the Icon, but when using Style in the component style, I am unale to change the color.

Here is the bit of code 
</aura:if>
        <aura:if isTrue="{!v.currentCaseRecordType=='Incident'}"> 
             
            <lightning:button variant="destructive"
                              label="Raise a Concern" class="concern"
                              iconName="utility:priority"
                              iconPosition="left"
                              title="Raise a Concern"
                              onclick="{! c.concernModalOpen }" 
                              disabled="{!if(v.currentCaseCaseConcern>0,'true','false')}"/>
        </aura:if>      

Could someone Help?
ThanksUser-added image