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

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 101
    Questions
  • 136
    Replies
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;

    }


}


 
I am copying contentdocumentlink to another object
cdl.ShareType = 'I';
cdl.Visibility = 'InternalUsers';

But the visibilty when I look at the fileis 'All Users', why is that?  I need it to be private.
P

 
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;
Can anyone assist me with getting coverage for this test class
global class AttachmentTriggerHandler r{
    
    Map<Id, List<ContentDocumentLink>> linkMap = new Map<Id, List<ContentDocumentLink>>();
    Map<String, Directory__c> directoryMap = new Map<String, Directory__c>();
    List<ContentDocumentLink> cdl_List = new List<ContentDocumentLink>();
    public ContentDocumentLink cdl = New ContentDocumentLink();
    List<Attachment__c> categoryvals = new List<Attachment__c>();
    public String parentId;
    public String catvalue;
    public String folderparentId;
    public string parentObjectType;
    public Map<Id,Programme__c> ProgrammeMap = new Map<Id,Programme__c>();
    public Map<Id,Permit__c>  PermitMap  = new Map<Id,Permit__c>();

    global override void bulkBeforeExtended() {
        if( Trigger.isUpdate ){
            List<Id> docIds = new List<Id>();
            List<String> parentIds = new List<String>();
            List<Id> progRecordIds = new List<Id>();
            List<Id> perRecordIds = new List<Id>();
                   
            for( Attachment__c attrecord : ( List<Attachment__c> ) Trigger.new ){
                Id recId = Id.valueOf(attrecord.Parent_ID__c ); 
                parentObjectType = String.valueOf( recId.getSObjectType());

                if(parentObjectType == 'Programme__c' ){
                    progRecordIds.add(attrecord.Parent_ID__c);
                }
                if(parentObjectType == 'Permit__c' ){
                    perRecordIds.add(attrecord.Parent_ID__c);
                }
            }
            if (!progRecordIds.isEmpty()) {
                programmeMap.putall([Select Project__c from Programme__c WHERE Id =: ProgRecordIds]);  
            }
            if (!perRecordIds.isEmpty()) {
                permitMap.putall([Select Project__c from Permit__c WHERE Id =: perRecordIds]); 
            }
            if (!jobRecordIds.isEmpty()) {
                jobMap.putall([Select Project__c from Job__c WHERE Id =: JobRecordIds]);
            }
          
            for( Attachment__c record : ( List<Attachment__c> ) Trigger.new ){
                Id docId = record.ContentDocumentId__c;
                    parentId = record.Parent_ID__c ;
                    Id recId = Id.valueOf(record.Parent_ID__c ); 
                    parentObjectType = String.valueOf( recId.getSObjectType() );
       
                    if( ProgrammeMap.containsKey(record.Parent_ID__c)){ 
                        for(Programme__c prog :ProgrammeMap.values()){
                            parentId = prog.Project__c;
                        }
                    }
                    if( PermitMap.containsKey(record.Parent_ID__c)){ 
                        parentId = record.Proj__c;
                        record.sobject__c ='Project';
                    }
                    }
                 
                    if( docId != null ){    
                        docIds.add( docId );
                    }
                  
                    if( parentId != null ){    
                        parentIds.add( parentId );
                    } 
                  
                    if( record.sobject__c != null ){    
                        categoryvals.add( record );
                    }       
            }

            list<Directory__c> dirs = [
                SELECT id,Directory_Template__c,Name,ParentId__c,Sobject__c,
                    (Select Id,Name, Directory__c, Folder_Template__c,Parent_File_Folder__c FROM File_Folders__r ORDER BY Name)
                FROM Directory__c 
                WHERE ParentId__c IN: parentIds
            ];
           
            if( !dirs.isEmpty() ){
                for( Directory__c dir : dirs ){
                    this.directoryMap.put( dir.ParentId__c, dir );
                }
            }

            List<ContentDocumentLink> linkList = [ SELECT Id, ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE ContentDocumentId IN: docIds ];
            if( !linkList.isEmpty() ){
                for( ContentDocumentLink link : linkList ){
                    List<ContentDocumentLink> links = this.linkMap.containsKey( link.ContentDocumentId )
                        ? this.linkMap.get( link.ContentDocumentId ) : new List<ContentDocumentLink>();
                    links.add( link );
                    this.linkMap.put( link.ContentDocumentId, links );
                }
            }
        }
    }
    global override void bulkAfterExtended() {
    }

    global override void beforeInsertExtended(SObject so) {
        Attachment__c newAttachment = ( Attachment__c ) so;
        this.getObjectType(newAttachment);
    }
    global override void beforeUpdateExtended(SObject oldso, SObject newso) {
      	Attachment__c newAttachment = ( Attachment__c ) newSo;
        folderparentId = newAttachment.Parent_Id__c;
        Id recId = Id.valueOf(newAttachment.Parent_ID__c );
        parentObjectType = String.valueOf( recId.getSObjectType() );
        this.getParentObjectType(parentObjectType,newAttachment);      

        if( directoryMap.containsKey( folderparentId)){           
            Directory__c dir = this.directoryMap.get( folderparentId );
            List<File_Folder__c> folders = dir.File_Folders__r;
            system.debug('dir.File_Folders__r '+ dir.File_Folders__r);
            List<ContentDocumentLink> links = this.linkMap.get( newAttachment.ContentDocumentId__c );

            for (ContentDocumentLink cont : links ){
                for (File_Folder__c folder: folders ){
                    if(newattachment.Document_Type__c == folder.name ){
                        ContentDocumentLink cdl = new ContentDocumentLink();
                        cdl.LinkedEntityId = folder.Id;
                        cdl.ContentDocumentId = cont.ContentDocumentId;
                        cdl.ShareType = 'V';
                        cdl.Visibility = 'AllUsers';
                        newAttachment.File_Folder__c = folder.Id;
                        cdl_List.add(cdl);
                        break;
                    }
                }
            }
        }
    }
    global override void afterUpdateExtended(SObject oldso, SObject newso) {}
    global override void afterInsertExtended(SObject newso) {} 
    global override void andFinallyExtended() {
    
      if (!Trigger.isDelete) {
            if (Trigger.isUpdate) {
                try {
                    if (cdl_List.size() > 0) {
                        insert cdl_List;
                    }
                } catch (Exception e) {
                    System.debug('Error: ' + e.getMessage());
                }
            }
        }

        if (!Trigger.isDelete) {
            if (Trigger.isInsert) {
                try {
                    if (categoryvals.size() > 0) {
                        update categoryvals;
                    }
                } catch (Exception e) {
                    System.debug('Error: ' + e.getMessage());
                }
            }
        }

    }

    private void getParentObjectType(String tempParentObjectType,Attachment__c newAttachment){
   
        if( tempParentObjectType == 'Programme__c'  ){
            folderparentId = parentId;
            newAttachment.sobject__c='Programme';
        }
        else{
            folderparentId = parentId;
            newAttachment.sobject__c='Project';
        }
    }

    private void getObjectType(Attachment__c newAttachment){
        if( this.linkMap.containsKey( newAttachment.ContentDocumentId__c ) ){
            List<ContentDocumentLink> links = this.linkMap.get( newAttachment.ContentDocumentId__c );
            if( !links.isEmpty() ){
                for( ContentDocumentLink link : links ){
                    String objectType = String.valueOf( link.LinkedEntityId.getSObjectType() );
                    Directory__c dir = this.directoryMap.containsKey( link.LinkedEntityId )
                        ? this.directoryMap.get( link.LinkedEntityId ) : null;
                    if( dir != null ){
                        switch on ( objectType ){
                            when 'Programme__c' {
                                newAttachment.Programme__c = link.LinkedEntityId;
                            }
         
                            when 'Permit__c' {
                               newAttachment.Permit__c = link.LinkedEntityId;
                            }
                            
                        }
                    }
                }
            }
        }
    }
}

