• Phuc Nguyen 18
  • SMARTIE
  • 680 Points
  • Member since 2019

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 108
    Questions
  • 140
    Replies
Hello All,
Trying to detect when a formula field is being updated in my Apex Class  but I am only seeing the original value.  I can see the new value on the page layout and can see the update in the history.  I am working in the after update of the Apex Class.  Any thoughts why I am not seeing the new value in the class?
Thanks,
P
Hello All,
Was wondering if someone will help me with the best approach for adding  multiple child records:
Parent is Project  and finance is child.  The Child records will mostly be the same exexpt for a text field that I will populate:
List<Finance__c> finline = new List<Finance__c>();   

if(trigger.isInsert){        
            for (SObject so : Trigger.New) {
                Project__c newP = (Project__c) so;
                
                if (newP.ProjectChild__c != null ) { 
                   Finance__c newF = new Finance__c();
                        newF.Subject = newP.ProjectSubject__c;
                        newF.description__c = 'Custom text for finance record';
                        finline .add(newF);

                        newF.Subject = newP.ProjectSubject__c;
                        newF.description__c = 'Another Custom text for finance record';
                        finline .add(newF);

                }
            }
        }
Was wondering if there is a better way to perform this action.  There will be 5-6 child records.  Also, I will a different child record that will be created off the same parent record and there may be 3-4 records for this custom object.  
Any suggestions would be greatly appreciated.
Cheers,
P
 
Hello Everone,
I ahve the below batch class and was wondering if ther eis a way to throw up a message to let the user know that the update is happening.  Its a batch and some of the recvords have 100+ child records so it will take a awhile for the batch classes to complete. 
public class UpdateNoticeFromAccountQueueableBatch implements Database.Batchable <sObject>, Database.Stateful{
    public List<Notice__c> noticeList = new List<Notice__c>();
    public String vatQueVatValue;
    public UpdateNoticeFromAccountQueueableBatch ( List<Notice__c> records ,String vatValueFromQue ) {
        noticeList = records;
        vatQueVatValue = vatValueFromQue;
        system.debug('noticeList value in batch' + noticeList );
        system.debug('vatQueVatValue value in batch' + vatQueVatValue );
    }
    public List<SObject> start(Database.BatchableContext bc){
        return noticeList;
    }
    public void execute(Database.BatchableContext bc, List<Notice__c> scope){
         List< notice>  NoticeToUpdateFromAccount = new List<Notice__c>();   
         system.debug('scope value ' + scope);
         system.debug('vatQueVatValue value batch' + vatQueVatValue);
         if(!scope.isEmpty()){
             For ( Notice__c noticess : scope){  
               noticess.Any_other_Lessor_Info_VAT_Number__c  = vatQueVatValue;
             }
         Database.update(scope, false);
         ---- add label message here to notify user that batch is running?
         }   
       
    }

Just don't want the user guessing what is going on.

Thanks you.
P
Hello,
Having an issue saving my class.  getting 
Compile Error: Invalid loop variable type expected SObject was Notice__c

I am passing the parameters from another Class and I am trying to update a field on the Notice__c object with teh vatQueVatValue value
If you see any other issues with the batch class please also advise.
public class UpdateNoticeFromAccountQueueableBatch implements Database.Batchable <sObject>, Database.Stateful{
    public List<Notice__c> noticeList = new List<Notice__c>();
    public String vatQueVatValue;
    public UpdateNoticeFromAccountQueueableBatch ( List<Notice__c> records ,String vatValueFromQue ) {
        noticeList = records;
        vatQueVatValue = vatValueFromQue;
        system.debug('noticeList value in batch' + noticeList );
        system.debug('vatQueVatValue value in batch' + vatQueVatValue );
    }
    public List<SObject> start(Database.BatchableContext bc){
        return noticeList;
    }
    public void execute(Database.BatchableContext bc, List<SObject> scope){
         List< notice>  NoticeToUpdateFromAccount = new List<Notice__c>();   
         system.debug('scope value ' + scope);
         system.debug('vatQueVatValue value batch' + vatQueVatValue);
         if(!scope.isEmpty()){
             For ( Notice__c noticess : scope){  ---- Compile Error: Invalid loop variable type expected SObject was notice Notice__c 
               noticess.Any_other_Lessor_Info_VAT_Number__c  = vatQueVatValue;
              system.debug('notices.Any_other_Lessor_Info_VAT_Number__c ' + notices.Any_other_Lessor_Info_VAT_Number__c);
             }
         }   
         Database.update(scope, false);
    }
    public void finish(Database.BatchableContext bc){
    }
}

Cheers,
P
 
Hello All,
Going in circles over how to resolve this.
I have Object Projects.  
The Project has a lookup to an Account
The account can reside on multiple Projects

So Project 1, Project 2, Project 3 all have the same loopup record 'Account Test'
So if field 'user' is Updated on Project 1.  How can I update the 'user' field on Project 2 and Project 3. 

Cheers,
P


 
Hello All,
I have a LWC where I need to get the count of records where the record name is alike.  For example the record names are Test, Test2, Test3.  I would want to retrieve the count of 3 so that when I create the new record I can append teh count to the end of the new recods Name.
Any help is greatly appreciated.
Cheers,
P
Trying to call a Class method from a test class:
Class UtilHelper
global class FeeWrapper { global List<Project__c> transToUpdate; } 

public static FeeWrapper PassingRentFee(Fee_Calculation__c Config, Project__c trans, List<Project__c> transToUpdate, Map<String, Fee_Mapping__c> m_Fee)



Test class
Map<String,Fee_Mapping__c > afMap = new Map<String,Fee_Mapping__c >( [ SELECT Id, Fee_Amount__c , _Fee_Basis__c , WO__c,Group__c,Type__c,Macro_Type__c FROM Fee_Mapping__c]); 

List<Fee_Calculation__c > feeRec = [ SELECT Id, Name FROM Fee_Calculation__c]; 

List<Project__c> projectRec = [ SELECT Id, Name FROM Project__c]

UtilHelper.PassingRentFee(feeRec[0],projectRec[0],projectRec[0],afMap);

Error is Method does not exist or incorrect signature
Any suggesitons are appreciated
P
Hello All,
I have an issue and not sure how to approach it.
I have a Parent record 'Product'
And multiple child records 'Items'
If a user inserts an item name 'Test 1' then assign field desc__c to '1000'
And if another Item record name 'Test 1' is inserted then assign field desc__c to '2000'.  This format would continue
These Item records may be dataloaded so basically the original item will have a desc__c field value of '1000' and all other records with the same name value would have a desc__c field value that is incremented by 1000.
I am not sure how to even approach this.  Aggragate all records that are being inserted and look for a count greater than 1? 
User will also be able to manually insert indivisual item record.
Any suggestions would be greatly appreciated.
Cheers,
P
I am trying to get a vlaue from a map to use in an If statement
I need to get the status value from the m_cl map.  How do I do that?
Thank you,
P
 
Map<Id,Checklist__c> m_cl = new Map<Id, Checklist__c>();
Set<Id> checkListIds = new Set<Id>();
        Set<Id> prjIds = new Set<Id>();
        Set<Id> prjNcIds = new Set<Id>();
        Set<Id> checkListNcIds = new Set<Id>();

