• Victor Nguyen 13
  • NEWBIE
  • 10 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 11
    Questions
  • 10
    Replies
Hi everyone,

I have a scheduled Apex class, but it's not on the Schedule list. Can you please help me what I did wrong?
 
global class LatePayment implements Schedulable {      
    global void execute(SchedulableContext ctx) {
        Date AcceptedDate;
        
        //Schedule the class to run on every Friday at 11:59PM
        String Cron_exp = '59 59 23 ? * FRI';
        String JobID = System.Schedule('Check Late Payment', Cron_exp, new LatePayment());
        
        //Creating Registration Deadlines Date table
        List<hed__Term__c> lstTerm = [SELECT Id, Name, Application_Session__c, Application_Year__c, Registration_Deadlines__c 
                                      FROM hed__Term__c
                                      WHERE Registration_Deadlines__c < TODAY
                                      ORDER BY Registration_Deadlines__c asc];
        
        //Creating a list of all Opp that are under Acceptance Letter Issued and Visa Pass stage
        List<Opportunity> lstOpp = [SELECT Id, Deferred__c, RecordTypeId, Name, StageName, Accepted_Letter_Issued_Date__c, Visa_Pass_Date__c, CloseDate,
                                   		Late_Payment__c, I_am_applying_for_the__c, Year_of_Semester__c
                                   FROM Opportunity
                                   WHERE (StageName = 'Visa Pass' OR StageName ='Acceptance Letter Issued')
                                   AND RecordTypeId != '0126A000000xOkkQAE' AND RecordTypeId != '0126A000000xOkfQAE'
                                   ORDER BY CloseDate asc];
        
        List<Opportunity> lstUpdate = new List<Opportunity>(); 
        if (!lstOpp.IsEmpty()) {
            for (Opportunity opp : lstOpp) {
                if ((opp.RecordTypeId == '0126A000000xOkVQAU' || opp.RecordTypeId == '0126A000000JHdYQAW')) {
                    if (opp.Deferred__c == false) {
                        AcceptedDate = opp.Visa_Pass_Date__c;
                    }
                    else {
                        AcceptedDate = opp.Accepted_Letter_Issued_Date__c;
                    }
                }
                else {
                    AcceptedDate = opp.Accepted_Letter_Issued_Date__c;
                }
                for (hed__Term__c terms : lstTerm) {  
                    if (opp.I_am_applying_for_the__c == terms.Application_Session__c && opp.Year_of_Semester__c == terms.Application_Year__c) {
                        if (AcceptedDate < terms.Registration_Deadlines__c.addDays(-7)) {
                            opp.Late_Payment__c = (terms.Registration_Deadlines__c.daysBetween(Date.today())+3) / 7;
                        }
                        else {
                            opp.Late_Payment__c = AcceptedDate.daysBetween(Date.today()) / 7;
                        }
                    }
                }
                lstUpdate.add(opp);
            }
            update lstUpdate;
        }
    }
}

 
Hi everyone,

I have a schedule Apex class that is used for tracking pate payment.

Below is the source code. However, the code is not on the Schedule list for some reasons that I don't know. Please give me some advice on this.

Apex Class:
global class LatePayment implements Schedulable {      
    global void execute(SchedulableContext ctx) {
        Date AcceptedDate;
        
        //Schedule the class to run on every Friday at 11:59PM
        String Cron_exp = '59 59 23 ? * FRI';
        String JobID = System.Schedule('Check Late Payment', Cron_exp, new LatePayment());
        
        //Creating Registration Deadlines Date table
        List<hed__Term__c> lstTerm = [SELECT Id, Name, Application_Session__c, Application_Year__c, Registration_Deadlines__c 
                                      FROM hed__Term__c
                                      WHERE Registration_Deadlines__c < TODAY
                                      ORDER BY Registration_Deadlines__c asc];
        
        //Creating a list of all Opp that are under Acceptance Letter Issued and Visa Pass stage
        List<Opportunity> lstOpp = [SELECT Id, Deferred__c, RecordTypeId, Name, StageName, Accepted_Letter_Issued_Date__c, Visa_Pass_Date__c, CloseDate,
                                   		Late_Payment__c, I_am_applying_for_the__c, Year_of_Semester__c
                                   FROM Opportunity
                                   WHERE (StageName = 'Visa Pass' OR StageName ='Acceptance Letter Issued')
                                   AND RecordTypeId != '0126A000000xOkkQAE' AND RecordTypeId != '0126A000000xOkfQAE'
                                   ORDER BY CloseDate asc];
        
        List<Opportunity> lstUpdate = new List<Opportunity>(); 
        if (!lstOpp.IsEmpty()) {
            for (Opportunity opp : lstOpp) {
                if ((opp.RecordTypeId == '0126A000000xOkVQAU' || opp.RecordTypeId == '0126A000000JHdYQAW')) {
                    if (opp.Deferred__c == false) {
                        AcceptedDate = opp.Visa_Pass_Date__c;
                    }
                    else {
                        AcceptedDate = opp.Accepted_Letter_Issued_Date__c;
                    }
                }
                else {
                    AcceptedDate = opp.Accepted_Letter_Issued_Date__c;
                }
                for (hed__Term__c terms : lstTerm) {  
                    if (opp.I_am_applying_for_the__c == terms.Application_Session__c && opp.Year_of_Semester__c == terms.Application_Year__c) {
                        if (AcceptedDate < terms.Registration_Deadlines__c.addDays(-7)) {
                            opp.Late_Payment__c = terms.Registration_Deadlines__c.daysBetween(Date.today()) / 7;
                        }
                        else {
                            opp.Late_Payment__c = AcceptedDate.daysBetween(Date.today()) / 7;
                        }
                    }
                }
                lstUpdate.add(opp);
            }
            update lstUpdate;
        }
    }
}

