• Glenn Daly
  • NEWBIE
  • 40 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 14
    Questions
  • 5
    Replies
I need to update a record if it meets a certain criteria, and if all other object records created within the last three months don't meet this criteria. I want to do this declaritvely so I am trying to use a combination of process builder and flow.

The process builder evaluates the criteria of a particular record on creation and edit, if this criteria is met, it's then passed onto a flow.

Once in the flow I wish to query all BMCServiceDesk__Incident__c objects records where the COL_JIS_Caller_Email__c field matches the record that originally triggered the flow. And only display records where survey_sent__c = TRUE and CreatedDate = Last 3 months.

IF the query displays no records, I wish to update the original Incident that triggered the flow, with the value of true on Survey_Sent__c.

Unfortunately this is not working, is there anyone able to help me with flow, I am very new to this tool!

User-added imageUser-added imageUser-added imageUser-added imageUser-added image
When field `review_date__c` on object `knowledge_article__c` changes to a specific date, it should create a new record on object `Incident__c`. I have achieved this with process builder.

However I then wish to be able to create a `Knowledge_Incident_Link__c` record and link the  `knowledge_article__c` record with the `Incident__c`. Ideally I'd like to do this with another process, but what are my options? How can I implement this idea? What steps would I need to take if I create a trigger?

Would somebody be able to get me started as I'm not an apex developer.
Below are the object relationships.

User-added image
I need to add an statement into this custom button so that it only runs if it meets a certain, how would I do this?
The statement essentially needs to say if the logged in user is equal to the R_D_Service_Owner__c or the project_owner__c then it can run, or if the logged in user profile equals 'system administrator' it can run, or if the logged in user equals a specific user id, or another specific user id it can run.

{!REQUIRESCRIPT("/soap/ajax/19.0/connection.js")}
var r = new sforce.SObject("Product2");
r.id = "{!Product2.Id}";
r.Convert_to_Service_Catalogue__c = true;
result = sforce.connection.update([r]);

window.location.reload();

if ( result[0].getBoolean( "success" ) ) {

location.reload( true ); // refresh page

} else {

var errors = result[0].errors;

var errorMessages = "The Lifecycle Status must be Beta, and the following fields must be populated; Name, Unique ID, Jisc Directorate, Include in Dashboard, Service/Project Owner or else this record won't be converted to a Service Catalogue record";

for ( var i = 0; i < errors.length; i++ ) {
errorMessages += errors[i].message + '\n';
}

alert( errorMessages ); // display all validation errors

}
I only wish for the vf page below to be displayed if the record type of the record clicked on is "unavailable_r_d_project", otherwise I want the standard page layout. However it's removing the block section "R&D Project Detail" if the record is of "unavailable_r_d_project". where am i going wrong?

<apex:page standardController="Product2">
    <apex:form >
        <apex:pageBlock rendered="{!Product2.recordType.DeveloperName == 'Unavailable_R_D_Project'}">
            <apex:pageBlockSection columns="2" showHeader="true" title="R&D Project Detail" rendered="{!Product2.recordType.DeveloperName == 'Unavailable_R_D_Project'}">
                <apex:inputField Value="{!Product2.Name}" label="Project Name" / >
                <apex:inputField Value="{!Product2.R_D_Directorate__c}"/>              
                <apex:inputField Value="{!Product2.Status__c}"/>
                <apex:inputField Value="{!Product2.Expected_Next_Stage_Date__c}"/>
                <apex:inputField Value="{!Product2.R_D_Unique_ID__c}"/>
                <apex:inputField Value="{!Product2.Lifecycle_Status__c}"/>
                   <apex:inputField Value="{!Product2.Project_Owner__c}"/>
                <br/>
                <apex:inputField Value="{!Product2.Alternative_Project_Contact__c}"/>
                <br/>
                <apex:inputField Value="{!Product2.Can_the_project_be_discussed_externally__c}"/>
                <br/>
                <apex:inputField Value="{!Product2.Looking_for_participants__c}"/>
            </apex:pageBlockSection>
                       <apex:pageBlockSection columns="2" showHeader="true" title="Description Information">
                            <apex:inputField Value="{!Product2.Project_Description__c}"/>
                         <apex:inputField Value="{!Product2.Cluster_Area_Portfolio__c}"/>
                         <apex:inputField Value="{!Product2.Benefits_to_the_customer__c}"/>
                         <apex:inputField Value="{!Product2.Eligibility__c}"/>
                    </apex:pageBlockSection>
                            <apex:pageBlockSection columns="2" showHeader="true" title="Service Information">
                                <apex:inputField Value="{!Product2.Risks__c}"/>
                                <apex:inputField Value="{!Product2.Include_in_Dashboard__c}"/>
                                <apex:inputField Value="{!Product2.Expected_Date_Service__c}"/>
                                <apex:inputField Value="{!Product2.Sector__c}"/>
                                <apex:inputField Value="{!Product2.Expected_Date_Alpha__c}"/>
                                <apex:inputField Value="{!Product2.Jisc_Directorate__c}"/>
                                <apex:inputField Value="{!Product2.Expected_Date_Beta__c}"/>
                            </apex:pageBlockSection>
                                    <apex:pageBlockSection columns="2" showHeader="true" title="Progress Information">
                                        <apex:inputField Value="{!Product2.Level_of_Demand__c}"/>
                                        <apex:inputField Value="{!Product2.Feasibility__c}"/>
                                        <apex:inputField Value="{!Product2.Notes_on_Current_Progress__c}"/>
                                        <apex:inputField Value="{!Product2.Expected_Usefulness__c}"/>
                                    </apex:pageBlockSection>
                                            <apex:pageBlockSection columns="2" showHeader="true" title="System Information">
                                                <apex:inputField Value="{!Product2.createdbyId}"/>
                                                <apex:inputField Value="{!Product2.lastmodifiedbyId}"/>
                                            </apex:pageBlockSection>   
       </apex:pageBlock>
   </apex:form>