        if(Trigger.isUpdate) {            
            for (SObject so : Trigger.New) {
              Checklist__c newCL = (Checklist__c) so;
              Checklist__c oldCL = Trigger.oldMap != null && Trigger.oldMap.containsKey(newCL.Id)
                ? (Checklist__c) Trigger.oldMap.get(newCL.Id)
                : null;

                    if(newCL.Status__c != oldCL.Status__c && (newCL.Status__c == 'Complete' || oldCL.Status__c == 'In Progress')){
                        m_cl.put(newCL.Activity__c, newCL);
                        checkListIds.add(newCL.Id);
                        prjIds.add(newCL.Project__c);
                    }

            }

            if(checkListIds.size()> 0){
                act = [Select id,Name,Project__c, Project__r.RC_Completed__c, Project__r.M5_Completed__c,Checklist__r.Status__c,Checklist__r.Name,Checklist__c,Form_Complete__c
                      FROM Activity__c 
                      WHERE Form_Complete__c = false 
                      AND Checklist__c IN : checkListIds
                      ];

                prj = [Select id, Name, RC_Completed__c ,M5_Completed__c 
                       FROM Project__c 
                       WHERE Id IN : prjIds];
              
                if( act.size() > 0){
                    for(Activity__c acts : act){
                        formName = acts.Checklist__r.Name.split(':');    
                        if(formName[1] == 'Pre-M5 Check List Form' && m_cl.get('Status__c') == 'Complete'){
                            acts.M5_Completed__c = true;
                            actToUpdate.add(acts);
                        }
                        else {
                            acts.RC_Completed__c = true;
                            actToUpdate.add(acts);
                        }
                    }
                }

 
Hello All,
I have a Queueable class that I want to execute in a Batch class but I am not sure how to pass the list of Leases to the Batch and execute. 
Any suggestions will be greatly appreciated.
public  class UpdateLeaseQueueable implements Queueable {
    
    List<Lease__c> updateLeases = new List<Lease__c>();

    public UpdateLeaseQueueable( Map<Id, Lease__c> leases) {
        updateLeases.addAll(leases.Values());
    }

    public void execute(QueueableContext qc) {  

        if (!updateLeases.isEmpty()) { 
           //pass leases to Batch class
        }
    }
}


Batch
global class UpdateLeaseQueueableBatch implements Database.Batchable <sObject>, Database.Stateful{
   
    global Database.QueryLocator start(Database.BatchableContext bc){
        
    }
    
    global void execute(Database.BatchableContext bc, List<> listLease){
       
    }
    
    global void finish(Database.BatchableContext bc){
    }
}


Cheers,
P
Hello,
I could use some help on how to create a validation rule that forces users to fomat their text input
For example.  I need the user input to be like 
A.123456.D.54 OR A.789456.E.89
First letter needs to be an A followed by a . followed by 6 digits(numbers only) followed by a . followed by a D or E  then followed by a . and then followed by 2 digits(numbers only)
Can I do this in a validation rule? 
Thank you,
P
 
Hello All,
Currently I am attaching a PDF that is dynamically generated and atatching it to an email.  All done via controller.
The email itself has become more complicated and the users want to be able to update the email as needed so I need to utilize a SF email template instead of my email controller.  Is this possible?  Use SF email tempalte and dynamically attach a file?  This file is not attched to the record.  I am currently rendering it as a pdf and attaching it before I send.  
Thank you,
P
I have delete batch that I would like to improve by using the existing mapping(m_finNums) but when I did I would get a duplicate id error on update.  I am looking at 3 fields on FInance record and to match them with the ones on teh DCON record. 
So to get around it I created 2 for loops which seems ineffecient. Any suggestions why I am getting the error would be appreciated
global class BatchFinanceUpdateFromDCON implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext BC)
    {        
        Date yesterday = System.today() - 2;
        String query = 'SELECT Id, Requisition_Number__c, PO_Line_Description__c, DCONFinanceKeyField__c, PO_Number__c, PO_Line_Number__c,' +
                      'Goods_Received_Date__c,Record_Marked_for_Deletion__c FROM DCON_Cube_Data__c WHERE Record_Marked_for_Deletion__c = false AND '+
                      'LastModifiedDate > yesterday AND (Requisition_Number__c != null AND PO_Line_Description__c != null) AND ' +
                      '(PO_Number__c != null OR PO_Line_Number__c != Null OR Goods_Received_Date__c != null)';

       return Database.getQueryLocator(query);
    }
  
    global void execute(Database.BatchableContext BC, List<SObject> scope)
    {                   
        List<DCON_Cube_Data__c> matchDCONAndFin = (List<DCON_Cube_Data__c>)scope;
        Set<String> odapIds = new Set<String>();
        List<Finance__c> finListToUpdate = new List<Finance__c>();
        List<Finance__c> listOfFinance = new List<Finance__c>();
        List<Finance__c> listOfFinanceAllValues = new List<Finance__c>();
        List<DCON_Cube_Data__c> listOfDCONToDelete = new List<DCON_Cube_Data__c>();
        List<DCON_Cube_Data__c> DCONListToUpdate = new List<DCON_Cube_Data__c>();
        Date yesterday = System.today() - 2;

        for (DCON_Cube_Data__c DCONs : matchDCONAndFin){
            if(DCONs.PO_Line_Description__c != null && DCONs.Requisition_Number__c != null){
                odapIds.add(DCONs.DCONFinanceKeyField__c);
            }
        }

        if (!odapIds.isEmpty()) {
            listOfFinance = [SELECT Id, finDCONKeyField__c, PO_Number_Custom__c, PO_Line_Number_Custom__c, Goods_Received_Date__c ,Actual_Date__c
                                                              FROM Finance__c 
                                                              WHERE (PO_Number_Custom__c = null OR PO_Line_Number_Custom__c = Null OR Goods_Received_Date__c = null) 
                                                              AND finDCONKeyField__c in : odapIds];
        }

        Map<String, Finance__c> m_finNums = new  Map<String, Finance__c>();
        Map<String, DCON_Cube_Data__c> o_DCONNums = new  Map<String, DCON_Cube_Data__c>();
    
        for(Finance__c fins : listOfFinance){
            m_finNums.put(fins.finDCONKeyField__c, fins);
        }

         for(DCON_Cube_Data__c DCON : matchDCONAndFin){
             o_DCONNums.put(DCON.DCONFinanceKeyField__c, DCON);
         }
         
        for (DCON_Cube_Data__c DCONs : o_DCONNums.values()){                                      
            for(Finance__c finObj : listOfFinance){
                if(finObj.finDCONKeyField__c == DCONs.DCONFinanceKeyField__c ){    
                    if(finObj.Actual_Date__c == null){
                        finObj.Actual_Date__c = System.today();
                    }
                        if(DCONs.PO_Number__c != null && finObj.PO_Number_Custom__c == null){
                                finObj.PO_Number_Custom__c = DCONs.PO_Number__c;
                        }
                            if(DCONs.PO_Line_Number__c != null && finObj.PO_Line_Number_Custom__c == null){
                                finObj.PO_Line_Number_Custom__c = DCONs.PO_Line_Number__c;
                            }
                                if(DCONs.Goods_Received_Date__c != null && finObj.Goods_Received_Date__c == null){
                                    finObj.Goods_Received_Date__c = DCONs.Goods_Received_Date__c;
                                }
                        finListToUpdate.add(finObj);             
                } 
            } 
        }

        if(!finListToUpdate.isEmpty()){
            Database.update(finListToUpdate, false);
        }               
   }

    global void finish(Database.BatchableContext BC){
        BatchUpdateDCONForDeletion bd = new BatchUpdateDCONForDeletion();
        Database.executeBatch(bd, 200);
   }    
}

Thank you,
P
Hello,
Is there a way to hide/remove the Cancel button ona  visualforce page?  When the button is clicked I can see that the Save button is greyed out but the cancel is not.  The page does disapear but I do not want the user to accidently click the cancel button.

VF Page
<apex:page standardController="Project__c" extensions="CreateNewProRecord" action="{!newRecord}"/>

Thanks,
P
I need some help with solving an issue where I wan tto improve the user experince.  Currently I have a quaick action that has no fields on teh page except for Name whcih is requirted.  I defaulted the vlaue to 'Leave Blank".  I do this because I have a custom controller that assigned the name and updated other fields.  How can I remove the need for the user to have to do anything.  Ideally they would click the new button and it would generate the record. ANy suggestions 
Will someone help me with writing a test class for my email class?
 
public with sharing class PDF_EmailController {
    
    @auraEnabled

    public static void SendAttachment(String recordId){
           
        for(Purchase_Order_Request__c por : [SELECT Id, Email_Address__c FROM Purchase_Order__c
        WHERE Id =: recordId]){
            Messaging.SingleEmailMessage semail = new Messaging.SingleEmailMessage();
            Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();

            PageReference pref = page.POPDF;
            pref.getParameters().put('Id',por.Id);
            pref.setRedirect(true);
            Blob b = pref.getContent();
            attach.setFileName('POR.pdf');
            attach.setBody(b);
            semail.setSubject('Purchase Order Request Details');
            semail.setToAddresses(new String[] { por.Email_Address__c });
            semail.setPlainTextBody('Please find the attached POR details');
            semail.setFileAttachments(new Messaging.EmailFileAttachment[]{attach});
            Messaging.sendEmail(new Messaging.SingleEmailMessage[]{semail});

        }

        for(Purchase_Order_Request__c por : [SELECT Id, Email_Address__c,Version__c FROM Purchase_Order__c
                                             WHERE Id =: recordId]){
            PageReference PDf =  Page.PORequestPDF;
            PDf.getParameters().put('Id',por.Id);
            PDf.setRedirect(true);
            Attachment attach = new Attachment();
            Blob b ;
            b = PDf.getContent();
            attach.Body = b;
            attach.Name = 'Purchase Order Confirmation ' + System.today();
            attach.IsPrivate = false;
            attach.ParentId = por.Id;
            insert attach;

        }
    }
 }



Visualforce Page

<apex:page controller="PDF_EmailController" standardStylesheets="false" showHeader="false">    
    <center>
        <P style="font-size:22px;"><u>Send Purchase Order Request</u></P>
        <input type="text" value="" id="txtEmailAddress"/><br/><br/>
        <input type="button" onclick="SendEmailAttachment();" value="Send"/>
    </center>
    <script>
    function SendEmailAttachment(){
        var PORId = '{!$CurrentPage.parameters.Id}';
        var emailAddress=document.getElementById('txtEmailAddress').value;
        if(emailAddress!=null && emailAddress!=''){
            TestHandler.SendAttachment(emailAddress,porId,function(result,event){
                if(event.status){
                    if(result=='SUCCESS'){
                        alert('Email sent successfully.');
                    }
                    else{
                        alert(result);
                    }
                }
            })
        }
        else{
            alert('Please provide email address!');
        }
    }
    </script>
 </apex:page>

Thank you,
P
Hello,
I need to be able to create a child record from a botton with users having to enter the name.  So a user select the 'New Button' on teh aprent and a child record is created.  I have a class that populates the vlaues on the new child record but the'Name' field is required and I do not need them to enter the name field.  Any suggestion would be appreciated
Thanks
P
Hello All,
I have a VF page that renders record information as shows it as a PDF .  I am using renderAs="PDF"
How can I now email that PDF?
I thought I needed an email controller show below
RequestPDF is the name of the VF PDF page that is rendering the data.  How do I pass the id to the controller?  I would like to try with either a button or maybe when a user updates and saves the record.  Either way the id and email address is sent to the controller.  And if the email address is null prompt for 1? 
public with sharing class RequestPDF_EmailController {
    
    @RemoteAction
    public static string SendAttachment(String sEmailAddress, String tempId){
        String sMessage='';
        try{            
            Messaging.SingleEmailMessage semail = new Messaging.SingleEmailMessage();
            Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();

            PageReference pref = page.RequestPDF;
            pref.getParameters().put('id',tempId);
            pref.setRedirect(true);
            Blob b = pref.getContent();
            attach.setFileName('AttachedInV.pdf');
            attach.setBody(b);
            semail.setSubject('Inv Details');
            semail.setToAddresses(new List<String>{sEmailAddress});
            semail.setPlainTextBody('Please find the attached INV details');
            semail.setFileAttachments(new Messaging.EmailFileAttachment[]{attach});
            Messaging.sendEmail(new Messaging.SingleEmailMessage[]{semail});
            sMessage='SUCCESS';
        }
        catch(Exception ex){
            sMessage=ex.getMessage()+'\n'+ex.getLineNumber()+'\n'+ex.getCause();
        }
        return sMessage;
    }
 }

Thank you,
P

Hello All,
I have a test class where I am updating a checkbox.  In the Apex Class this would create 2 new records.  The tets class fails when I perform the update.  The record I am updating exist since I checked in an assertion so not sure why I am getting an error:
 Attempt to de-reference a null object.
Would that tyupe of error message be due to information missing in my test data or the creation of the neww records?
Cheers,

P

I am wondering how do I cover code that is related to cusotm metadata.
class:
public with sharing class ApplicationServices {

    public static final String APPLICATION_STATUS_DRAFT = 'Draft';
    public string coloTemplateName;

    public static List<ApplicationProjectTemplateConfig__mdt> templateConfigs = [SELECT Id,ApplicationCriteria__c,ProjectTemplateName__c from ApplicationProjectTemplateConfig__mdt];
     
    public static Map<String, SObject> templatesByNameMap {
        get{
            if(templatesByNameMap == null){
                list<Project_Template__c> templates = [Select Id, Name FROM Project_Template__c WHERE 
Active__c =: true];
                templatesByNameMap = PGE_EDSUtils.createMapByStringFieldSingleObject(templates, 'Name');
            }

            return templatesByNameMap;
        }
        private set;
    }

    public static void handleSubmit(Map<Id, Application__c> applications) {
        // Only before update
        if( !Trigger.isBefore || !Trigger.isUpdate ) {
            return;
        }
      
        // Determine the projects to create, if any
        Map<Application__c, Project__c> projectsToCreate = new Map<Application__c, Project__c>();
        for(Application__c application : applications.values()) {
            boolean docreate = shouldCreateColoProject(application);
            if( docreate ) {
                Project__c project = createColoProject(application);
                   if(project != null){
                        projectsToCreate.put(application, project);
                    }
            }
        }


///no code coverage
        if(projectsToCreate.size() > 0) {
            insert projectsToCreate.values();
            for(Application__c application : projectsToCreate.keySet()) {
                Project__c project = projectsToCreate.get(application);
                application.Project__c = project.Id;
                application.Date_Submitted__c = application.Date_Submitted__c == null
                                                ? System.today()
                                                : application.Date_Submitted__c ;
            }
        }
    }

///no code coverage
     public static String coloTemplateName {
        get {
            if(coloTemplateName == null) {
                coloTemplateName = AppConfig.getAppConfigValue('COL_PROJECT_TEMPLATE');
            }
            return coloTemplateName;
        }
        private set;
    }

///no code coverage
    public static Id coloTemplateId {
        get {
            if(coloTemplateId == null) {
                if(String.isNotEmpty(coloTemplateName)) {
                    Project_Template__c template = [SELECT Id 
                                                                 FROM Project_Template__c
                                                                 WHERE Name =: coloTemplateName LIMIT 1];
                    coloTemplateId = template.Id;
                }
            }
            return coloTemplateId;
        }
        private set;
    }


    public static Boolean shouldCreateColoProject(Application__c application) {
        return !isDraft(application) && !hasProject(application);
    }

    private static Boolean isDraft(Application__c application) {
        return application.Application_Status__c == APPLICATION_STATUS_DRAFT;
    }

    private static Boolean hasProject(Application__c application) {
        return application.Project__c != null;
    }

  
    public static Project__c createColoProject(Application__c application) {
        Project__c project = null;
        string projectTemplate;
   
        for( ApplicationProjectTemplateConfig__mdt  config :templateConfigs){
            boolean templatematch = BooleanLogicEvaluation.evaluate(application , config.ApplicationCriteria__c);
     
            if(templatematch){
                projectTemplate = config.ProjectTemplateName__c;
                break;
            }
         } 
      
         if (projectTemplate!=null && templatesByNameMap.containsKey(projectTemplate)){
           // no code coverage
            project = new Project__c(
                AccountSite__c =  application.AccountSite__c 
                OwnerId = application.ownerId,
                application__c = application.Id,
                ProjectTemplate__c = templatesByNameMap.get(projectTemplate).id,
                Project_Start_Date_A__c = System.today()
            );
         }

        return project;
    }

}
Test Class
static testMethod void testApplicationBasicCRUD() {
    	AccountSite__c  as = [SELECT Id FROM AccountSite__c LIMIT 1];
        Test.startTest();

        Application__c application = new Application__c(
            Application_Type__c = 'NewAgreement',
            Scope_of_Work__c = 'Test Setup',
            AccountSite__c = as.Id
        );
        insert application;
        System.assert(application.Id != null, 'Successfully created application');

        // Update
        application.Tenant_AccountSite_Name__c = ' Mountain';
        application.Tenant_AccountSite_Number__c = '123';
        update application;
        System.assert(application.Id != null, 'Successfully updates application');

        // Delete
        delete application;
        System.assert(true, 'Successfully deleted application');

        Test.stopTest();
    }

