• Brian Nolau 2
  • NEWBIE
  • 0 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 7
    Questions
  • 9
    Replies
I have three tables. Pilots, Certifications, and the Linking Table Pilots_Certifications. 
User-added imageI enter Pilot Object fields PiFirstName, PiLastName as text. I enter Certification Object fields CertificationType, Plane as text.

Pilot_Certifications object has lookups to Pilot. Pilot_Certifications object has lookups to Certifications. The lookups only link to the autonumber Primary key field: 
User-added imageMy intent is to build a many to many relationship with Pilot_Certifications as the Linking, or Junction table. It works fine as is. I can apply Search Layouts on Pilot_Certification Lookups to include the name so that I can see "Brian" for example while selecting the Pilot instead of 1. 

When I do a lookup for Pilot_Certification, I want the value in the field to be matched based on the primary key to the Pilot table and to the Certifications table, but I want the value that is shown on the Pilot_Certification table to be PILOTFIRSTNAME/PILOTLASTNAME for the first Pilot lookup and PLANE/CERTIFICATIOTYPE for the Second Certification lookup.

It must be something with picklists or something.

I basically want the tables to work like in 33:35 to the end of this youtube video. I'm practicing my SOQL and not being able to setup tables like I do in Access is mad annoying because I can't progress in SOQL until I can make the tables how I want:
https://www.youtube.com/watch?v=nJCAcaGCHvE
Is it possible for a Process Builder to work with CSV Upload Import files for Leads and/or Contacts? It works when I create a manual record, but it doesn't work with uploads. 


I know what workflow rules are. I specifically want something from process builder. 
So i'm about 50% into my Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition) book and I'm stuck on the below code. I provide a text version under the image. The below code has no problems. When I create a new task nothing happens though and if I create a task with a Contact it has an issue that says: TaskTrigger: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.TaskTrigger: line 14, column 1

User-added imageText version of the code from Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition):

trigger TaskTrigger on Task (after insert, after update) {
    switch on Trigger.operationType {
        when AFTER_INSERT {
        Set<Id> contactIds = new Set<Id>();
    For(Task t: Trigger.new) {
    If(t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
    contactIds.add(t.WhoId);
    }
    }
    Map<Id, Contact> contactMap = new Map<Id, Contact> ([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in: contactIds]);

    For(Task t :Trigger.new) {
    If(contactMap.containsKey(t.WhoId)) {
    contactMap.get(t.WhoId).No_of_Open_Tasks__c += 1;
    }
    }
    Update contactMap.values();
    }
        when AFTER_UPDATE {            
        Set<ID> contactIds = new Set<Id>();
    For(Task t : Trigger.new) {
    If(t.IsClosed && !Trigger.oldMap.get(t.Id).IsClosed && t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
    contactIds.add(t.WhoId);
    }
    }
    Map<Id, Contact> contactMap = new Map<Id, Contact>([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in :contactIds]);

    For(Contact con : contactMap.values()) {
    Con.No_of_open_tasks__c = 0;
    }

    For(AggregateResult ar : [SELECT WhoId, Count(Id) total FROM Task WHERE IsClosed = false AND WhoId in :contactIds GROUP BY WhoID]) {
    String who = String.Valueof(ar.get('WhoId'));
    Decimal total = (Decimal)(ar.get('total'));
    contactMap.get(who).No_of_Open_Tasks__c = total;
    }
    update contactMap.values();
        }
        }
}
I was trying to read through "Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition)" but the author doesn't even introduce basic concepts in APEX and spends 100 pages introducing the entire language. He then introduces two concepts with triggers for creating invoice records when opportunities reach a certain stage and the second opportunity he introduces doesn't even work before getting into even more advanced concepts like Salesforce SQL. 

 
Apex Trigger Codeactual code:
trigger OpportunityTrigger on Opportunity (after update) {
    for(Opportunity opp : Trigger.new){
        if(opp.StageName == 'Closed/Won' && Trigger.oldMap.get(opp.Id).StageName != 'Closed/Won') {
        Invoice__c firstInvoice = new Invoice__c();
        firstInvoice.Amount__c =opp.Amount * 0.5;
        firstInvoice.Opportunity__c = opp.Id;
       
        Invoice__c secondInvoice = new Invoice__c();
        secondInvoice.Amount__c = opp.Amount * 0.5;
        secondInvoice.Opportunity__c = opp.Id;
           
        Invoice__c thirdInvoice = new Invoice__c();
        thirdInvoice.Amount__c = opp.Amount * 0.2;
        thirdInvoice.Opportunity__c = opp.Id;
           
            insert new List<Invoice__c>{firstInvoice, secondInvoice, thirdInvoice};
        }
    }
}