Test class (This is the updated version, but I can't push it to the Procduction due to the below error)
 
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, hed.TDTM_Opportunity: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Class.OPP_Naming_TDTM.generateContactNamePortion: line 18, column 1 Class.OPP_Naming_TDTM.run: line 84, column 1 Class.hed.TDTM_TriggerHandler.runClass: line 145, column 1 Class.hed.TDTM_TriggerHandler.run: line 75, column 1 Class.hed.TDTM_Global_API.run: line 61, column 1 Trigger.hed.TDTM_Opportunity: line 33, column 1: []
Stack Trace: Class.LatePaymentTest.testScheduleJob: line 22, column 1
Previous (1 - 1 of 1) Next
 
@isTest(SeeAllData=true)
public class LatePaymentTest {
    // Creating dummy CRON expression
    public static String CRON_EXP = '0 0 0 1 1 ? 2022';
    static testmethod void testScheduleJob () {
        List<Opportunity> opptys = new List<Opportunity>();
        List<hed__Term__c> termList = new List<hed__Term__c>([SELECT Id, Name, Registration_Deadlines__c, Application_Session__c, Application_Year__c, hed__Start_Date__c FROM hed__Term__c
                                                             ORDER BY Registration_Deadlines__c asc]);
        System.assert(termList.size() == 10);
        Integer i = 0;
        for (hed__Term__c t : termList) {
            if (i < termList.size() / 2) {
                opptys.add(new Opportunity (Name = 'Opportunity ' + i, CloseDate = t.hed__Start_Date__c, RecordTypeId = '0126A000000xOkVQAU', StageName = 'Visa Pass',
                                           Visa_Pass_Date__c = t.Registration_Deadlines__c.addDays(-7), I_am_applying_for_the__c = t.Application_Session__c, Year_of_Semester__c = t.Application_Year__c));
            }
            else {
                opptys.add(new Opportunity (Name = 'Opportunity ' + i, CloseDate = t.hed__Start_Date__c, RecordTypeId = '0126A000000xOkQQAU', StageName = 'Acceptance Letter Issued',
                                           Accepted_Letter_Issued_Date__c = t.Registration_Deadlines__c.addDays(-7), I_am_applying_for_the__c = t.Application_Session__c, Year_of_Semester__c = t.Application_Year__c));
            }
            i++;
        }
        insert opptys;
        
        Map<Id,Opportunity> OppMap = new Map<Id,Opportunity> (opptys);
        List<Id> oppIds = new List<Id>(OppMap.keySet());
        
        Test.startTest();
        
        String JobId = system.schedule('Test Payment', CRON_EXP, new LatePayment());
        // Verify the scheduled job has not run yet
        List <Opportunity> OppTest = [Select Id, Late_Payment__c FROM Opportunity WHERE Id IN :oppIds];
        for (Opportunity o : OppTest) {
            System.assertEquals(0, o.Late_Payment__c);
        }
        
        Test.stopTest();
        // The job is running synchronously        
        
        OppTest = [SELECT Id, Late_Payment__c, Accepted_Letter_Issued_Date__c, Visa_Pass_Date__c FROM Opportunity WHERE Id IN :oppIds];
        System.debug('The list is ' + OppTest);
        for (Opportunity oppcheck : OppTest) {
            System.debug('Late Payment number is ' + oppcheck.Late_Payment__c);
        }
        
    }
}


 
Hi everyone!

We need to track students late payment. When they are accepted to our school, the Representatives will toggle "Acceptance Letter Issued" stage. When the students pay their fees, the Reps will toggle "Registered" as the students are ready to be enrolled.

We have a deadline for payment as well. If Reps don't toggle a different stage after "Acceptance Letter Issued" stage after the deadline, we want a custom field to indicate that the student is late on paying their fees.

What would be the best practice to accomplish this project? Please give me some advice.

Thank you!
Hi everyone,

I'm getting this error on line 58:
ystem.NullPointerException: Attempt to de-reference a null object

Below is the code. I'm planning to put this code on Process Builder. This code will transfer the opportunity to other representatives when the opportunity has been touched for 4 days. Before transferring away, it will create a record on Round Robin Record object. Record Distribution is the list of teams. Record Distribution Mapping is the list of Representatives with a lookup field to Record Distribution object.
 
public class RoundRobinOpp {
    public class RRRequest {
        @InvocableVariable
        public String opportunityName;
        
        @InvocableVariable
        public String distributionName;
        
        @InvocableVariable
        public Id opportunityId;
        
        @InvocableVariable
        public Id ownerId;   
    }
    
    public static List<Record_Distribution_Mapping__c> getRepsByDistribution(String distributionName) {
        return [select User__r.id, CreatedDate, Record_Distribution__c, Record_Distribution__r.Number_of_RR__c 
                from Record_Distribution_Mapping__c 
                where Record_Distribution__r.Name = :distributionName
                order by CreatedDate asc];
    }
    
    @InvocableMethod
    public static void RoundRobinOpp(List<RRRequest> requests) {
        Set<String> distributionnames = new Set<String>();
        Set<Id> username = new Set<Id>();
        
        for (RRRequest request : requests) {
			distributionnames.add(request.distributionName);
            username.add(request.ownerId);
        }
        
        Map<String, List<Record_Distribution_Mapping__c>> distributionToMappings = new Map<String, List<Record_Distribution_Mapping__c>>();
        Map<String, Record_Distribution__c> relevantDistributions = new Map<String, Record_Distribution__c>();
        Map<String, Record_Distribution_Mapping__c> relevantUser = new Map<String, Record_Distribution_Mapping__c>();
        
        for (Record_Distribution_Mapping__c users : [SELECT User__c, Opportunity_Name_1__c, Opportunity_Name_2__c, Opportunity_Name_3__c, Number_of_Opp__c
                                                     FROM Record_Distribution_Mapping__c WHERE User__c = :username]) {
                                                         relevantUser.put(users.User__c,users);
                                                     }
        
        for (Record_Distribution__c distribution : [select Name, Number_of_RR__c from Record_Distribution__c where name in :distributionnames]) {
			relevantDistributions.put(distribution.name, distribution);
		}
        
        for (String distributionName : distributionnames) {
			distributionToMappings.put(distributionName, getRepsByDistribution(distributionName));
		}      
        
        List<Round_Robin_Record__c> lstRRrecord = new List<Round_Robin_Record__c>();
        List<Opportunity> lstOppsToUpdate = new List<Opportunity>();
        for (RRRequest request : requests) {
            Round_Robin_Record__c newRecord = new Round_Robin_Record__c();
            newRecord.Opportunity_Name__c = request.opportunityName;
            newRecord.User__c = request.ownerId;
            
            Record_Distribution_Mapping__c updateRRnumber = relevantUser.get(request.ownerId);
            updateRRnumber.Number_of_Opp__c++;
            //Might add the opportunity names for reporting
            
            Opportunity reassignedOpp = new Opportunity(id = request.opportunityId);
            Record_Distribution__c TeamDistribution =  relevantDistributions.get(request.distributionName);
            reassignedOpp.OwnerId = distributionToMappings.get(request.distributionName)[Math.mod((Integer) TeamDistribution.Number_of_RR__c,
                                                                                                 distributionToMappings.get(request.distributionName).size())].User__r.id;
            lstRRrecord.add(newRecord);
            TeamDistribution.Number_of_RR__c++;
            lstOppsToUpdate.add(reassignedOpp);
        }
        
        insert lstRRrecord;
        update lstOppsToUpdate;
        update relevantDistributions.values();
        update relevantUser.values();
    }
}

I can't find the reason why the Number_of_Opp__c is empty, I have put 0 in that field for each record already.

Please help! Thanks in advance.
Hi everyone,

I'm having trouble setting up on process builder. I want it to invoke another process 4 days (weekend excluded) after created date when no Activity and no StageName updated.

Below is the formula that trigger the action
MOD([Opportunity].Opportunity_Age__c , 1) = 0 && 
ISNULL([Opportunity].Last_Activity_Subject__c) &&
ISPICKVAL([Opportunity].StageName , 'New')

Where Opportunity_Age__c is a formula fields (return type is Number): 
(5 * ( FLOOR( ( NOW() - DATETIMEVALUE("1900-01-08 00:00:00")) / 7 ) ) + MIN( 5, MOD( NOW() - DATETIMEVALUE("1900-01-08 00:00:00"), 7 ) ) )
-
(5 * ( FLOOR( ( DATETIMEVALUE(CreatedDate) - DATETIMEVALUE("1900-01-08 00:00:00") ) / 7 ) ) + MIN( 5, MOD( DATETIMEVALUE(CreatedDate) - DATETIMEVALUE("1900-01-08 00:00:00"), 7 ) ) )

It doesn't work for some reasons. Please give me some advice on this.
 
Hi everyone,

My sales users want to associate multiple campaigns to ONE opportunity. I have created 1 more lookup field called "Secondary Campaign". Now, they want to add another campaign, I don't want to create another lookup field.

Is there anyway that we can associate multiple campaigns to one opportunity?

Thanks in advance.
Hi everyone,

I want to Round Robin the opportunity if it's not contacted by 3 days. If a representative get 5 cycles of Round Robin, the Director will get notification.

How can I start with this project? I'm thinking using Process Builder, but it wouldn't work for the second part.

Please give me some advice on this. Thank you!
Hi everyone,

My users are using Salesforce Extension to log emails. They want to send a mass emails to different contacts.

Is there a way that they can log emails to every contacts that they send a mass email to?

Thank you in advance.

Hi everyone,

I'm new to Salesforce and Apex coding. I'm making a function so that user can upload a csv file to generate opportunity and contact. However, it hit the SOQL queries limit, I was able to upload maximum 12 rows.

I need to insert Contact first, in order to get an Contact Id and put it in Opportunity. Since I put the queries inside For loops plus other triggers, it exceeded the queries limit.

I'm planning to create an Apex Batch Process, but not sure if it will solve the problem.

Below is the Apex code and Visualforce page:

Apex:

public class FileUploader {
    private ApexPages.StandardController std;
    public string nameFile{get;set;}
    public Blob contentFile{get;set;}
    public Date closeDate {get;set;}
    public Id recordType {get;set;}
    public Id ownerId {get; set;}
    public List<opportunity> opplist{get;set;}
    public Contact con {get; set;}
    public Opportunity opp {get; set;}
    
    private final String integrationName = 'Inquiry Import';
    String campaignlookup;
    String[] filelines = new String[]{};
        
    public List<SelectOption> repSelectOptions {get {
        List<SelectOption> repSelectOptions = new List<SelectOption> {new SelectOption('','Select One')};
        for (User u : [SELECT Id, Name
                       FROM User 
                       WHERE UserType = 'Standard' AND 
                       IsActive = true
                       ORDER BY Name asc]) {
        	repSelectOptions.add(new SelectOption(u.Id, u.Name));
        }
        return repSelectOptions;
    }}
    
    public List<SelectOption> recordOptions {get {
        List<SelectOption> recordOptions = new List<SelectOption>{new SelectOption('','Select One')};
        
        for (RecordType r : [SELECT Id, Name FROM RecordType WHERE sobjecttype = 'Opportunity']) {
            recordOptions.add(new SelectOption(r.Id, r.Name));
        }
        return recordOptions;
    }}
    
    {
        initializeObjects();
    }
            
    public void initializeObjects() {
        con = new Contact();
        opp = new Opportunity();
    }
    
    public FileUploader() {
		opplist = New List<Opportunity>(); 
	}
    
    /***This function reads the CSV file and inserts records into objects. ***/
    public Pagereference ReadFile()
    {
        opplist.clear();
        try{
                //Convert the uploaded file which is in BLOB format into a string
                nameFile =blobToString( contentFile,'ISO-8859-1');
                
                //Now sepatate every row of the csv file
                filelines = nameFile.split('\n');
                
                //Iterate through every line and create a Record for each row
                for (Integer i=1; i<filelines.size(); i++)
                {                                       
                    String[] inputvalues = new String[]{};
                    inputvalues = filelines[i].split(',');
                    
                    con.FirstName = inputvalues[0] ;             
                 	con.LastName = inputvalues[1];
                 	con.MobilePhone = inputvalues[2];
                 	con.Personal_Email__c = inputvalues[3];
                 	con.OwnerId = this.ownerId;
                 	con.Integration__c = this.integrationName;
                 	insert con;
                 
                 	Contact queriedCon = [SELECT Id, FirstName, LastName, AccountId FROM Contact WHERE Id = :con.Id];
                 	opp.CloseDate = this.closeDate;
                 	opp.RecordTypeId = this.recordType;
                 	opp.OwnerId = this.ownerId;
				 	opp.Contact__c = queriedCon.Id;
				 	opp.AccountId = queriedCon.AccountId;
				 	opp.Name = queriedCon.FirstName + ' ' + queriedCon.LastName;
                 	opp.Program_of_Interest__c = inputvalues[4];
                    campaignlookup = inputvalues[5];
                    Campaign[] campaignId = [SELECT Id FROM Campaign WHERE Name = :campaignlookup];
                    if (campaignId.size() > 0) {
                        opp.CampaignId = campaignId[0].Id;
                    }
                 	opp.StageName = 'New';
        		 	opp.Integration__c = this.integrationName;
                 	insert opp;
                    opplist.add(opp);
                 
                 	Integration_Origin__c origin = new Integration_Origin__c();
        		 	origin.Contact__c = queriedCon.id;
        		 	origin.Opportunity__c = opp.id;
        		 	origin.Integration__c = [SELECT Id FROM Integration__c WHERE Name = :this.integrationName].Id;
        		 	insert origin;
                 
                 	initializeObjects();
                    campaignlookup = null;
                }
         }
         catch(Exception e){
             	initializeObjects();
                ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured reading the CSV file '+e.getMessage());
                ApexPages.addMessage(errormsg);
         }               
        return null;
    }
    
    public List<Opportunity> getuploadedOpp () {
        return opplist;
    }
        /**
         This function converts the input CSV file in BLOB format into a string
        @param input    Blob data representing correct string in @inCharset encoding
        @param inCharset    encoding of the Blob data
     */
    public static String blobToString(Blob input, String inCharset){
        String hex = EncodingUtil.convertToHex(input);
        System.assertEquals(0, hex.length() & 1);
        final Integer bytesCount = hex.length() >> 1;
        String[] bytes = new String[bytesCount];
        for(Integer i = 0; i < bytesCount; ++i)
            bytes[i] =  hex.mid(i << 1, 2);
        return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
    }
}

Visualforce Page:
 
<apex:page sidebar="false" controller="FileUploader" docType="html-5.0" lightningStylesheets="true">
    <apex:slds />
   <apex:form >
      <apex:sectionHeader title="Upload data from CSV file"/>
      <apex:pagemessages />
       
      <apex:pageBlock >
          <apex:pageBlockSection id="RequiredBlock" rendered="true" title="Required Information">		            
            <apex:input required="true" type="date" label="Expected Start Date"  value="{!CloseDate}"/>
            <apex:selectList required="true" id="recordtypeSelection" size="1" label="Student Type" value="{!recordType}">
            	<apex:selectOptions value="{!recordOptions}"/>
            </apex:selectList>
            <apex:selectList required="true" id="userSelect" size="1" label="Advisor" value="{!ownerId}">
            	<apex:selectOptions value="{!repSelectOptions}"/>
            </apex:selectList>
          </apex:pageBlockSection>
      </apex:pageBlock> 
       
      <apex:pageBlock >
             <!--  Component to allow user to upload file from local machine -->
             <center>
              <apex:inputFile value="{!contentFile}" filename="{!nameFile}" /> <apex:commandButton action="{!ReadFile}" value="Upload File" id="theButton" style="width:100px;"/>
              <br/> <br/> <font color="red"> <b>Note: Please use the standard template to upload Records. <a href="https://universities.my.salesforce.com/sfc/p/6A000000voho/a/3s000000PTVs/HzZ5Kbu_BdhxG51fDbiHaTMZHguLFRg6gjYC2e75BIg" target="_blank"> Click here </a> to download the template. </b> </font>
             </center>  
       </apex:pageBlock> 
      <!-- After the user clicks the 'Upload File' button, this section displays the inserted data -->
       <apex:pageBlock title="Successfully Imported Students">
      
          <apex:pageblocktable value="{!opplist}" var="opp" rendered="{!NOT(ISNULL(opplist))}">
          <apex:column headerValue="Opportunity ID">
              <apex:outputField value="{!opp.Id}"/>
          </apex:column>
          <apex:column headerValue="Opportunity Name">
              <apex:outputField value="{!opp.Name}"/>
          </apex:column>
          <apex:column headerValue="Expected Starte Date">
              <apex:outputField value="{!opp.CloseDate}"/>
          </apex:column>
          <apex:column headerValue="Campaign Source">
              <apex:outputField value="{!opp.CampaignId}"/>
          </apex:column>
          <apex:column headerValue="Opportunity Owner">
              <apex:outputField value="{!opp.OwnerId}"/>
          </apex:column>
      </apex:pageblocktable>            
       </apex:pageBlock>
           
   </apex:form>   
</apex:page>

 

Hello,
I'm using Webhook to retrieve data from a Form provider. Data is in json format. I would like to map the data to each field of Contact and Opportunity in order to create an Opportunity. I want to map the data to these to Maps

Map<String,String> contactMap = new Map<String,String>();
Map<String,String> opportunityMap = new Map<String,String>();
  
From there, I already wrote a class to create an Opportunity. All I need is to map the data to that map.

Does anyone know how to do that, I'm new to Apex and Salesforce?
Thank you in advance.
I'm trying to create an integration between Jotform and Salesforce via Webhook. Can you please help me find the Post Variable Name so that I can use it to code?
Thanks in advance.
Hi everyone,

I have a scheduled Apex class, but it's not on the Schedule list. Can you please help me what I did wrong?
 
global class LatePayment implements Schedulable {      
    global void execute(SchedulableContext ctx) {
        Date AcceptedDate;
        
        //Schedule the class to run on every Friday at 11:59PM
        String Cron_exp = '59 59 23 ? * FRI';
        String JobID = System.Schedule('Check Late Payment', Cron_exp, new LatePayment());
        
        //Creating Registration Deadlines Date table
        List<hed__Term__c> lstTerm = [SELECT Id, Name, Application_Session__c, Application_Year__c, Registration_Deadlines__c 
                                      FROM hed__Term__c
                                      WHERE Registration_Deadlines__c < TODAY
                                      ORDER BY Registration_Deadlines__c asc];
        
        //Creating a list of all Opp that are under Acceptance Letter Issued and Visa Pass stage
        List<Opportunity> lstOpp = [SELECT Id, Deferred__c, RecordTypeId, Name, StageName, Accepted_Letter_Issued_Date__c, Visa_Pass_Date__c, CloseDate,
                                   		Late_Payment__c, I_am_applying_for_the__c, Year_of_Semester__c
                                   FROM Opportunity
                                   WHERE (StageName = 'Visa Pass' OR StageName ='Acceptance Letter Issued')
                                   AND RecordTypeId != '0126A000000xOkkQAE' AND RecordTypeId != '0126A000000xOkfQAE'
                                   ORDER BY CloseDate asc];
        
        List<Opportunity> lstUpdate = new List<Opportunity>(); 
        if (!lstOpp.IsEmpty()) {
            for (Opportunity opp : lstOpp) {
                if ((opp.RecordTypeId == '0126A000000xOkVQAU' || opp.RecordTypeId == '0126A000000JHdYQAW')) {
                    if (opp.Deferred__c == false) {
                        AcceptedDate = opp.Visa_Pass_Date__c;
                    }
                    else {
                        AcceptedDate = opp.Accepted_Letter_Issued_Date__c;
                    }
                }
                else {
                    AcceptedDate = opp.Accepted_Letter_Issued_Date__c;
                }
                for (hed__Term__c terms : lstTerm) {  
                    if (opp.I_am_applying_for_the__c == terms.Application_Session__c && opp.Year_of_Semester__c == terms.Application_Year__c) {
                        if (AcceptedDate < terms.Registration_Deadlines__c.addDays(-7)) {
                            opp.Late_Payment__c = (terms.Registration_Deadlines__c.daysBetween(Date.today())+3) / 7;
                        }
                        else {
                            opp.Late_Payment__c = AcceptedDate.daysBetween(Date.today()) / 7;
                        }
                    }
                }
                lstUpdate.add(opp);
            }
            update lstUpdate;
        }
    }
}

 
Hi everyone!

We need to track students late payment. When they are accepted to our school, the Representatives will toggle "Acceptance Letter Issued" stage. When the students pay their fees, the Reps will toggle "Registered" as the students are ready to be enrolled.

We have a deadline for payment as well. If Reps don't toggle a different stage after "Acceptance Letter Issued" stage after the deadline, we want a custom field to indicate that the student is late on paying their fees.

What would be the best practice to accomplish this project? Please give me some advice.

Thank you!
Hi everyone,

I'm getting this error on line 58:
ystem.NullPointerException: Attempt to de-reference a null object

Below is the code. I'm planning to put this code on Process Builder. This code will transfer the opportunity to other representatives when the opportunity has been touched for 4 days. Before transferring away, it will create a record on Round Robin Record object. Record Distribution is the list of teams. Record Distribution Mapping is the list of Representatives with a lookup field to Record Distribution object.
 
public class RoundRobinOpp {
    public class RRRequest {
        @InvocableVariable
        public String opportunityName;
        
        @InvocableVariable
        public String distributionName;
        
        @InvocableVariable
        public Id opportunityId;
        
        @InvocableVariable
        public Id ownerId;   
    }
    
    public static List<Record_Distribution_Mapping__c> getRepsByDistribution(String distributionName) {
        return [select User__r.id, CreatedDate, Record_Distribution__c, Record_Distribution__r.Number_of_RR__c 
                from Record_Distribution_Mapping__c 
                where Record_Distribution__r.Name = :distributionName
                order by CreatedDate asc];
    }
    
    @InvocableMethod
    public static void RoundRobinOpp(List<RRRequest> requests) {
        Set<String> distributionnames = new Set<String>();
        Set<Id> username = new Set<Id>();
        
        for (RRRequest request : requests) {
			distributionnames.add(request.distributionName);
            username.add(request.ownerId);
        }
        
        Map<String, List<Record_Distribution_Mapping__c>> distributionToMappings = new Map<String, List<Record_Distribution_Mapping__c>>();
        Map<String, Record_Distribution__c> relevantDistributions = new Map<String, Record_Distribution__c>();
        Map<String, Record_Distribution_Mapping__c> relevantUser = new Map<String, Record_Distribution_Mapping__c>();
        
        for (Record_Distribution_Mapping__c users : [SELECT User__c, Opportunity_Name_1__c, Opportunity_Name_2__c, Opportunity_Name_3__c, Number_of_Opp__c
                                                     FROM Record_Distribution_Mapping__c WHERE User__c = :username]) {
                                                         relevantUser.put(users.User__c,users);
                                                     }
        
        for (Record_Distribution__c distribution : [select Name, Number_of_RR__c from Record_Distribution__c where name in :distributionnames]) {
			relevantDistributions.put(distribution.name, distribution);
		}
        
        for (String distributionName : distributionnames) {
			distributionToMappings.put(distributionName, getRepsByDistribution(distributionName));
		}      
        
        List<Round_Robin_Record__c> lstRRrecord = new List<Round_Robin_Record__c>();
        List<Opportunity> lstOppsToUpdate = new List<Opportunity>();
        for (RRRequest request : requests) {
            Round_Robin_Record__c newRecord = new Round_Robin_Record__c();
            newRecord.Opportunity_Name__c = request.opportunityName;
            newRecord.User__c = request.ownerId;
            
            Record_Distribution_Mapping__c updateRRnumber = relevantUser.get(request.ownerId);
            updateRRnumber.Number_of_Opp__c++;
            //Might add the opportunity names for reporting
            
            Opportunity reassignedOpp = new Opportunity(id = request.opportunityId);
            Record_Distribution__c TeamDistribution =  relevantDistributions.get(request.distributionName);
            reassignedOpp.OwnerId = distributionToMappings.get(request.distributionName)[Math.mod((Integer) TeamDistribution.Number_of_RR__c,
                                                                                                 distributionToMappings.get(request.distributionName).size())].User__r.id;
            lstRRrecord.add(newRecord);
            TeamDistribution.Number_of_RR__c++;
            lstOppsToUpdate.add(reassignedOpp);
        }
        
        insert lstRRrecord;
        update lstOppsToUpdate;
        update relevantDistributions.values();
        update relevantUser.values();
    }
}

I can't find the reason why the Number_of_Opp__c is empty, I have put 0 in that field for each record already.

Please help! Thanks in advance.
Hi everyone,

My sales users want to associate multiple campaigns to ONE opportunity. I have created 1 more lookup field called "Secondary Campaign". Now, they want to add another campaign, I don't want to create another lookup field.

Is there anyway that we can associate multiple campaigns to one opportunity?

Thanks in advance.

Hi everyone,

I'm new to Salesforce and Apex coding. I'm making a function so that user can upload a csv file to generate opportunity and contact. However, it hit the SOQL queries limit, I was able to upload maximum 12 rows.

I need to insert Contact first, in order to get an Contact Id and put it in Opportunity. Since I put the queries inside For loops plus other triggers, it exceeded the queries limit.

I'm planning to create an Apex Batch Process, but not sure if it will solve the problem.

Below is the Apex code and Visualforce page:

Apex:

public class FileUploader {
    private ApexPages.StandardController std;
    public string nameFile{get;set;}
    public Blob contentFile{get;set;}
    public Date closeDate {get;set;}
    public Id recordType {get;set;}
    public Id ownerId {get; set;}
    public List<opportunity> opplist{get;set;}
    public Contact con {get; set;}
    public Opportunity opp {get; set;}
    
    private final String integrationName = 'Inquiry Import';
    String campaignlookup;
    String[] filelines = new String[]{};
        
    public List<SelectOption> repSelectOptions {get {
        List<SelectOption> repSelectOptions = new List<SelectOption> {new SelectOption('','Select One')};
        for (User u : [SELECT Id, Name
                       FROM User 
                       WHERE UserType = 'Standard' AND 
                       IsActive = true
                       ORDER BY Name asc]) {
        	repSelectOptions.add(new SelectOption(u.Id, u.Name));
        }
        return repSelectOptions;
    }}
    
    public List<SelectOption> recordOptions {get {
        List<SelectOption> recordOptions = new List<SelectOption>{new SelectOption('','Select One')};
        
        for (RecordType r : [SELECT Id, Name FROM RecordType WHERE sobjecttype = 'Opportunity']) {
            recordOptions.add(new SelectOption(r.Id, r.Name));
        }
        return recordOptions;
    }}
    
    {
        initializeObjects();
    }
            
    public void initializeObjects() {
        con = new Contact();
        opp = new Opportunity();
    }
    
    public FileUploader() {
		opplist = New List<Opportunity>(); 
	}
    
    /***This function reads the CSV file and inserts records into objects. ***/
    public Pagereference ReadFile()
    {
        opplist.clear();
        try{
                //Convert the uploaded file which is in BLOB format into a string
                nameFile =blobToString( contentFile,'ISO-8859-1');
                
                //Now sepatate every row of the csv file
                filelines = nameFile.split('\n');
                
                //Iterate through every line and create a Record for each row
                for (Integer i=1; i<filelines.size(); i++)
                {                                       
                    String[] inputvalues = new String[]{};
                    inputvalues = filelines[i].split(',');
                    
                    con.FirstName = inputvalues[0] ;             
                 	con.LastName = inputvalues[1];
                 	con.MobilePhone = inputvalues[2];
                 	con.Personal_Email__c = inputvalues[3];
                 	con.OwnerId = this.ownerId;
                 	con.Integration__c = this.integrationName;
                 	insert con;
                 
                 	Contact queriedCon = [SELECT Id, FirstName, LastName, AccountId FROM Contact WHERE Id = :con.Id];
                 	opp.CloseDate = this.closeDate;
                 	opp.RecordTypeId = this.recordType;
                 	opp.OwnerId = this.ownerId;
				 	opp.Contact__c = queriedCon.Id;
				 	opp.AccountId = queriedCon.AccountId;
				 	opp.Name = queriedCon.FirstName + ' ' + queriedCon.LastName;
                 	opp.Program_of_Interest__c = inputvalues[4];
                    campaignlookup = inputvalues[5];
                    Campaign[] campaignId = [SELECT Id FROM Campaign WHERE Name = :campaignlookup];
                    if (campaignId.size() > 0) {
                        opp.CampaignId = campaignId[0].Id;
                    }
                 	opp.StageName = 'New';
        		 	opp.Integration__c = this.integrationName;
                 	insert opp;
                    opplist.add(opp);
                 
                 	Integration_Origin__c origin = new Integration_Origin__c();
        		 	origin.Contact__c = queriedCon.id;
        		 	origin.Opportunity__c = opp.id;
        		 	origin.Integration__c = [SELECT Id FROM Integration__c WHERE Name = :this.integrationName].Id;
        		 	insert origin;
                 
                 	initializeObjects();
                    campaignlookup = null;
                }
         }
         catch(Exception e){
             	initializeObjects();
                ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured reading the CSV file '+e.getMessage());
                ApexPages.addMessage(errormsg);
         }               
        return null;
    }
    
    public List<Opportunity> getuploadedOpp () {
        return opplist;
    }
        /**
         This function converts the input CSV file in BLOB format into a string
        @param input    Blob data representing correct string in @inCharset encoding
        @param inCharset    encoding of the Blob data
     */
    public static String blobToString(Blob input, String inCharset){
        String hex = EncodingUtil.convertToHex(input);
        System.assertEquals(0, hex.length() & 1);
        final Integer bytesCount = hex.length() >> 1;
        String[] bytes = new String[bytesCount];
        for(Integer i = 0; i < bytesCount; ++i)
            bytes[i] =  hex.mid(i << 1, 2);
        return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
    }
}

Visualforce Page:
 
<apex:page sidebar="false" controller="FileUploader" docType="html-5.0" lightningStylesheets="true">
    <apex:slds />
   <apex:form >
      <apex:sectionHeader title="Upload data from CSV file"/>
      <apex:pagemessages />
       
      <apex:pageBlock >
          <apex:pageBlockSection id="RequiredBlock" rendered="true" title="Required Information">		            
            <apex:input required="true" type="date" label="Expected Start Date"  value="{!CloseDate}"/>
            <apex:selectList required="true" id="recordtypeSelection" size="1" label="Student Type" value="{!recordType}">
            	<apex:selectOptions value="{!recordOptions}"/>
            </apex:selectList>
            <apex:selectList required="true" id="userSelect" size="1" label="Advisor" value="{!ownerId}">
            	<apex:selectOptions value="{!repSelectOptions}"/>
            </apex:selectList>
          </apex:pageBlockSection>
      </apex:pageBlock> 
       
      <apex:pageBlock >
             <!--  Component to allow user to upload file from local machine -->
             <center>
              <apex:inputFile value="{!contentFile}" filename="{!nameFile}" /> <apex:commandButton action="{!ReadFile}" value="Upload File" id="theButton" style="width:100px;"/>
              <br/> <br/> <font color="red"> <b>Note: Please use the standard template to upload Records. <a href="https://universities.my.salesforce.com/sfc/p/6A000000voho/a/3s000000PTVs/HzZ5Kbu_BdhxG51fDbiHaTMZHguLFRg6gjYC2e75BIg" target="_blank"> Click here </a> to download the template. </b> </font>
             </center>  
       </apex:pageBlock> 
      <!-- After the user clicks the 'Upload File' button, this section displays the inserted data -->
       <apex:pageBlock title="Successfully Imported Students">
      
          <apex:pageblocktable value="{!opplist}" var="opp" rendered="{!NOT(ISNULL(opplist))}">
          <apex:column headerValue="Opportunity ID">
              <apex:outputField value="{!opp.Id}"/>
          </apex:column>
          <apex:column headerValue="Opportunity Name">
              <apex:outputField value="{!opp.Name}"/>
          </apex:column>
          <apex:column headerValue="Expected Starte Date">
              <apex:outputField value="{!opp.CloseDate}"/>
          </apex:column>
          <apex:column headerValue="Campaign Source">
              <apex:outputField value="{!opp.CampaignId}"/>
          </apex:column>
          <apex:column headerValue="Opportunity Owner">
              <apex:outputField value="{!opp.OwnerId}"/>
          </apex:column>
      </apex:pageblocktable>            
       </apex:pageBlock>
           
   </apex:form>   
</apex:page>

 

Hi, guys

When I did the project named "Build a Discount Approval Process", I could not pass the verification of the step "Prepare Your Org". Then the information I got is "Step not yet complete in My Trailhead Playground 1, Couldn’t find Allison Wheeler with the correct information. Please double check the instructions."

I knew this question probably is not very hard, but I tried to follow that step instruction 3 times, and I got the same error. So I confuse that why what I did is not correct.

Please help me or give me some suggestions about that and I appreciate for your guys help.

Thank you so much. 
  • January 06, 2019
  • Like
  • 0
hai 
 please tell me the code to insert records related to multiple objects with the data from csv file using custom visualforce upload page, you can see preview of my page attached hereUser-added image

Thanks in advance