    static testMethod void testAutomaticProjectCreation() {
    	AccountSite__c  as= [SELECT Id FROM AccountSite__c  LIMIT 1];

        Test.startTest();
        Application__c application = new Application__c(
            Application_Type__c = 'NewAgreement',
            Scope_of_Work__c = 'Test Setup',
            Date_Submitted__c = System.today(),
            AccountSite__c = as.Id
        );
        insert application;

        application.Application_Status__c = 'Feasibility';
        application.Approval_Status__c = 'Pending';
        update application;
        
        application = [SELECT id, Project__c,  Date_Submitted__c FROM Application__c where id=: application.Id];
        System.assertEquals(System.today(), application.Date_Submitted__c, 'Date Submitted Set');
     
        Test.stopTest();
    }


    @testSetup
    private static void createTestData() {

       
        AccountSite__c as = new AccountSite__c (
            Name = 'Casterly Rock'
        );
        insert as;

      
        Project_Template__c template = new Project_Template__c (
            Name = 'Collocation',
            Active__c = true,
            Object__c  = 'Project__c',
            Project_Extension_Objects__c = 'Coll_Project__c'
        );
        insert template;

        Collocation__c collocation = new Collocation__c (
            Name = '100ft',
            AccountSite__c = as.Id
        );
        insert collocation;

        Application__c application = new Application__c (
            Application_Type__c = 'NewAgreement',
            Scope_of_Work__c = 'Test Setup',
            AccountSite__c = as.Id
        );
        insert application;

    }


}


 
Hello All,
Was wondering if someone will help me with the best approach for adding  multiple child records:
Parent is Project  and finance is child.  The Child records will mostly be the same exexpt for a text field that I will populate:
List<Finance__c> finline = new List<Finance__c>();   