Test Class
@IsTest
private class AttachmentTriggerHandlerTest {
    @TestSetup
    static void setupTestData() {
        Directory_Template__c dirTemplate = new Directory_Template__c(
            Name = 'Directory Template Test',
            Sobject__c = 'Project',
            Active__c = true
        );
        insert dirTemplate;
    }

    @isTest
    private static void TestTriggerFunctions(){

        List<Directory_Template__c> dirTemplates = [
            SELECT Id
            FROM Directory_Template__c
        ];
        
        System.assertEquals( 1, dirTemplates.size(), '1 template found' );

        Programme__c prog = new Programme__c(
                Name = 'Test Program',
                Operator__c = 'MBNL',
                Directory_Template__c = dirTemplates[ 0 ].Id
        );
        insert prog;

        Attachment attach = new Attachment();       
        attach.Name='Test Attachment';
        Blob bodyBlob=Blob.valueOf('Test Attachment Body');
        attach.body=bodyBlob;
        attach.parentId=prog.id;
        insert attach;
        
        List<Attachment> attachments=[select id, name from Attachment where parent.id=:prog.id];
        System.assertEquals(1, attachments.size());

        Blob contentData = Blob.valueOf( 'Test File' );
        String documentName = 'testfile.txt';

        ContentVersion newDocument = new ContentVersion(
            Title = documentName,
            VersionData = contentData,
            PathOnClient = documentName
        );

        insert newDocument;

        List<ContentVersion> versionVerify = [
            SELECT Id, ContentDocumentId
            FROM ContentVersion
            WHERE Id =: newDocument.Id
        ];
        System.assertEquals( 1, versionVerify.size() );

        List<ContentDocument> documents = [
            SELECT Id
            FROM ContentDocument
            WHERE Id =: versionVerify[ 0 ].ContentDocumentId
        ];

        System.assertEquals( 1, documents.size() );

        ContentDocumentLink newLink = new ContentDocumentLink(
            LinkedEntityId = projects[ 0 ].Id,
            ContentDocumentId = documents[ 0 ].Id,
            ShareType = 'V',
            Visibility = 'AllUsers'
        );
        insert newLink;
    }
}

 
        
 
I think I am iterating ov erht same list twice.  Will someone help me streamline the code.  Can I get the second for loop inside the first and be efficient?
Attachment__c newAttachment = (Attachment__c ) so;
        String objectType;
        List<Plan__c > palnId = new List<Plan__c>();
        Map<String,String> planMap = new Map<String,String>();
        
        if( this.linkMap.containsKey( newAttachment.ContentDocumentId__c ) ){
            List<ContentDocumentLink> links = this.linkMap.get( newAttachment.ContentDocumentId__c );
            if( !links.isEmpty() ){
                for( ContentDocumentLink link : links ){
                    objectType = String.valueOf( link.LinkedEntityId.getSObjectType() );
                    switch on ( objectType ){
                        when 'Activity__c' {
                            newAttachment.Activity__c= link.LinkedEntityId;
                        }
                        when 'Project__c' {
                            newAttachment.Proj__c= link.LinkedEntityId;
                        }
                    }
                }
            }
    
            List<Plan__c> plans= new List<Plan__c>();

            for (ContentDocumentLink cont : links ){                    
                if(newAttachment.Activity__c != null || newAttachment.Proj__c != null){
                    ContentDocumentLink cdl = new ContentDocumentLink();
                    cdl.LinkedEntityId = parentId;
                    cdl.ContentDocumentId = cont.ContentDocumentId;
                    cdl.ShareType = 'V';
                    cdl.Visibility = 'AllUsers';
                    cdl_List.add(cdl);
                    break;
                }
            }
        }

 