</apex:page>
I want to display the a field label differently on a Product record. I have written the VF below. However, when I go to a Product record, it still displays as "Product Name" and not "Project Name". What am I doing wrong?

<apex:page standardController="Product2">
   <apex:form>
       <apex:pageBlockSection columns="2">
    <apex:inputField Value="{!Product2.Name}" label="Project Name" />
       </apex:pageBlockSection>    
   </apex:form>
</apex:page>
I'm trying to bulkify my code, however I'm receiving the following error;

"Incompatible element type Messaging.SingleEmailMessage for collection of Opportunity".

What do I need to do to amend this so it works?   

    List<Opportunity>emailOpOwner = new list<Opportunity>();
            for(Opportunity opp : listOpportunity)
            {
               Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

                    mail.setTargetObjectId(opp.OwnerId);
                    mail.setReplyTo('glenn.daly@live.com');
                    mail.setSenderDisplayName('Salesforce Support');
                for(opportunitylineitem oppLineItem :opp.opportunitylineitems)                
                    mail.setSubject('Historic Service attached to current opportunity : ' + oppLineItem.Product2.Name);
                    String body = 'Hi '+ opp.Owner.FirstName + ', ';     
                       body += '<br><br>Salesforce recognises you as the owner of the following opportunity:'+ opp.Name;
                  for(opportunitylineitem oppLineItem :opp.opportunitylineitems)
                      body += '<br><br>Attached to this opportunity is a former R&D service or project that is no longer available:' + oppLineItem.Product2.Name;
                       body += '<br><br> Please use the link below to view the opportunity record:';
                       body += '<br><br>test.salesforce.com/'+ opp.id;     
                     mail.setHtmlBody(body);
                    mail.setSaveAsActivity(false);
                    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
                    emailOpOwner.add(mail);
                        update listOpportunity;
There is a requirement to have a new record created on the Product2 object when the current product2 record meets a certain criteria. These records should then be linked together.
I have used process builder to create a new product2 record in the product2 object when the current product2 record meets a certain criteria. On the new product2 record I have a lookup field that is populated with the historic product2 record Id.
If I want to reference the new product2 record, from the historic product2 record, how would I do this? The lookup field is called Historic_R&D_Record__c and has a child relationship name of "Services".
I need to reference the historic product record in the soql query below.

List<Opportunity> listOpportunity = new List<Opportunity>();
            listOpportunity = [SELECT Id, OwnerId, Name, Owner.FirstName, (SELECT Id, Product2.Name FROM OpportunityLineItems WHERE Product2.Opportunity_Owner_Notification__c = FALSE
                            AND Product2.Isactive = FALSE
                            AND (Product2.RecordType.DeveloperName = 'Unavailable_R_D_Service' OR Product2.RecordType.DeveloperName = 'Unavailable_R_D_Project' ) LIMIT 1)
                           FROM Opportunity WHERE Id In
                           (SELECT OpportunityId FROM OpportunityLineItem WHERE Product2.Opportunity_Owner_Notification__c = FALSE
                            AND Product2.Isactive = FALSE
                            AND (Product2.RecordType.DeveloperName = 'Unavailable_R_D_Service' OR Product2.RecordType.DeveloperName = 'Unavailable_R_D_Project' ))];
I'm trying to reference the product2 name from an opportunity record. However it's giving me this error and not allowing me to save the code.

"Invalid foreign key relationship: Opportunity.opportunitylineitem"

How should I be referencing this field?

global class OpOwnerOldService_Scheduled Implements Schedulable
    {
        global void execute(SchedulableContext sc)
        {
            sendEmailtoOppOwner();
        }

        public void sendEmailtoOppOwner()
        {
            List<Opportunity> listOpportunity = new List<Opportunity>();
            listOpportunity = [SELECT Id, OwnerId FROM Opportunity WHERE Id In (SELECT OpportunityId FROM OpportunityLineItem WHERE Product2.Make_unavailable_for_opps_and_proposals__c = TRUE)];

            for(Opportunity opp : listOpportunity)
            {
               Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

mail.setTargetObjectId(opp.OwnerId);
mail.setReplyTo('glenn.daly@live.com');
mail.setSenderDisplayName('Salesforce Support');
mail.setSubject('Historic Service attached to current opportunity : '+ opp.  );
mail.setPlainTextBody(opportunity.Id +' has been created.');
mail.setSaveAsActivity(false);
                
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
            }

            update listOpportunity;
        }
    }
Firstly, apologies, I'm not a developer! We have a piece of code that reads as follows

  String ref = ' (Ref:IN:' + incident.Name + ')';
                  subject = subject.left(235) + ref;

When we try to send an email from within the Remedyforce console it should populate the subject line like so "This is a test subject Ref:IN:00125455"

However if the subject has a hypen, it will not pull through any of the subject before the hyphen.

For example if my subject is "This is a test subject" - This really is a test subject it will pull through "This really is a test subject Ref:IN:012546" 

Any ideas on how we can prevent it chopping anything off to the left of the hyphen?
I have two fields on a junction object that look up to the account object. One is called "Member Account" the other "Group Account". If Account A = Member Account, and Account B = Group Account then Account A shouldn't be able to be a Group Account if Account B is a Member Account.
I realise that I can't enforce this with a validation rule, so was thinking along the lines of creating another field, making it unique, and updating it with the values of two fields combined, but that probably won't work either.
Any ideas on how I can prevent this happening?
Key point here is that if Account A = "Group Account" and Account B = "Member Account" then Account A can never be "Member Account" if Account B = "Group Account" on another record within the junction object.
I am running a SOQL query to pull through the most recent note into an email template. The only problem is that it's not pulling through everything in the note. Is there anything wrong with my SOQL query below? Could there be a limitation in the visualforce page that brings up the email template? I'm just curious as to where I should be looking as I'm not a dev!

List<BMCServiceDesk__IncidentHistory__c> inboundEmails = [select Id, BMCServiceDesk__note__c, BMCServiceDesk__EmailConversationData__c,
                                                                                    COL_JIS_CCEmailAddresses__c
                                                                                    from BMCServiceDesk__IncidentHistory__c 
                                                                                    where BMCServiceDesk__actionId__c = 'Email Received'
                                                                                    and BMCServiceDesk__FKIncident__c = :ApexPages.currentPage().getParameters().get('id')
                                                                                    order by Name DESC Limit 1]; 
I'm trying to amend our code so that it pulls through all incident history records into an email conversation, and not just one record. Would somebody be able to advise on how I can do this please? Below is some of my code. FYI a "BMCServiceDEsk__note__c is created after every interation through email in the remedyforce console. I want to ensure all of these are displayed.

public with sharing class COL_JIS_EmailConversationController {

    
    
     BMCServiceDesk__Incident__c incident = null;
    //List<BMCServiceDesk__CustomAttachment__c> incidentAttachments = null;
    //Map<String,String> incidentAttachments = null;
    
     transient String bodyText = null;
     transient String lastEmailBody = null;
     String subject = null;
    //Attachment attachment = null;
    //String attID = null;
    String toAddresses = '';
    String ccAddresses = '';
    
        public COL_JIS_EmailConversationController(){
      incident =  [select id, name, COL_JIS_Caller_Email__c, COL_JIS_Caller_Name__c, COL_JIS_Subject__c,
                        BMCServiceDesk__openDateTime__c,BMCServiceDesk__IncidentDescription__c,
                        COL_JIS_Service_Desk_Signature__c,COL_JIS_Incident_History_last_entry__c,
                        COL_JIS_Category_Type__c
                               from BMCServiceDesk__Incident__c
                where id = :ApexPages.currentPage().getParameters().get('id') limit 1];
                
            List<BMCServiceDesk__IncidentHistory__c> inboundEmails = [select Id, BMCServiceDesk__note__c, BMCServiceDesk__EmailConversationData__c,
                                                                                    COL_JIS_CCEmailAddresses__c
                                                                                    from BMCServiceDesk__IncidentHistory__c 
                                                                                    where BMCServiceDesk__actionId__c = 'Email Received'
                                                                                    and BMCServiceDesk__FKIncident__c = :ApexPages.currentPage().getParameters().get('id')
                                                                                    order by Name DESC Limit 10]; 
            
            if(inboundEmails != null && inboundEmails.size() > 0){
                lastEmailBody = inboundEmails[0].BMCServiceDesk__note__c;
                if(inboundEmails[0].BMCServiceDesk__EmailConversationData__c != null){toAddresses = inboundEmails[0].BMCServiceDesk__EmailConversationData__c;}
                if(inboundEmails[0].COL_JIS_CCEmailAddresses__c != null){ccAddresses = inboundEmails[0].COL_JIS_CCEmailAddresses__c;}
            }
        if(incident != null){
            toAddresses += incident.COL_JIS_Caller_Email__c;
            subject = incident.COL_JIS_Subject__c;   
        }
        
    }
    
    public PageReference sendEmail() {
        system.debug('enter sendEmail');
        
        // attach files
        attachFile();
        // create a mail incident history record 
        
        BMCServiceDesk__Action__c action = null;
        List<BMCServiceDesk__Action__c> actions = [select Id from BMCServiceDesk__Action__c where BMCServiceDesk__Abbreviation__c = 'EMAILOUT' Limit 1];
        if(actions != null && actions.size()>0){
            system.debug('action found');
          action = actions[0];
        }
        
        String emailBody = bodyText;
        
        
        
        
        system.debug('************************* To: ' + toAddresses);
        COL_JIS_SingleEmailMessage mail = new COL_JIS_SingleEmailMessage();
        
        // get the org address to send the email from
        if(incident.COL_JIS_Category_Type__c != ''){
            List<OrgWideEmailAddress> orgWideAddresses = [SELECT Id, Address FROM OrgWideEmailAddress WHERE DisplayName = :incident.COL_JIS_Category_Type__c limit 1 ];
            if(orgWideAddresses != null && orgWideAddresses.size() > 0){
                mail.setReplyTo(orgWideAddresses[0].Address);
                mail.setOrgWideEmailAddressId(orgWideAddresses[0].Id);
            }
            
        }
        
        // set the from address as the default no reply
        /*List<OrgWideEmailAddress> replyTo = [SELECT Id, Address FROM OrgWideEmailAddress WHERE DisplayName = 'Jisc Remedyforce' limit 1 ];
            if(replyTo != null && replyTo.size() > 0){
                mail.setOrgWideEmailAddressId(replyTo[0].Id);
                
            }*/
        
        mail.setToAddress(toAddresses);
        mail.setSubject(subject + '(Ref:IN:' + incident.Name + ')');
        if(ccAddresses != null && ccAddresses != ''){
            mail.setCcAddresses(ccAddresses);
        }
        mail.setPlainTextBody(buildPlaintextBody());
        mail.setHtmlBody(buildHTMLBody());
        mail.setSaveAsActivity(false);
        Messaging.EmailFileAttachment[] attachArray = new Messaging.EmailFileAttachment[]{};
        String attachmentText = '';
        Integer noOfAttachments = selectedFoos.size();
        
        if(selectedFoos.size() > 0){
            //noOfAttachments ++;
            attachmentText = 'Attachments sent with this email(' + noOfAttachments + ')';
        }
        
        //List<Attachment> attachmentsToInsert = new List<Attachment>();
        Integer i = 1;
        for(Attachment a : selectedFoos){
            
            attachmentText += '\n' + i + '. ' + a.Name;
            i++;
            Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
            Attachment at = [select body from Attachment where Id = :a.Id limit 1];
            attach.setFileName(a.Name);
            attach.setBody(at.body);
            //a.parentId = incident.Id;
            attachArray.add(attach);
            
            //if(a.Id == null){
                //attachmentsToInsert.add(a);
            //}
        }
        //insert attachmentsToInsert;
        
        if(attachmentText != ''){
            attachmentText += '\n***********************';
        }
        mail.setFileAttachments(attachArray);
        
        if(incident != null && action != null){
            system.debug('incident and action exist');
            Integer actionCount = [select count() from BMCServiceDesk__IncidentHistory__c where BMCServiceDesk__FKIncident__c = :incident.Id];
            actionCount++;
            String actionName = incident.Name + '_' + string.valueOf(actionCount);
            // add a note to the incident
            
            emailBody = bodyText + '\n\n' + attachmentText ;
            
            BMCServiceDesk__IncidentHistory__c note = new BMCServiceDesk__IncidentHistory__c(BMCServiceDesk__FKIncident__c = incident.Id,
                                                        BMCServiceDesk__note__c = emailBody,
                                                        BMCServiceDesk__description__c = 'Email sent to ' + toAddresses,
                                                        BMCServiceDesk__FKAction__c = action.Id,
                                                        Name =  actionName,COL_JIS_Caller_Email__c = incident.COL_JIS_Caller_Email__c );
            if(note != null){
                system.debug('insert the note');
                insert note;
            }
        }
            
    try{
        mail.send();
    }catch(Exception e){
        ApexPages.addMessages(e);
        return null;
    }
        
    //return null; // stay on the same page 
    return new PageReference('javascript:window.close()');
}
    
    String[] getAddressArray(String addresses){
        if(addresses == null){addresses = '';}
        String[] addressList = addresses.split(';',0);
        return addressList;
        
    }
    
    public BMCServiceDesk__Incident__c getIncident() {
      
        return incident;
    }
    
    public String getToAddresses() {
        if(toAddresses == null){
            toAddresses = getIncident().COL_JIS_Caller_Email__c;
        }
        return toAddresses;
    }
    
    public void setToAddresses(String s){
        toAddresses = s;
    }
    
    public String getCcAddresses() {
        
        return ccAddresses;
    }
    
    public void setCcAddresses(String s){
        ccAddresses = s;
    }
    
    public String getAdditionalText() {
        return bodyText;
    }

    public void setAdditionalText(String s) {
        bodyText = s;
    }
    
    public String getLastEmailText() {
        
            
        return lastEmailBody;
    }

    public void setLastEmailText(String s) {
        lastEmailBody = s;
    }
    
    public String getSubject() {
        
            
        return subject;
    }

    public void setSubject(String s) {
        subject = s;
    }
    
     public String getAttachFiles() {
        
        String attachmentList = '';
        
        for(Attachment a : attachments){
            attachmentList += a.name + '\n';
        }   
        return attachmentList;
    }

    
    
    // =====================================================================================
    // Private helper methods
    // =====================================================================================
    
    private String buildHTMLBody(){
        // we cannot use templates as this would require a contact or user and would 
        // result in a double count of the email limit.
        
    
        String body = bodyText;
        if(incident.COL_JIS_Service_Desk_Signature__c != null){body += incident.COL_JIS_Service_Desk_Signature__c;}
        body = body.replaceAll('\n','<br>');
        body += '<p>Enquiry Number: '  + incident.Name;
        body += '<br>Subject: ';
        if(incident.COL_JIS_Subject__c != null){body += incident.COL_JIS_Subject__c;}
        body += '<br>Open Date: ';
        if(incident.BMCServiceDesk__openDateTime__c != null){body += incident.BMCServiceDesk__openDateTime__c;}
        body += '<br>Caller Name: ';
        if(incident.COL_JIS_Caller_Name__c != null){body += incident.COL_JIS_Caller_Name__c;}
        body += '<br>Enquiry: <p>';
        
       
        body += '<p><hr/><p>';
        if(lastEmailBody != null){body += lastEmailBody.replaceAll('\n', '<br>');}
        
        return body;
        
    }
    
    private String buildPlaintextBody(){
        // we cannot use templates as this would require a contact or user and would 
        // result in a double count of the email limit.
        
        String body = bodyText;
         if(incident.COL_JIS_Service_Desk_Signature__c != null){body += incident.COL_JIS_Service_Desk_Signature__c;}
        body += '\n----------------------------------------------------------------\n\n';
        body += '\n\nEnquiry Number: '  + incident.Name;
        body += '\nSubject: ';
        if(incident.COL_JIS_Subject__c != null){body += incident.COL_JIS_Subject__c;}
        body += '\nOpen Date: ';
        if(incident.BMCServiceDesk__openDateTime__c != null){body += incident.BMCServiceDesk__openDateTime__c;}
        body += '\nCaller Name: ';
        if(incident.COL_JIS_Caller_Name__c != null){body += incident.COL_JIS_Caller_Name__c;}
        body += '\nEnquiry: \n';
       
       
        if(lastEmailBody != null){body += lastEmailBody;}

        return body;
        
    }
 
We have an apex class that in conjunction with a visualforce page is used to send emails to customers from within Salesforce and then store that information as a record.

We need to change one of the fields that pulls through into the email that is sent to the customer. Through Testing I have established the parts of the code that would need changing if the new field was on the same object as the old field. However it's not. It's on a seperate object called BMCServiceDesk__IncidentHistory__c. I'm guessing a new SOQL query would need to be written to query this object and to get the   BMCServiceDesk__note__c field. Below is an extract of the  code, highlighted in bold is what I need removed. I'm guessing the new SOQL query would sit underneath the first query that queries the incident object? Some help on this would be greatly appreciated as I'm very new to this!

public with sharing class COL_JIS_EmailConversationController {
 
        BMCServiceDesk__Incident__c incident = null;
    //List<BMCServiceDesk__CustomAttachment__c> incidentAttachments = null;
    //Map<String,String> incidentAttachments = null;
    
     transient String bodyText = null;
     transient String lastEmailBody = null;
     String subject = null;
    //Attachment attachment = null;
    //String attID = null;
    String toAddresses = '';
    String ccAddresses = '';
    
        public COL_JIS_EmailConversationController(){
      incident =  [select id, name, COL_JIS_Caller_Email__c, COL_JIS_Caller_Name__c, COL_JIS_Subject__c,
                        BMCServiceDesk__openDateTime__c,BMCServiceDesk__IncidentDescription__c,
                        COL_JIS_Service_Desk_Signature__c,COL_JIS_Incident_History_last_entry__c,
                        COL_JIS_Category_Type__c
                               from BMCServiceDesk__Incident__c
                where id = :ApexPages.currentPage().getParameters().get('id') limit 1];
                
            List<BMCServiceDesk__IncidentHistory__c> inboundEmails = [select Id, BMCServiceDesk__note__c, BMCServiceDesk__EmailConversationData__c,
                                                                                    COL_JIS_CCEmailAddresses__c
                                                                                    from BMCServiceDesk__IncidentHistory__c 
                                                                                    where BMCServiceDesk__actionId__c = 'Email Received'
                                                                                    and BMCServiceDesk__FKIncident__c = :ApexPages.currentPage().getParameters().get('id')
                                                                                    order by Name DESC Limit 1]; 
            
            if(inboundEmails != null && inboundEmails.size() > 0){
                lastEmailBody = inboundEmails[0].BMCServiceDesk__note__c;
                if(inboundEmails[0].BMCServiceDesk__EmailConversationData__c != null){toAddresses = inboundEmails[0].BMCServiceDesk__EmailConversationData__c;}
                if(inboundEmails[0].COL_JIS_CCEmailAddresses__c != null){ccAddresses = inboundEmails[0].COL_JIS_CCEmailAddresses__c;}
            }
        if(incident != null){
            toAddresses += incident.COL_JIS_Caller_Email__c;
            subject = incident.COL_JIS_Subject__c;   
        }
        
    }
    
    public PageReference sendEmail() {
        system.debug('enter sendEmail');
        
        // attach files
        attachFile();
        // create a mail incident history record 
        
        BMCServiceDesk__Action__c action = null;
        List<BMCServiceDesk__Action__c> actions = [select Id from BMCServiceDesk__Action__c where BMCServiceDesk__Abbreviation__c = 'EMAILOUT' Limit 1];
        if(actions != null && actions.size()>0){
            system.debug('action found');
          action = actions[0];
        }
        
        String emailBody = bodyText;
        
        
        
        
        system.debug('************************* To: ' + toAddresses);
        COL_JIS_SingleEmailMessage mail = new COL_JIS_SingleEmailMessage();
        
        // get the org address to send the email from
        if(incident.COL_JIS_Category_Type__c != ''){
            List<OrgWideEmailAddress> orgWideAddresses = [SELECT Id, Address FROM OrgWideEmailAddress WHERE DisplayName = :incident.COL_JIS_Category_Type__c limit 1 ];
            if(orgWideAddresses != null && orgWideAddresses.size() > 0){
                mail.setReplyTo(orgWideAddresses[0].Address);
                mail.setOrgWideEmailAddressId(orgWideAddresses[0].Id);
            }
            
        }
        
        // set the from address as the default no reply
        /*List<OrgWideEmailAddress> replyTo = [SELECT Id, Address FROM OrgWideEmailAddress WHERE DisplayName = 'Jisc Remedyforce' limit 1 ];
            if(replyTo != null && replyTo.size() > 0){
                mail.setOrgWideEmailAddressId(replyTo[0].Id);
                
            }*/
        
        mail.setToAddress(toAddresses);
        mail.setSubject(subject + '(Ref:IN:' + incident.Name + ')');
        if(ccAddresses != null && ccAddresses != ''){
            mail.setCcAddresses(ccAddresses);
        }
        mail.setPlainTextBody(buildPlaintextBody());
        mail.setHtmlBody(buildHTMLBody());
        mail.setSaveAsActivity(false);
        Messaging.EmailFileAttachment[] attachArray = new Messaging.EmailFileAttachment[]{};
        String attachmentText = '';
        Integer noOfAttachments = selectedFoos.size();
        
        if(selectedFoos.size() > 0){
            //noOfAttachments ++;
            attachmentText = 'Attachments sent with this email(' + noOfAttachments + ')';
        }
        
        //List<Attachment> attachmentsToInsert = new List<Attachment>();
        Integer i = 1;
        for(Attachment a : selectedFoos){
            
            attachmentText += '\n' + i + '. ' + a.Name;
            i++;
            Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
            Attachment at = [select body from Attachment where Id = :a.Id limit 1];
            attach.setFileName(a.Name);
            attach.setBody(at.body);
            //a.parentId = incident.Id;
            attachArray.add(attach);
            
            //if(a.Id == null){
                //attachmentsToInsert.add(a);
            //}
        }
        //insert attachmentsToInsert;
        
        if(attachmentText != ''){
            attachmentText += '\n***********************';
        }
        mail.setFileAttachments(attachArray);
        
        if(incident != null && action != null){
            system.debug('incident and action exist');
            Integer actionCount = [select count() from BMCServiceDesk__IncidentHistory__c where BMCServiceDesk__FKIncident__c = :incident.Id];
            actionCount++;
            String actionName = incident.Name + '_' + string.valueOf(actionCount);
            // add a note to the incident
            
            emailBody = bodyText + '\n\n' + attachmentText ;
            
            BMCServiceDesk__IncidentHistory__c note = new BMCServiceDesk__IncidentHistory__c(BMCServiceDesk__FKIncident__c = incident.Id,
                                                        BMCServiceDesk__note__c = emailBody,
                                                        BMCServiceDesk__description__c = 'Email sent to ' + toAddresses,
                                                        BMCServiceDesk__FKAction__c = action.Id,
                                                        Name =  actionName,COL_JIS_Caller_Email__c = incident.COL_JIS_Caller_Email__c );
            if(note != null){
                system.debug('insert the note');
                insert note;
            }
        }
            
    try{
        mail.send();
    }catch(Exception e){
        ApexPages.addMessages(e);
        return null;
    }
        
    //return null; // stay on the same page 
    return new PageReference('javascript:window.close()');
}
    
    String[] getAddressArray(String addresses){
        if(addresses == null){addresses = '';}
        String[] addressList = addresses.split(';',0);
        return addressList;
        
    }
    
    public BMCServiceDesk__Incident__c getIncident() {
      
        return incident;
    }
    
    public String getToAddresses() {
        if(toAddresses == null){
            toAddresses = getIncident().COL_JIS_Caller_Email__c;
        }
        return toAddresses;
    }
    
    public void setToAddresses(String s){
        toAddresses = s;
    }
    
    public String getCcAddresses() {
        
        return ccAddresses;
    }
    
    public void setCcAddresses(String s){
        ccAddresses = s;
    }
    
    public String getAdditionalText() {
        return bodyText;
    }

    public void setAdditionalText(String s) {
        bodyText = s;
    }
    
    public String getLastEmailText() {
        
            
        return lastEmailBody;
    }

    public void setLastEmailText(String s) {
        lastEmailBody = s;
    }
    
    public String getSubject() {
        
            
        return subject;
    }

    public void setSubject(String s) {
        subject = s;
    }
    
     public String getAttachFiles() {
        
        String attachmentList = '';
        
        for(Attachment a : attachments){
            attachmentList += a.name + '\n';
        }   
        return attachmentList;
    }

    
    
    // =====================================================================================
    // Private helper methods
    // =====================================================================================
    
    private String buildHTMLBody(){
        // we cannot use templates as this would require a contact or user and would 
        // result in a double count of the email limit.
        
    
        String body = bodyText;
        body = body.replaceAll('\n','<br>');
        body += '<p>Enquiry Number: '  + incident.Name;
        body += '<br>Subject: ';
        if(incident.COL_JIS_Subject__c != null){body += incident.COL_JIS_Subject__c;}
        body += '<br>Open Date: ';
        if(incident.BMCServiceDesk__openDateTime__c != null){body += incident.BMCServiceDesk__openDateTime__c;}
        body += '<br>Caller Name: ';
        if(incident.COL_JIS_Caller_Name__c != null){body += incident.COL_JIS_Caller_Name__c;}
        body += '<br>Enquiry: <p>';
        if(incident.BMCServiceDesk__incidentDescription__c != null){body += incident.BMCServiceDesk__incidentDescription__c.replaceAll('\n', '<br>');}
        body += '<p>Please reply to this email with any updates on this issue.<p>';
        if(incident.COL_JIS_Service_Desk_Signature__c != null){body += incident.COL_JIS_Service_Desk_Signature__c;}
        body += '<p><hr/><p>';
        if(lastEmailBody != null){body += lastEmailBody.replaceAll('\n', '<br>');}
        
        return body;
        
    }
    
    private String buildPlaintextBody(){
        // we cannot use templates as this would require a contact or user and would 
        // result in a double count of the email limit.
        
        String body = bodyText;
        body += '\n\nEnquiry Number: '  + incident.Name;
        body += '\nSubject: ';
        if(incident.COL_JIS_Subject__c != null){body += incident.COL_JIS_Subject__c;}
        body += '\nOpen Date: ';
        if(incident.BMCServiceDesk__openDateTime__c != null){body += incident.BMCServiceDesk__openDateTime__c;}
        body += '\nCaller Name: ';
        if(incident.COL_JIS_Caller_Name__c != null){body += incident.COL_JIS_Caller_Name__c;}
        body += '\nEnquiry: \n';
        if(incident.BMCServiceDesk__incidentDescription__c != null){body += incident.BMCServiceDesk__incidentDescription__c;}
        body += '\nPlease reply to this email with any updates on this issue.\n\n';
        if(incident.COL_JIS_Service_Desk_Signature__c != null){body += incident.COL_JIS_Service_Desk_Signature__c;}
        body += '\n----------------------------------------------------------------\n\n';
        if(lastEmailBody != null){body += lastEmailBody;}

        return body;
        
    }
    
I have three objects. Accounts, Consortiums, Campuses and have set up a many to many relationship between Consortiums and Accounts. And also from Campuses and Accounts. I've done this by creating two junction objects that sit inbetween. This enables me to add more than one consortium to an account, and more than one account to a consortium. I am looking for ways to prevent duplicate records being created. Can I do this by validation rule, or will I need to write a trigger?
I need to update a record if it meets a certain criteria, and if all other object records created within the last three months don't meet this criteria. I want to do this declaritvely so I am trying to use a combination of process builder and flow.

The process builder evaluates the criteria of a particular record on creation and edit, if this criteria is met, it's then passed onto a flow.

Once in the flow I wish to query all BMCServiceDesk__Incident__c objects records where the COL_JIS_Caller_Email__c field matches the record that originally triggered the flow. And only display records where survey_sent__c = TRUE and CreatedDate = Last 3 months.

IF the query displays no records, I wish to update the original Incident that triggered the flow, with the value of true on Survey_Sent__c.

Unfortunately this is not working, is there anyone able to help me with flow, I am very new to this tool!

User-added imageUser-added imageUser-added imageUser-added imageUser-added image
When field `review_date__c` on object `knowledge_article__c` changes to a specific date, it should create a new record on object `Incident__c`. I have achieved this with process builder.

However I then wish to be able to create a `Knowledge_Incident_Link__c` record and link the  `knowledge_article__c` record with the `Incident__c`. Ideally I'd like to do this with another process, but what are my options? How can I implement this idea? What steps would I need to take if I create a trigger?

Would somebody be able to get me started as I'm not an apex developer.
Below are the object relationships.

User-added image
I want to display the a field label differently on a Product record. I have written the VF below. However, when I go to a Product record, it still displays as "Product Name" and not "Project Name". What am I doing wrong?

<apex:page standardController="Product2">
   <apex:form>
       <apex:pageBlockSection columns="2">
    <apex:inputField Value="{!Product2.Name}" label="Project Name" />
       </apex:pageBlockSection>    
   </apex:form>
</apex:page>
I have two fields on a junction object that look up to the account object. One is called "Member Account" the other "Group Account". If Account A = Member Account, and Account B = Group Account then Account A shouldn't be able to be a Group Account if Account B is a Member Account.
I realise that I can't enforce this with a validation rule, so was thinking along the lines of creating another field, making it unique, and updating it with the values of two fields combined, but that probably won't work either.
Any ideas on how I can prevent this happening?
Key point here is that if Account A = "Group Account" and Account B = "Member Account" then Account A can never be "Member Account" if Account B = "Group Account" on another record within the junction object.