if(trigger.isInsert){        
            for (SObject so : Trigger.New) {
                Project__c newP = (Project__c) so;
                
                if (newP.ProjectChild__c != null ) { 
                   Finance__c newF = new Finance__c();
                        newF.Subject = newP.ProjectSubject__c;
                        newF.description__c = 'Custom text for finance record';
                        finline .add(newF);

                        newF.Subject = newP.ProjectSubject__c;
                        newF.description__c = 'Another Custom text for finance record';
                        finline .add(newF);

                }
            }
        }
Was wondering if there is a better way to perform this action.  There will be 5-6 child records.  Also, I will a different child record that will be created off the same parent record and there may be 3-4 records for this custom object.  
Any suggestions would be greatly appreciated.
Cheers,
P
 
Hello Everone,
I ahve the below batch class and was wondering if ther eis a way to throw up a message to let the user know that the update is happening.  Its a batch and some of the recvords have 100+ child records so it will take a awhile for the batch classes to complete. 
public class UpdateNoticeFromAccountQueueableBatch implements Database.Batchable <sObject>, Database.Stateful{
    public List<Notice__c> noticeList = new List<Notice__c>();
    public String vatQueVatValue;
    public UpdateNoticeFromAccountQueueableBatch ( List<Notice__c> records ,String vatValueFromQue ) {
        noticeList = records;
        vatQueVatValue = vatValueFromQue;
        system.debug('noticeList value in batch' + noticeList );
        system.debug('vatQueVatValue value in batch' + vatQueVatValue );
    }
    public List<SObject> start(Database.BatchableContext bc){
        return noticeList;
    }
    public void execute(Database.BatchableContext bc, List<Notice__c> scope){
         List< notice>  NoticeToUpdateFromAccount = new List<Notice__c>();   
         system.debug('scope value ' + scope);
         system.debug('vatQueVatValue value batch' + vatQueVatValue);
         if(!scope.isEmpty()){
             For ( Notice__c noticess : scope){  
               noticess.Any_other_Lessor_Info_VAT_Number__c  = vatQueVatValue;
             }
         Database.update(scope, false);
         ---- add label message here to notify user that batch is running?
         }   
       
    }

Just don't want the user guessing what is going on.

Thanks you.
P
Hello,
Having an issue saving my class.  getting 
Compile Error: Invalid loop variable type expected SObject was Notice__c

I am passing the parameters from another Class and I am trying to update a field on the Notice__c object with teh vatQueVatValue value
If you see any other issues with the batch class please also advise.
public class UpdateNoticeFromAccountQueueableBatch implements Database.Batchable <sObject>, Database.Stateful{
    public List<Notice__c> noticeList = new List<Notice__c>();
    public String vatQueVatValue;
    public UpdateNoticeFromAccountQueueableBatch ( List<Notice__c> records ,String vatValueFromQue ) {
        noticeList = records;
        vatQueVatValue = vatValueFromQue;
        system.debug('noticeList value in batch' + noticeList );
        system.debug('vatQueVatValue value in batch' + vatQueVatValue );
    }
    public List<SObject> start(Database.BatchableContext bc){
        return noticeList;
    }
    public void execute(Database.BatchableContext bc, List<SObject> scope){
         List< notice>  NoticeToUpdateFromAccount = new List<Notice__c>();   
         system.debug('scope value ' + scope);
         system.debug('vatQueVatValue value batch' + vatQueVatValue);
         if(!scope.isEmpty()){
             For ( Notice__c noticess : scope){  ---- Compile Error: Invalid loop variable type expected SObject was notice Notice__c 
               noticess.Any_other_Lessor_Info_VAT_Number__c  = vatQueVatValue;
              system.debug('notices.Any_other_Lessor_Info_VAT_Number__c ' + notices.Any_other_Lessor_Info_VAT_Number__c);
             }
         }   
         Database.update(scope, false);
    }
    public void finish(Database.BatchableContext bc){
    }
}

Cheers,
P
 
Trying to call a Class method from a test class:
Class UtilHelper
global class FeeWrapper { global List<Project__c> transToUpdate; } 

public static FeeWrapper PassingRentFee(Fee_Calculation__c Config, Project__c trans, List<Project__c> transToUpdate, Map<String, Fee_Mapping__c> m_Fee)



Test class
Map<String,Fee_Mapping__c > afMap = new Map<String,Fee_Mapping__c >( [ SELECT Id, Fee_Amount__c , _Fee_Basis__c , WO__c,Group__c,Type__c,Macro_Type__c FROM Fee_Mapping__c]); 

List<Fee_Calculation__c > feeRec = [ SELECT Id, Name FROM Fee_Calculation__c]; 

List<Project__c> projectRec = [ SELECT Id, Name FROM Project__c]

UtilHelper.PassingRentFee(feeRec[0],projectRec[0],projectRec[0],afMap);

Error is Method does not exist or incorrect signature
Any suggesitons are appreciated
P
I am trying to get a vlaue from a map to use in an If statement
I need to get the status value from the m_cl map.  How do I do that?
Thank you,
P
 
Map<Id,Checklist__c> m_cl = new Map<Id, Checklist__c>();
Set<Id> checkListIds = new Set<Id>();
        Set<Id> prjIds = new Set<Id>();
        Set<Id> prjNcIds = new Set<Id>();
        Set<Id> checkListNcIds = new Set<Id>();