I have an class where I have a Class level Variable
private static final Map<Id,Customer__c> CUSTOMERTEMP;

In my method
global override void bulkAfterExtended(){  
if (!CustVal.isEmpty()) {
                CUSTOMERTEMP = new Map<Id,Customer_c>([SELECT Id, Name,Status__c FROM Customer__c);
                }

When I go to deploy I get a 
"Final Memebers can only be assigned in thier declaration, init blocks,or constructor: CUSTOMERTEMP"

I have other private static final with no issue but they are not maps.  What am doing wrong?
Thanks,
P
I am getting an errro with my code:
Illegal assignment from List<sector__c> to id
What I am trying to do:
When a Candidate is made Primary, the Sector Record's Site Lookup field should get populated with the Site record that is linked with the Candidate record.
 
Map<Id, Sector__c> m_Sectors;
Map<Id, List<Sector__c>> m_sitesToSectors = new Map<Id, List<Sector__c>>();
List<Sector__c> sectorsToUpdate = new List<Sector__c>();

 public void bulkAfter(){{
 if (Trigger.IsUpdate && Trigger.isAfter) {
            for (SObject so : Trigger.New) {
                Candidate__c newCandidate = (Candidate__c) so;
               Candidate__c oldCandidate = (Candidate__c) Trigger.oldMap.get(newCandidate.Id);

if ((newCandidate.Primary_Candidate__c != oldCandidate.Primary_Candidate__c) && 
                     newCandidate.Primary_Candidate__c == true && newCandidate.Site__c != null) {                    candidateIdsPrimary.add(newCandidate.Id);                }

 if (!candidateIds.isEmpty()) {
                m_Sectors = new Map<Id, Sector__c>([SELECT Id,Candidate__c,Site__c FROM Sector__c WHERE Site__c = null AND Candidate__c IN: candidateIdsPrimary]);
            }

if (m_Sectors != null && !m_Sectors.isEmpty()){
                for (Sector__c sect : m_Sectors.values()) {
                    if (!m_sitesToSectors.containsKey(sect.Candidate__c)) {
                        m_sitesToSectors.put(sect.Candidate__c, new List<Sector__c>{sect});
                    }
                    else {
                        m_sitesToSectors.get(sect.Candidate__c).add(sect);
                    }
                }
            }

}

public void afterUpdate( SObject oldSo, SObject newSo ){

Candidate__c newCandidate = (Candidate__c) newSo;
Candidate__c oldCandidate = (Candidate__c) oldSo;

if (m_sitesToSectors.get(newCandidate.Id) != null && !m_sitesToSectors.get(newCandidate.Id).isEmpty()) {
            for (Sector__c sector: m_sitesToSectors.get(newCandidate.Id)) {
                sector.Site__c = m_sitesToSectors.get(newCandidate.Site__c); ---error here
                sectorsToUpdate.add(sector);
            }
        }

}

 
I am trying to create a utility class but it keeps throughing an error.
Here is the original code
List<Directory_Template__c> directorytemplate =
            ([select id,Name from Directory_Template__c where Sobject__c = 'Project' AND Active__c = true limit 1]);
                for (Permit__c proj : (List<Permit__c >) trigger.New){
                    for (Directory_Template__c dir : directorytemplate)
                    {
                        if (dir.Id != null) { 
                            proj.Directory_Template__c = dir.Id; 
                        }
                    }
                }

Here is the utility class
global class ViewUtils {
    
    public static String getDirectory(String objectType){
     
        List<Directory_Template__c> directorytemplate = new List<Directory_Template__c>();
        system.debug('objectType '+ objectType);
            if(objectType  == 'Programme__c'){
                directorytemplate =
                ([select id,Name from Directory_Template__c where Sobject__c = 'Programme' AND Active__c = true limit 1]);
                    for (Programme__c prog : (List<Programme__c >) trigger.New){
                        for (Directory_Template__c dir : directorytemplate)
                        {
                            if (dir.Id != null) { 
                                return prog.Directory_Template__c = dir.Id; 
                            }
                        }
                    }
            } 
            else{
                directorytemplate =
                ([select id,Name from Directory_Template__c where Sobject__c = 'Project' AND Active__c = true limit 1]);
                    for (objectType proj : (List<objectType >) trigger.New){
                        for (Directory_Template__c dir : directorytemplate)
                        {
                            if (dir.Id != null) { 
                                return proj.Directory_Template__c = dir.Id; 
                            }
                        }
                    } 
            }   
        }
    }

So in the original class I am trying this
ViewUtils.getDirectory('Permit__c');

It states that the return statement is missing and that objecttype is invalid.  Is it becasue I am trying to use the Object and I am actaully passing in a string?

Thanks
​​​​​​​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;
I am getting an errro with my code:
Illegal assignment from List<sector__c> to id
What I am trying to do:
When a Candidate is made Primary, the Sector Record's Site Lookup field should get populated with the Site record that is linked with the Candidate record.
 
Map<Id, Sector__c> m_Sectors;
Map<Id, List<Sector__c>> m_sitesToSectors = new Map<Id, List<Sector__c>>();
List<Sector__c> sectorsToUpdate = new List<Sector__c>();

 public void bulkAfter(){{
 if (Trigger.IsUpdate && Trigger.isAfter) {
            for (SObject so : Trigger.New) {
                Candidate__c newCandidate = (Candidate__c) so;
               Candidate__c oldCandidate = (Candidate__c) Trigger.oldMap.get(newCandidate.Id);

if ((newCandidate.Primary_Candidate__c != oldCandidate.Primary_Candidate__c) && 
                     newCandidate.Primary_Candidate__c == true && newCandidate.Site__c != null) {                    candidateIdsPrimary.add(newCandidate.Id);                }

 if (!candidateIds.isEmpty()) {
                m_Sectors = new Map<Id, Sector__c>([SELECT Id,Candidate__c,Site__c FROM Sector__c WHERE Site__c = null AND Candidate__c IN: candidateIdsPrimary]);
            }

if (m_Sectors != null && !m_Sectors.isEmpty()){
                for (Sector__c sect : m_Sectors.values()) {
                    if (!m_sitesToSectors.containsKey(sect.Candidate__c)) {
                        m_sitesToSectors.put(sect.Candidate__c, new List<Sector__c>{sect});
                    }
                    else {
                        m_sitesToSectors.get(sect.Candidate__c).add(sect);
                    }
                }
            }

}

public void afterUpdate( SObject oldSo, SObject newSo ){

Candidate__c newCandidate = (Candidate__c) newSo;
Candidate__c oldCandidate = (Candidate__c) oldSo;

if (m_sitesToSectors.get(newCandidate.Id) != null && !m_sitesToSectors.get(newCandidate.Id).isEmpty()) {
            for (Sector__c sector: m_sitesToSectors.get(newCandidate.Id)) {
                sector.Site__c = m_sitesToSectors.get(newCandidate.Site__c); ---error here
                sectorsToUpdate.add(sector);
            }
        }

}