How do I now loop through the created List and create the new records in my custom Invoice Object with the values based on the Opportunity stage name changing to Closed/Won?
I have three tables. Pilots, Certifications, and the Linking Table Pilots_Certifications. 
User-added imageI enter Pilot Object fields PiFirstName, PiLastName as text. I enter Certification Object fields CertificationType, Plane as text.

Pilot_Certifications object has lookups to Pilot. Pilot_Certifications object has lookups to Certifications. The lookups only link to the autonumber Primary key field: 
User-added imageMy intent is to build a many to many relationship with Pilot_Certifications as the Linking, or Junction table. It works fine as is. I can apply Search Layouts on Pilot_Certification Lookups to include the name so that I can see "Brian" for example while selecting the Pilot instead of 1. 

When I do a lookup for Pilot_Certification, I want the value in the field to be matched based on the primary key to the Pilot table and to the Certifications table, but I want the value that is shown on the Pilot_Certification table to be PILOTFIRSTNAME/PILOTLASTNAME for the first Pilot lookup and PLANE/CERTIFICATIOTYPE for the Second Certification lookup.

It must be something with picklists or something.

I basically want the tables to work like in 33:35 to the end of this youtube video. I'm practicing my SOQL and not being able to setup tables like I do in Access is mad annoying because I can't progress in SOQL until I can make the tables how I want:
https://www.youtube.com/watch?v=nJCAcaGCHvE
Is it possible for a Process Builder to work with CSV Upload Import files for Leads and/or Contacts? It works when I create a manual record, but it doesn't work with uploads. 


I know what workflow rules are. I specifically want something from process builder. 
I have more than 500 records in invoice which is in related list to one account and the name of the account is "Account1"(Invoice- Account: Lookup relationship). Now Im try to insert more than 10 records into Invoice for the same account using dataloader. In that time only Im getting an error like "System.LimitException: Too many SOQL queries: 101". 
And my code is public class CommercientSF21InvoiceTriggerHandler1 {
    public static void accountUpdate(List<Invoice__c> currentRecordId){
        List<Account> accUpdate = new List<Account>();
        List<Account> accountWithoutInvoice = new List<Account>();
        Id accountId;
        for(Invoice__c acc : currentRecordId ){
            accountId = acc.Account__c;
        }
        List<Invoice__c> invoiceList = [select Id,CommercientSF21_IVM_InvoiceDate__c from Invoice__c where Account__c=: accountId];
        System.debug(invoiceList.size());
         for(Account acc : [select id,Current_Year_Revenue__c,Last_Order_Date__c,
                           Previous_Year_Revenue__c from Account where Id =:accountId]){
                               if(invoiceList.size() == 0){
                                   acc.Current_Year_Revenue__c = NULL;
                                   acc.Lifetime_Value_LTV__c = NULL;
                                   acc.Previous_Year_Revenue__c = NULL;
                                   accountWithoutInvoice.add(acc);
                               }
                           }
        map<id,account> accmap = new map<id,account>();
        accmap.putall(accountWithoutInvoice);
        if(accmap.size()>0){
            update accmap.values();
        }
        Set<Id> currentYearRecordIds = new Set<Id>();
        Set<Id> previousYearRecordIds = new Set<Id>();
        for(integer i=0; i<invoiceList.size(); i++){ 
            Datetime record = invoiceList[i].CommercientSF21_IVM_InvoiceDate__c;
            if(record != NULL){ 
                String yearoftherecord = String.valueOf(record.Year());
                Integer curentYear = Date.Today().Year();
                String currentYearInteger = String.valueOf(curentYear);
                Integer previousyear = curentYear -1;
                String previousyearInteger = String.valueOf(previousyear);
                if(currentYearInteger == yearoftherecord ){
                    currentYearRecordIds.add(invoiceList[i].Id);
                }
                else if(previousyearInteger == yearoftherecord){
                    previousYearRecordIds.add(invoiceList[i].Id);
                }
            }
        }
        List<AggregateResult> currentYearAmountList = [SELECT SUM(CommercientSF21_IVM_InvoiceAmt_c__c )tot FROM Invoice__c WHERE Id= :currentYearRecordIds];
        List<AggregateResult> previousYearAmountList = [SELECT SUM(CommercientSF21_IVM_InvoiceAmt_c__c )tot FROM Invoice__c WHERE Id= :previousYearRecordIds];
        List<AggregateResult> totalAmountList = [SELECT SUM(CommercientSF21_IVM_InvoiceAmt_c__c )tot FROM Invoice__c WHERE Account__c =: accountId ];
        System.debug(totalAmountList);
        Object sumAmountCurrentYear;
        Object sumAmountPreviousYear; 
        Object sumAmountTotalYear;
        for(AggregateResult acc : currentYearAmountList){
            sumAmountCurrentYear = acc.get('tot');  
        }
        for(AggregateResult acc : previousYearAmountList){
            sumAmountPreviousYear = acc.get('tot');  
        }
        
        for(AggregateResult acc : totalAmountList){
            sumAmountTotalYear = acc.get('tot');  
        }
        for(Account acc: [select id,Current_Year_Revenue__c,Last_Order_Date__c,
                          Previous_Year_Revenue__c from Account where Id =: accountId] ){
                              acc.Previous_Year_Revenue__c = Integer.valueOf(sumAmountPreviousYear);
                              acc.Current_Year_Revenue__c = Integer.valueOf(sumAmountCurrentYear);
                              acc.Lifetime_Value_LTV__c = Integer.valueOf(sumAmountTotalYear);
                              accUpdate.add(acc);
                          }
        map<id,account> accMapToUpdate = new map<id,account>();
        accMapToUpdate.putall(accUpdate);
        if(accMapToUpdate.size()>0){
            update accMapToUpdate.values();
        } 
    } 
}
So i'm about 50% into my Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition) book and I'm stuck on the below code. I provide a text version under the image. The below code has no problems. When I create a new task nothing happens though and if I create a task with a Contact it has an issue that says: TaskTrigger: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.TaskTrigger: line 14, column 1