        if(Trigger.isUpdate) {            
            for (SObject so : Trigger.New) {
              Checklist__c newCL = (Checklist__c) so;
              Checklist__c oldCL = Trigger.oldMap != null && Trigger.oldMap.containsKey(newCL.Id)
                ? (Checklist__c) Trigger.oldMap.get(newCL.Id)
                : null;

                    if(newCL.Status__c != oldCL.Status__c && (newCL.Status__c == 'Complete' || oldCL.Status__c == 'In Progress')){
                        m_cl.put(newCL.Activity__c, newCL);
                        checkListIds.add(newCL.Id);
                        prjIds.add(newCL.Project__c);
                    }

            }

            if(checkListIds.size()> 0){
                act = [Select id,Name,Project__c, Project__r.RC_Completed__c, Project__r.M5_Completed__c,Checklist__r.Status__c,Checklist__r.Name,Checklist__c,Form_Complete__c
                      FROM Activity__c 
                      WHERE Form_Complete__c = false 
                      AND Checklist__c IN : checkListIds
                      ];

                prj = [Select id, Name, RC_Completed__c ,M5_Completed__c 
                       FROM Project__c 
                       WHERE Id IN : prjIds];
              
                if( act.size() > 0){
                    for(Activity__c acts : act){
                        formName = acts.Checklist__r.Name.split(':');    
                        if(formName[1] == 'Pre-M5 Check List Form' && m_cl.get('Status__c') == 'Complete'){
                            acts.M5_Completed__c = true;
                            actToUpdate.add(acts);
                        }
                        else {
                            acts.RC_Completed__c = true;
                            actToUpdate.add(acts);
                        }
                    }
                }

 
Hello All,
I have a Queueable class that I want to execute in a Batch class but I am not sure how to pass the list of Leases to the Batch and execute. 
Any suggestions will be greatly appreciated.
public  class UpdateLeaseQueueable implements Queueable {
    
    List<Lease__c> updateLeases = new List<Lease__c>();

    public UpdateLeaseQueueable( Map<Id, Lease__c> leases) {
        updateLeases.addAll(leases.Values());
    }

    public void execute(QueueableContext qc) {  

        if (!updateLeases.isEmpty()) { 
           //pass leases to Batch class
        }
    }
}


Batch
global class UpdateLeaseQueueableBatch implements Database.Batchable <sObject>, Database.Stateful{
   
    global Database.QueryLocator start(Database.BatchableContext bc){
        
    }
    
    global void execute(Database.BatchableContext bc, List<> listLease){
       
    }
    
    global void finish(Database.BatchableContext bc){
    }
}


Cheers,
P
Hello,
I could use some help on how to create a validation rule that forces users to fomat their text input
For example.  I need the user input to be like 
A.123456.D.54 OR A.789456.E.89
First letter needs to be an A followed by a . followed by 6 digits(numbers only) followed by a . followed by a D or E  then followed by a . and then followed by 2 digits(numbers only)
Can I do this in a validation rule? 
Thank you,
P
 
Hello All,
Currently I am attaching a PDF that is dynamically generated and atatching it to an email.  All done via controller.
The email itself has become more complicated and the users want to be able to update the email as needed so I need to utilize a SF email template instead of my email controller.  Is this possible?  Use SF email tempalte and dynamically attach a file?  This file is not attched to the record.  I am currently rendering it as a pdf and attaching it before I send.  
Thank you,
P
I need some help with solving an issue where I wan tto improve the user experince.  Currently I have a quaick action that has no fields on teh page except for Name whcih is requirted.  I defaulted the vlaue to 'Leave Blank".  I do this because I have a custom controller that assigned the name and updated other fields.  How can I remove the need for the user to have to do anything.  Ideally they would click the new button and it would generate the record. ANy suggestions 
Will someone help me with writing a test class for my email class?
 
public with sharing class PDF_EmailController {
    
    @auraEnabled

    public static void SendAttachment(String recordId){
           
        for(Purchase_Order_Request__c por : [SELECT Id, Email_Address__c FROM Purchase_Order__c
        WHERE Id =: recordId]){
            Messaging.SingleEmailMessage semail = new Messaging.SingleEmailMessage();
            Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();

            PageReference pref = page.POPDF;
            pref.getParameters().put('Id',por.Id);
            pref.setRedirect(true);
            Blob b = pref.getContent();
            attach.setFileName('POR.pdf');
            attach.setBody(b);
            semail.setSubject('Purchase Order Request Details');
            semail.setToAddresses(new String[] { por.Email_Address__c });
            semail.setPlainTextBody('Please find the attached POR details');
            semail.setFileAttachments(new Messaging.EmailFileAttachment[]{attach});
            Messaging.sendEmail(new Messaging.SingleEmailMessage[]{semail});

        }

        for(Purchase_Order_Request__c por : [SELECT Id, Email_Address__c,Version__c FROM Purchase_Order__c
                                             WHERE Id =: recordId]){
            PageReference PDf =  Page.PORequestPDF;
            PDf.getParameters().put('Id',por.Id);
            PDf.setRedirect(true);
            Attachment attach = new Attachment();
            Blob b ;
            b = PDf.getContent();
            attach.Body = b;
            attach.Name = 'Purchase Order Confirmation ' + System.today();
            attach.IsPrivate = false;
            attach.ParentId = por.Id;
            insert attach;

        }
    }
 }



Visualforce Page

<apex:page controller="PDF_EmailController" standardStylesheets="false" showHeader="false">    
    <center>
        <P style="font-size:22px;"><u>Send Purchase Order Request</u></P>
        <input type="text" value="" id="txtEmailAddress"/><br/><br/>
        <input type="button" onclick="SendEmailAttachment();" value="Send"/>
    </center>
    <script>
    function SendEmailAttachment(){
        var PORId = '{!$CurrentPage.parameters.Id}';
        var emailAddress=document.getElementById('txtEmailAddress').value;
        if(emailAddress!=null && emailAddress!=''){
            TestHandler.SendAttachment(emailAddress,porId,function(result,event){
                if(event.status){
                    if(result=='SUCCESS'){
                        alert('Email sent successfully.');
                    }
                    else{
                        alert(result);
                    }
                }
            })
        }
        else{
            alert('Please provide email address!');
        }
    }
    </script>
 </apex:page>

Thank you,
P
Hello All,
I have a VF page that renders record information as shows it as a PDF .  I am using renderAs="PDF"
How can I now email that PDF?
I thought I needed an email controller show below
RequestPDF is the name of the VF PDF page that is rendering the data.  How do I pass the id to the controller?  I would like to try with either a button or maybe when a user updates and saves the record.  Either way the id and email address is sent to the controller.  And if the email address is null prompt for 1? 
public with sharing class RequestPDF_EmailController {
    
    @RemoteAction
    public static string SendAttachment(String sEmailAddress, String tempId){
        String sMessage='';
        try{            
            Messaging.SingleEmailMessage semail = new Messaging.SingleEmailMessage();
            Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();

            PageReference pref = page.RequestPDF;
            pref.getParameters().put('id',tempId);
            pref.setRedirect(true);
            Blob b = pref.getContent();
            attach.setFileName('AttachedInV.pdf');
            attach.setBody(b);
            semail.setSubject('Inv Details');
            semail.setToAddresses(new List<String>{sEmailAddress});
            semail.setPlainTextBody('Please find the attached INV details');
            semail.setFileAttachments(new Messaging.EmailFileAttachment[]{attach});
            Messaging.sendEmail(new Messaging.SingleEmailMessage[]{semail});
            sMessage='SUCCESS';
        }
        catch(Exception ex){
            sMessage=ex.getMessage()+'\n'+ex.getLineNumber()+'\n'+ex.getCause();
        }
        return sMessage;
    }
 }

Thank you,
P
I am wondering how do I cover code that is related to cusotm metadata.
class:
public with sharing class ApplicationServices {

    public static final String APPLICATION_STATUS_DRAFT = 'Draft';
    public string coloTemplateName;

    public static List<ApplicationProjectTemplateConfig__mdt> templateConfigs = [SELECT Id,ApplicationCriteria__c,ProjectTemplateName__c from ApplicationProjectTemplateConfig__mdt];
     
    public static Map<String, SObject> templatesByNameMap {
        get{
            if(templatesByNameMap == null){
                list<Project_Template__c> templates = [Select Id, Name FROM Project_Template__c WHERE 
Active__c =: true];
                templatesByNameMap = PGE_EDSUtils.createMapByStringFieldSingleObject(templates, 'Name');
            }

            return templatesByNameMap;
        }
        private set;
    }

    public static void handleSubmit(Map<Id, Application__c> applications) {
        // Only before update
        if( !Trigger.isBefore || !Trigger.isUpdate ) {
            return;
        }
      
        // Determine the projects to create, if any
        Map<Application__c, Project__c> projectsToCreate = new Map<Application__c, Project__c>();
        for(Application__c application : applications.values()) {
            boolean docreate = shouldCreateColoProject(application);
            if( docreate ) {
                Project__c project = createColoProject(application);
                   if(project != null){
                        projectsToCreate.put(application, project);
                    }
            }
        }


///no code coverage
        if(projectsToCreate.size() > 0) {
            insert projectsToCreate.values();
            for(Application__c application : projectsToCreate.keySet()) {
                Project__c project = projectsToCreate.get(application);
                application.Project__c = project.Id;
                application.Date_Submitted__c = application.Date_Submitted__c == null
                                                ? System.today()
                                                : application.Date_Submitted__c ;
            }
        }
    }

///no code coverage
     public static String coloTemplateName {
        get {
            if(coloTemplateName == null) {
                coloTemplateName = AppConfig.getAppConfigValue('COL_PROJECT_TEMPLATE');
            }
            return coloTemplateName;
        }
        private set;
    }

///no code coverage
    public static Id coloTemplateId {
        get {
            if(coloTemplateId == null) {
                if(String.isNotEmpty(coloTemplateName)) {
                    Project_Template__c template = [SELECT Id 
                                                                 FROM Project_Template__c
                                                                 WHERE Name =: coloTemplateName LIMIT 1];
                    coloTemplateId = template.Id;
                }
            }
            return coloTemplateId;
        }
        private set;
    }


    public static Boolean shouldCreateColoProject(Application__c application) {
        return !isDraft(application) && !hasProject(application);
    }

    private static Boolean isDraft(Application__c application) {
        return application.Application_Status__c == APPLICATION_STATUS_DRAFT;
    }

    private static Boolean hasProject(Application__c application) {
        return application.Project__c != null;
    }

  
    public static Project__c createColoProject(Application__c application) {
        Project__c project = null;
        string projectTemplate;
   
        for( ApplicationProjectTemplateConfig__mdt  config :templateConfigs){
            boolean templatematch = BooleanLogicEvaluation.evaluate(application , config.ApplicationCriteria__c);
     
            if(templatematch){
                projectTemplate = config.ProjectTemplateName__c;
                break;
            }
         } 
      
         if (projectTemplate!=null && templatesByNameMap.containsKey(projectTemplate)){
           // no code coverage
            project = new Project__c(
                AccountSite__c =  application.AccountSite__c 
                OwnerId = application.ownerId,
                application__c = application.Id,
                ProjectTemplate__c = templatesByNameMap.get(projectTemplate).id,
                Project_Start_Date_A__c = System.today()
            );
         }

        return project;
    }

}
Test Class
static testMethod void testApplicationBasicCRUD() {
    	AccountSite__c  as = [SELECT Id FROM AccountSite__c LIMIT 1];
        Test.startTest();

        Application__c application = new Application__c(
            Application_Type__c = 'NewAgreement',
            Scope_of_Work__c = 'Test Setup',
            AccountSite__c = as.Id
        );
        insert application;
        System.assert(application.Id != null, 'Successfully created application');

        // Update
        application.Tenant_AccountSite_Name__c = ' Mountain';
        application.Tenant_AccountSite_Number__c = '123';
        update application;
        System.assert(application.Id != null, 'Successfully updates application');

        // Delete
        delete application;
        System.assert(true, 'Successfully deleted application');

        Test.stopTest();
    }

    static testMethod void testAutomaticProjectCreation() {
    	AccountSite__c  as= [SELECT Id FROM AccountSite__c  LIMIT 1];

        Test.startTest();
        Application__c application = new Application__c(
            Application_Type__c = 'NewAgreement',
            Scope_of_Work__c = 'Test Setup',
            Date_Submitted__c = System.today(),
            AccountSite__c = as.Id
        );
        insert application;

        application.Application_Status__c = 'Feasibility';
        application.Approval_Status__c = 'Pending';
        update application;
        
        application = [SELECT id, Project__c,  Date_Submitted__c FROM Application__c where id=: application.Id];
        System.assertEquals(System.today(), application.Date_Submitted__c, 'Date Submitted Set');
     
        Test.stopTest();
    }


    @testSetup
    private static void createTestData() {

       
        AccountSite__c as = new AccountSite__c (
            Name = 'Casterly Rock'
        );
        insert as;

      
        Project_Template__c template = new Project_Template__c (
            Name = 'Collocation',
            Active__c = true,
            Object__c  = 'Project__c',
            Project_Extension_Objects__c = 'Coll_Project__c'
        );
        insert template;

        Collocation__c collocation = new Collocation__c (
            Name = '100ft',
            AccountSite__c = as.Id
        );
        insert collocation;

        Application__c application = new Application__c (
            Application_Type__c = 'NewAgreement',
            Scope_of_Work__c = 'Test Setup',
            AccountSite__c = as.Id
        );
        insert application;

    }


}


 
So in this example for inserting Content docuemnt link.  How can I limit access to a specifc user group or profile?  And how could I use a CMT so that an admin can update or add groups so that the sahring is not hard coded in the apex?
Thanks
//Get attachment
Attachment attach = [SELECT Id, Name, Body, ContentType, ParentId From Attachment LIMIT 1];
 
//Insert ContentVersion
ContentVersion cVersion = new ContentVersion();
cVersion.ContentLocation = 'S';
cVersion.PathOnClient = attach.Name;
cVersion.Origin = 'H';
cVersion.OwnerId = attach.OwnerId;
cVersion.Title = attach.Name;
cVersion.VersionData = attach.Body;
Insert cVersion;
 
//After saved the Content Verison, get the ContentDocumentId
Id conDocument = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:cVersion.Id].ContentDocumentId;
 
//Insert ContentDocumentLink
ContentDocumentLink cDocLink = new ContentDocumentLink();
cDocLink.ContentDocumentId = conDocument;//Add ContentDocumentId
cDocLink.LinkedEntityId = attach.ParentId;//Add attachment parentId
cDocLink.ShareType = 'I';
cDocLink.Visibility = 'InternalUsers';
Insert cDocLink;