I am trying to alter the code below. It has these requirements:

  1. Create a Check Box Field to Update when its Approved (Done)

  2. Update This Check Box To True Approval actions. (Done)

  3. Compare in Trigger and have this in IF Condition whether Check_Box == True

Instead of creating an issue when the case is created I need it to trigger when the (custom obj) CDR__c is approved. I just need to insert #3 into the existing trigger.

trigger CreateIssue on Case (after insert) {

    // Check whether current user is not JIRA agent so that we don't create an infinite loop.
    if (JIRA.currentUserIsNotJiraAgent()) {
        for (Case c : Trigger.new) {
            // Define parameters to be used in calling Apex Class
            String objectType ='Case';  // Please change this according to the object type
            String objectId = c.id;
            String projectKey = 'SFDC'; //Please change this according to the JIRA project key
            String issueType = '1';     //Please change this according to the JIRA issue type ID
            // Calls the actual callout to create the JIRA issue.
            JIRAConnectorWebserviceCalloutCreate.createIssue(JIRA.baseUrl, JIRA.systemId, objectType, objectId, projectKey, issueType);
  • 1
    No coding experience? so, basically, you are copy pasting code from someone else, and expecting someone to modify it to fit your requirements? This is not a free coding service platform. We expect you to understand what you are posting. Based on what you have posted, it looks like you either need to hire someone or you should start learning, there are plenty of online resources to help you do so, such as Trailheads
    – glls
    Dec 28 '17 at 17:56
  • What does the included code have to do with the CDR__c object?
    – Adrian Larson
    Dec 28 '17 at 17:58
  • Jira provided the code. Its for a SF/Jira connector. So yes I did copy and paste as per their directions. I just needed a little help with making a small change. I understand that this is not a free coding service but thought it was a helpful resource. I do understand that its creating a Jira issue when a new case is created. The CDR is where the approval process is and what object in jira we are referencing.
    – PJ Greene
    Dec 28 '17 at 18:15
  • 2
    I agree that @glls was out of line here, and way too harsh. For what it's worth, I've upvoted you to offset one of the downvotes.
    – Derek F
    Dec 29 '17 at 1:52
  • 1
    Well, without the proper context, it’s kind of hard to guess where the code comes from and what it is intended for, if I was harsh, I do apologize. And I did undo my downvote after reading the context. Please do include context when providing code snippets, as there are too many freeloaders as of lately. Do feel free to open new posts with specific questions related to code and at least show some good faith effort in trying to modify the code to fit your needs for the same reasons stated above.
    – glls
    Dec 29 '17 at 4:05

Although you don't have much in the way of experience with code, it seems clear that you do know what generally needs to be done.

A few extra things to keep in mind to help make it even more clear what needs to be done:

  • Instead of being on a Case, it appears that you'll want this trigger to be on CDR__c
  • From item #2 in your question, your approval process has a final approval or rejection action that updates your record. This means that an update trigger is more appropriate here
  • From the documentation on Apex Triggers an after trigger is more appropriate here
    • After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

  • Following trigger best practices, you'll want to assume that you'll be processing more than one record at a time. Doing your comparison inside a for loop over the trigger.new context variable is a good idea
  • Callouts inside of a loop are dangerous

Those last two points present an issue here. The JIRA REST API looks like it can only create one record at a time. The JIRA docs provide another method for automating creation of JIRA issues, and I would strongly recommend using that instead.

The basic form of your trigger will be

Trigger CDR_Create_JIRA_Issue on <<object name>>((before|after)(insert|update|delete|undelete){
    // Declare a collection (that is, a set, map, or list) to hold the Ids of the
    //   objects that will become JIRA issues
    // Set<Id> -> the data type
    // = new Set<Id>(); -> One way to initialize a new set
    // Variables need to declared prior to being used, and most (if not all)
    //   need to be initialized prior to use as well.
    Set<Id> jiraIssueObjectIdsSet = new Set<Id>();

    // The other JIRA class we can use expects a List of SObjects instead of simply Ids
    List<CDR__c> jiraIssueCDRList = new List<CDR__c>();

    // Also probably a good idea to just define the things that won't change from
    //   JIRA issue to JIRA issue
    String objectType = 'CDR__c';
    String projectKey = 'SFDC'; // Change as appropriate
    String issueType = '1'; // Change as appropriate

    // Iterate over the trigger context variable 'trigger.new', and figure out which
    //   records need JIRA issues created for them
    // CDR__c myCDR -> defining the 'loop variable' that we can use inside the loop
    // :trigger.new -> tells us what to iterate over, each single item from trigger.new
    //   is placed into the loop variable, and the loop variable is updated
    //   after we reach the bottom of the loop
    for(CDR__c myCDR :trigger.new){
        // We use dot notation to access data inside of records
        // Replace 'yourField__c' with the actual name of your field
        // For boolean (i.e. true/false, or checked/unchecked in the case of a checkbox field)
        //   fields, we don't need to explicitly say field == true because
        //   true == true evaluates to simply true
            // This is a record for which we want to create a JIRA issue
            //   add the id to our set

            // If you want to use the better method of creating JIRA issues,
            //   then you'll want to add this CDR to the list of CDRs we want to create
            //   issues for

    // While we could have just created the JIRA issues in the previous loop, it's
    //   generally a good idea to separate gathering Ids from doing work on those Ids

    /*for(Id jiraObjectId :jiraIssueObjectIdsSet){
        // Method call to create a JIRA issue here

    // The above will work (up to a point), but there is a more appropriate way
    //   to do this.
    // If you want to use the loop + REST API for JIRA, uncomment the loop above
    //   (remove the "/*" and "*/")
    JCFS.API.createJiraIssue(projectKey, issueType, jiraIssueCDRList, Trigger.old);

Hope you can take things from here.

  • Thank you for your in-depth explanation! Truly appreciated. I think this way is the only option since we are using the Server Connector(you linked the cloud connector). We won't be creating a lot of Jira issues in this fashion as this is for custom requests from clients. Will the test class work for this new version of the code or do I need to test for the additional steps that were created? I add the test class above (Poorly. I will need to figure out the formatting in the future)
    – PJ Greene
    Jan 2 '18 at 23:10
  • @PJGreene Ah, didn't know there was a difference (I've never used JIRA myself). At first blush, it looks like that test class should work with my suggested trigger structure without issue. The golden rule of unit testing is you only gain coverage for code that is executed as part of a test method. Separate from that, the most important part of unit testing isn't code coverage, but rather making assertions to verify that your code does what you expect it to do (in this case, verifying the endpoint as you are doing is about the only thing you can verify).
    – Derek F
    Jan 3 '18 at 13:37
  • @PJGreene So, in my eyes, testing comes down to making sure that you execute a variety of possible paths through your code. For example, if you have if(<condition>){ <<some code here>> } else { <<some other code here>>}, in a single go, you can only enter the if block, or the else block. To get coverage for both, best practice would be to have 2 separate test methods. One where you set up appropriate data to get into the if block, and the other with appropriate setup to get you into the else block. If you have a loop, you need to make sure you'll have records to loop over.
    – Derek F
    Jan 3 '18 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.