User-added imageText version of the code from Learning Salesforce Development with Apex: Write, Run and Deploy Apex Code with Ease (English Edition):

trigger TaskTrigger on Task (after insert, after update) {
    switch on Trigger.operationType {
        when AFTER_INSERT {
        Set<Id> contactIds = new Set<Id>();
    For(Task t: Trigger.new) {
    If(t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
    contactIds.add(t.WhoId);
    }
    }
    Map<Id, Contact> contactMap = new Map<Id, Contact> ([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in: contactIds]);

    For(Task t :Trigger.new) {
    If(contactMap.containsKey(t.WhoId)) {
    contactMap.get(t.WhoId).No_of_Open_Tasks__c += 1;
    }
    }
    Update contactMap.values();
    }
        when AFTER_UPDATE {            
        Set<ID> contactIds = new Set<Id>();
    For(Task t : Trigger.new) {
    If(t.IsClosed && !Trigger.oldMap.get(t.Id).IsClosed && t.WhoId != null && String.valueOf(t.WhoId).startsWith('003')) {
    contactIds.add(t.WhoId);
    }
    }
    Map<Id, Contact> contactMap = new Map<Id, Contact>([SELECT Id, No_Of_Open_Tasks__c FROM Contact WHERE Id in :contactIds]);

    For(Contact con : contactMap.values()) {
    Con.No_of_open_tasks__c = 0;
    }

    For(AggregateResult ar : [SELECT WhoId, Count(Id) total FROM Task WHERE IsClosed = false AND WhoId in :contactIds GROUP BY WhoID]) {
    String who = String.Valueof(ar.get('WhoId'));
    Decimal total = (Decimal)(ar.get('total'));
    contactMap.get(who).No_of_Open_Tasks__c = total;
    }
    update contactMap.values();
        }
        }
}
Apex Trigger Codeactual code:
trigger OpportunityTrigger on Opportunity (after update) {
    for(Opportunity opp : Trigger.new){
        if(opp.StageName == 'Closed/Won' && Trigger.oldMap.get(opp.Id).StageName != 'Closed/Won') {
        Invoice__c firstInvoice = new Invoice__c();
        firstInvoice.Amount__c =opp.Amount * 0.5;
        firstInvoice.Opportunity__c = opp.Id;
       
        Invoice__c secondInvoice = new Invoice__c();
        secondInvoice.Amount__c = opp.Amount * 0.5;
        secondInvoice.Opportunity__c = opp.Id;
           
        Invoice__c thirdInvoice = new Invoice__c();
        thirdInvoice.Amount__c = opp.Amount * 0.2;
        thirdInvoice.Opportunity__c = opp.Id;
           
            insert new List<Invoice__c>{firstInvoice, secondInvoice, thirdInvoice};
        }
    }
}


How do I now loop through the created List and create the new records in my custom Invoice Object with the values based on the Opportunity stage name changing to Closed/Won?