• Chris Lam
  • NEWBIE
  • 10 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 6
    Replies
I am trying to create a flow that can duplicate an email message including attachment onto a new case from an existing case that has been closed.
So far I have been able to create the flow as attached, which create a new case from existing case as well as copying the email message over, however it doesn't seems to copy the attachment over and the flow ran without issue.  Does any one know what I have done wrong? I would like to copy the whole email including attachment from the last email in the old case into the new case.  While the email has been copied over, the attachment didn't get created under the new email or case.

1) Part of the Flow
User-added image
2) Fast Lookup on Email attachment from the Email ID from the closed case.

3) Loop thru the list of attachments
User-added image
4) Assigning the SOObject variabe (var_CurrentAttachment) to the new SOObject variable NewAttachment, including the new email message ID as the parentID of the attachment.
User-added image
5) Adding each of the NewAttachment SOObject variable to the NewAttachmentCollection SOObject Collection variable (cater for multiple attachments)
User-added image
6) Fast Create an attachment using SOObject collection variable NewAttachmentCollection. 
Case and Email are both successfully created however attachment is not in the email created on the new case. Can you tell me what I have done wrong in this Visual Flow?
User-added image
Hi Everyone,

I am trying to create an Apex class which will add the incoming email message which contains projectID in the subject heading into an existing project(custom objec) and discard the email message if it doesn't match any of our project ID.

The test class works fine but is not able to trigger the true condition for the below IF statement even though  the System.debug(myMatcher.group()); contains a valid Name in the project__c database.

IF ([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()] == 1)

I have ran a similar Apex code as below below using developer console (Open Execute Anonymous Window) and the three system debugs are returning TRUE result of the IF statement:

USER_DEBUG [6]|DEBUG|UKGWY0000000002
USER_DEBUG [7]|DEBUG|1
USER_DEBUG [9]|DEBUG|Matched

Whereby running the test class returns below DEBUG results:
USER_DEBUG [19]|DEBUG|UKGWY0000000002
USER_DEBUG [58]|DEBUG|No Match Found

My custom email handler class is as below
global class CI_EmailToSalesForce implements Messaging.InboundEmailHandler {
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, 
                                                         Messaging.Inboundenvelope envelope) {
  
Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();

//Set the Regex Matching Pattern to look for Project number in the email subject heading
String EmailSubject = email.subject;
String regexMatch = '^(UKGWY\\d+\\b?)';
//Declare a new instance of the Project object
project__c p;

try {

    // Check to see if the email subject contains any project ID
    Pattern MyPattern = Pattern.compile(regexMatch);
    Matcher MyMatcher = MyPattern.matcher(EmailSubject);
    if(myMatcher.find()){
        System.debug(myMatcher.group());
    }    
    //Condition if there is exactly one project ID match from email subject
    if ([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()] == 1) {
    system.debug('Matched');
    p = [SELECT ID FROM project__c WHERE Name =:myMatcher.group()];
    Note note = new Note();
    note.Title = email.fromName + '(' +DateTime.now() + ')';
    note.Body = email.plainTextBody;
    note.ParentId = p.Id;
    insert note;

      // Save attachments, if any 
      if (email.binaryAttachments!=null && email.binaryAttachments.size() > 0) { 
        for (Messaging.Inboundemail.BinaryAttachment bAttachment :email.binaryAttachments) { 
        Attachment attachment = new Attachment(); 
        attachment.ContentType = bAttachment.mimeTypeSubType; 
        attachment.Name = bAttachment.fileName; 
        attachment.Body = bAttachment.body; 
        attachment.ParentId = p.Id; 
        insert attachment; 
        } 
      } 
 
      else if (email.textAttachments!=null && email.textAttachments.size() > 0) { 
        for (Messaging.Inboundemail.TextAttachment tAttachment :email.textAttachments) { 
        Attachment attachment = new Attachment(); 
        attachment.Name = tAttachment.fileName; 
        attachment.Body = Blob.valueOf(tAttachment.body); 
        attachment.ParentId = p.Id; 
        insert attachment; 
        } 
      }        

    }
    //Condition if there are more than one project ID match from email subject
    else if ([SELECT COUNT() FROM Project__c WHERE Name =:myMatcher.group()] > 1) {
    system.debug('More than 1 project ID found');
    } else {
      system.debug('No Match Found');
      }
    
    result.success = true;
    } catch (Exception e) {
      result.success = false;
      result.message = 'Oops, I failed.';
    }
   
    return result;
  }
}
My test class is as below:
 
@IsTest
public class CI_EmailToSalesForce_Test {
    static testMethod void testCI_EmailToSalesForce() {
        // Create a new email, envelope and attachment object
        Messaging.InboundEmail email  = new Messaging.InboundEmail();
        Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
        Messaging.InboundEmail.BinaryAttachment att = new Messaging.InboundEmail.BinaryAttachment();

        // Setup the data for the email
        email.subject = 'UKGWY0000000002 This is a test';
        email.plainTextBody = 'This should become a note';
        env.fromAddress ='test@test.com';
        String contactEmail = 'test@test.com';
        att.body = blob.valueOf('test attachment');
        att.fileName = 'testfile.txt';
        att.mimeTypeSubType = 'text/plain';
        
        email.binaryAttachments = new Messaging.InboundEmail.binaryAttachment[] {att};
        
        // Call the TSG_Email class and test this with the above data
        CI_EmailToSalesForce CI_EmailObjTst = new CI_EmailToSalesForce();

        Test.startTest();
        CI_EmailObjTst.handleInboundEmail(email, env);
        Test.stopTest();

    }
}


​Can anyone tell me what I have done wrong?

Kind regards,
Chris
Hi Everyone,

I am trying to create an Apex class which will add the incoming email message which contains projectID in the subject heading into an existing project(custom objec) and discard the email message if it doesn't match any of our project ID.

The test class works fine but is not able to trigger the true condition for the below IF statement even though  the System.debug(myMatcher.group()); contains a valid Name in the project__c database.

IF ([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()] == 1)

I have ran a similar Apex code as below below using developer console (Open Execute Anonymous Window) and the three system debugs are returning TRUE result of the IF statement:

USER_DEBUG [6]|DEBUG|UKGWY0000000002
USER_DEBUG [7]|DEBUG|1
USER_DEBUG [9]|DEBUG|Matched

Whereby running the test class returns below DEBUG results:
USER_DEBUG [19]|DEBUG|UKGWY0000000002
USER_DEBUG [58]|DEBUG|No Match Found
String EmailSubject = 'UKGWY0000000002 Testing 1234';
String regexMatch = '^(UKGWY\\d+\\b?)';
Pattern MyPattern = Pattern.compile(regexMatch);
Matcher MyMatcher = MyPattern.matcher(EmailSubject);
if(myMatcher.find())
system.debug(myMatcher.group());
system.debug([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()]);
IF ([SELECT COUNT() FROM project__c WHERE name =:myMatcher.group()] == 1)
system.debug('Matched');



My custom email handler class is as below
global class CI_EmailToSalesForce implements Messaging.InboundEmailHandler {
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, 
                                                         Messaging.Inboundenvelope envelope) {
  
Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();

//Set the Regex Matching Pattern to look for Project number in the email subject heading
String EmailSubject = email.subject;
String regexMatch = '^(UKGWY\\d+\\b?)';
//Declare a new instance of the Project object
project__c p;

try {

    // Check to see if the email subject contains any project ID
    Pattern MyPattern = Pattern.compile(regexMatch);
    Matcher MyMatcher = MyPattern.matcher(EmailSubject);
    if(myMatcher.find()){
        System.debug(myMatcher.group());
    }    
    //Condition if there is exactly one project ID match from email subject
    if ([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()] == 1) {
    system.debug('Matched');
    p = [SELECT ID FROM project__c WHERE Name =:myMatcher.group()];
    Note note = new Note();
    note.Title = email.fromName + '(' +DateTime.now() + ')';
    note.Body = email.plainTextBody;
    note.ParentId = p.Id;
    insert note;

      // Save attachments, if any 
      if (email.binaryAttachments!=null && email.binaryAttachments.size() > 0) { 
        for (Messaging.Inboundemail.BinaryAttachment bAttachment :email.binaryAttachments) { 
        Attachment attachment = new Attachment(); 
        attachment.ContentType = bAttachment.mimeTypeSubType; 
        attachment.Name = bAttachment.fileName; 
        attachment.Body = bAttachment.body; 
        attachment.ParentId = p.Id; 
        insert attachment; 
        } 
      } 
 
      else if (email.textAttachments!=null && email.textAttachments.size() > 0) { 
        for (Messaging.Inboundemail.TextAttachment tAttachment :email.textAttachments) { 
        Attachment attachment = new Attachment(); 
        attachment.Name = tAttachment.fileName; 
        attachment.Body = Blob.valueOf(tAttachment.body); 
        attachment.ParentId = p.Id; 
        insert attachment; 
        } 
      }        

    }
    //Condition if there are more than one project ID match from email subject
    else if ([SELECT COUNT() FROM Project__c WHERE Name =:myMatcher.group()] > 1) {
    system.debug('More than 1 project ID found');
    } else {
      system.debug('No Match Found');
      }
    
    result.success = true;
    } catch (Exception e) {
      result.success = false;
      result.message = 'Oops, I failed.';
    }
   
    return result;
  }
}

Test Class
 
@IsTest
public class CI_EmailToSalesForce_Test {
    static testMethod void testCI_EmailToSalesForce() {
        // Create a new email, envelope and attachment object
        Messaging.InboundEmail email  = new Messaging.InboundEmail();
        Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
        Messaging.InboundEmail.BinaryAttachment att = new Messaging.InboundEmail.BinaryAttachment();

        // Setup the data for the email
        email.subject = 'UKGWY0000000002 This is a test';
        email.plainTextBody = 'This should become a note';
        env.fromAddress ='something@something.com';
        String contactEmail = 'something@something.com';
        att.body = blob.valueOf('test attachment');
        att.fileName = 'testfile.txt';
        att.mimeTypeSubType = 'text/plain';
        
        email.binaryAttachments = new Messaging.InboundEmail.binaryAttachment[] {att};
        
        // Call the TSG_Email class and test this with the above data
        CI_EmailToSalesForce CI_EmailObjTst = new CI_EmailToSalesForce();

        Test.startTest();
        CI_EmailObjTst.handleInboundEmail(email, env);
        Test.stopTest();

    }
}

​Can anyone tell me what I have done wrong?

Kind regards,
Chris
Hi,

I have created a custom button in the case which opens up a visual force page to list all contacts in the account of the current case.  Is there a way to change these contact name into a link whereby on clicking, I can change the case contact?

My Visual Force Page:

<apex:page standardController="account" showHeader="false" sidebar="false">
<apex:pageBlock >
<apex:pageBlockTable value="{! account.contacts}" var="item">
    <apex:column value="{! item.name}"/>
    <apex:column value="{! item.email}"/>

</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>

Screen shot for my list contact button as below:

User-added image

Cheers,
Chris
Hi All,

I am having an issue when attempting to deploy a code from SF dev into production environment.  The test class has been successfully uploaded and deployed to production evnironment however I am having the below errors when deploying the trigger.  I have ran a test against the trigger and it worked in the dev box.

CalculateBusinessHoursAgesTest testBusinessHoursBucketer System.DmlException: Update failed. First exception on row 0 with id 5009000000WIPyQAAX; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CalculateBusinessHoursAges: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.CalculateBusinessHoursAges: line 40, column 1: []
Stack Trace: Class.CalculateBusinessHoursAgesTest.testBusinessHoursBucketer: line 25, column 1

Apex Trigger:

trigger CalculateBusinessHoursAges on Case (before insert, before update) {
    if (Trigger.isInsert) {
        for (Case updatedCase:System.Trigger.new) {
            updatedCase.Last_Status_Change__c = System.now();
        }
    } else {
        //Get the stop statuses
        Set<String> stopStatusSet = new Set<String>();
        for (Stop_Status__c stopStatus:[Select Name From Stop_Status__c]) {
            stopStatusSet.add(stopStatus.Name);
        }

        //Get the default business hours (we might need it)
        BusinessHours defaultHours = [select Id from BusinessHours where IsDefault=true];

        //Get the closed statuses (because at the point of this trigger Case.IsClosed won't be set yet)
        Set<String> closedStatusSet = new Set<String>();
        for (CaseStatus status:[Select MasterLabel From CaseStatus where IsClosed=true]) {
            closedStatusSet.add(status.MasterLabel);
        }

        //For any case where the status is changed, recalc the business hours in the buckets
        for (Case updatedCase:System.Trigger.new) {
            Case oldCase = System.Trigger.oldMap.get(updatedCase.Id);

            if (oldCase.Status!=updatedCase.Status && updatedCase.Last_Status_Change__c!=null) {
                //OK, the status has changed
                if (!oldCase.IsClosed) {
                    //We only update the buckets for open cases

                    //On the off-chance that the business hours on the case are null, use the default ones instead
                    Id hoursToUse = updatedCase.BusinessHoursId!=null?updatedCase.BusinessHoursId:defaultHours.Id;

                    //The diff method comes back in milliseconds, so we divide by 60000 to get minutes.
                    Double timeSinceLastStatus = BusinessHours.diff(hoursToUse, updatedCase.Last_Status_Change__c, System.now())/60000.0;
                    System.debug(timeSinceLastStatus);

                    //We decide which bucket to add it to based on whether it was in a stop status before
                    if (stopStatusSet.contains(oldCase.Status)) {
                        updatedCase.Time_With_Customer__c += timeSinceLastStatus;
                    } else {
                        //Calculate the different time with TNS in Minutes
                        if (oldCase.Status == 'In Progress') {
                            updatedCase.Time_In_Progress__c += timeSinceLastStatus;   
                        } else if (oldCase.Status == 'B2B Investigation') {
                            updatedCase.Time_With_B2B__c += timeSinceLastStatus;
                        } else if (oldCase.Status == 'CE Investigation') {
                            updatedCase.Time_With_CE__c += timeSinceLastStatus;
                        } else if (oldCase.Status == 'New') {
                            updatedCase.Time_in_New_State__c += timeSinceLastStatus;
                        } else if (oldCase.Status == 'Needs Reply') {
                            updatedCase.Time_Pending_Response__c += timeSinceLastStatus;
                        }
                       
                    }
                       

                    if (closedStatusSet.contains(updatedCase.Status)) {
                        updatedCase.Case_Age_In_Business_Minutes__c = updatedCase.Time_With_Customer__c + updatedCase.Time_With_Support__c + updatedCase.Time_With_CE__c + updatedCase.Time_With_B2B__c + updatedCase.Time_Pending_Response__c + updatedCase.Time_in_New_State__c;
                        updatedCase.Time_With_Support__c = updatedCase.Time_With_Support__c + updatedCase.Time_Pending_Response__c + updatedCase.Time_in_New_State__c;
                    }
                }

                updatedCase.Last_Status_Change__c = System.now();
            }
        }
    }
}

Apex test class:

@IsTest
public class CalculateBusinessHoursAgesTest {
    public static testMethod void testBusinessHoursBucketer() {
        Stop_Status__c ss = new Stop_Status__c(Name = 'On Hold');
        insert ss;

        Case c = new Case();
        c.Status = 'New';
        c.Category__c = 'Production Support';
        c.Sub_Category__c = 'Settlement';
        c.Last_Status_Change__c = System.Now();
        c.Subject = 'TEST';
        insert c;
       
        c.Status = 'In Progress';
        update c;

        c.Status = 'On Hold';
        update c;
       
        c.Status = 'On Hold';
        update c;
             
        c.Status = 'Pending Third Party';
        update c;
       
        c.Status = 'CE Investigation';
        update c;
       
        c.Status = 'B2B Investigation';
        update c;
       
        c.Status = 'Needs Reply';
        update c;
       
        c.Status = 'Needs More Info';
        update c;
    
        Case updatedCase = [select Status, Time_in_New_State__c, Time_With_Customer__c,Time_With_Support__c,Case_Age_In_Business_Minutes__c,Time_With_CE__c,Time_With_B2B__c,Time_Pending_Response__c from Case where Id=:c.Id];
       
        System.assert(updatedCase.Time_in_New_State__c!=0.000);
        System.assert(updatedCase.Time_Pending_Response__c!=0.000);
        System.assert(updatedCase.Time_With_B2B__c!=0.000);
        System.assert(updatedCase.Time_With_Customer__c!=0.000);
        System.assert(updatedCase.Time_With_CE__c!=0.000);
        System.assert(updatedCase.Time_With_Support__c!=0.010);
        System.assert(updatedCase.Case_Age_In_Business_Minutes__c==0);
   
        c.Status = 'Closed';
        update c;
       
        updatedCase = [select Status, Time_in_New_State__c, Time_With_Customer__c,Time_With_Support__c,Case_Age_In_Business_Minutes__c,Time_With_CE__c,Time_With_B2B__c,Time_Pending_Response__c from Case where Id=:c.Id];
       
        System.assert(updatedCase.Case_Age_In_Business_Minutes__c!=null);
        System.debug('TEST Completed'+ c.Status + c.Time_in_New_State__c + c.Time_With_Customer__c + c.Time_With_Support__c + c.Case_Age_In_Business_Hours__c + c.Time_With_CE__c + c.Time_With_B2B__c + c.Time_Pending_Response__c);       
    }
}
I am trying to create a flow that can duplicate an email message including attachment onto a new case from an existing case that has been closed.
So far I have been able to create the flow as attached, which create a new case from existing case as well as copying the email message over, however it doesn't seems to copy the attachment over and the flow ran without issue.  Does any one know what I have done wrong? I would like to copy the whole email including attachment from the last email in the old case into the new case.  While the email has been copied over, the attachment didn't get created under the new email or case.

1) Part of the Flow
User-added image
2) Fast Lookup on Email attachment from the Email ID from the closed case.

3) Loop thru the list of attachments
User-added image
4) Assigning the SOObject variabe (var_CurrentAttachment) to the new SOObject variable NewAttachment, including the new email message ID as the parentID of the attachment.
User-added image
5) Adding each of the NewAttachment SOObject variable to the NewAttachmentCollection SOObject Collection variable (cater for multiple attachments)
User-added image
6) Fast Create an attachment using SOObject collection variable NewAttachmentCollection. 
Case and Email are both successfully created however attachment is not in the email created on the new case. Can you tell me what I have done wrong in this Visual Flow?
User-added image
Hi Everyone,

I am trying to create an Apex class which will add the incoming email message which contains projectID in the subject heading into an existing project(custom objec) and discard the email message if it doesn't match any of our project ID.

The test class works fine but is not able to trigger the true condition for the below IF statement even though  the System.debug(myMatcher.group()); contains a valid Name in the project__c database.

IF ([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()] == 1)

I have ran a similar Apex code as below below using developer console (Open Execute Anonymous Window) and the three system debugs are returning TRUE result of the IF statement:

USER_DEBUG [6]|DEBUG|UKGWY0000000002
USER_DEBUG [7]|DEBUG|1
USER_DEBUG [9]|DEBUG|Matched

Whereby running the test class returns below DEBUG results:
USER_DEBUG [19]|DEBUG|UKGWY0000000002
USER_DEBUG [58]|DEBUG|No Match Found

My custom email handler class is as below
global class CI_EmailToSalesForce implements Messaging.InboundEmailHandler {
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, 
                                                         Messaging.Inboundenvelope envelope) {
  
Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();

//Set the Regex Matching Pattern to look for Project number in the email subject heading
String EmailSubject = email.subject;
String regexMatch = '^(UKGWY\\d+\\b?)';
//Declare a new instance of the Project object
project__c p;

try {

    // Check to see if the email subject contains any project ID
    Pattern MyPattern = Pattern.compile(regexMatch);
    Matcher MyMatcher = MyPattern.matcher(EmailSubject);
    if(myMatcher.find()){
        System.debug(myMatcher.group());
    }    
    //Condition if there is exactly one project ID match from email subject
    if ([SELECT COUNT() FROM project__c WHERE Name =:myMatcher.group()] == 1) {
    system.debug('Matched');
    p = [SELECT ID FROM project__c WHERE Name =:myMatcher.group()];
    Note note = new Note();
    note.Title = email.fromName + '(' +DateTime.now() + ')';
    note.Body = email.plainTextBody;
    note.ParentId = p.Id;
    insert note;

      // Save attachments, if any 
      if (email.binaryAttachments!=null && email.binaryAttachments.size() > 0) { 
        for (Messaging.Inboundemail.BinaryAttachment bAttachment :email.binaryAttachments) { 
        Attachment attachment = new Attachment(); 
        attachment.ContentType = bAttachment.mimeTypeSubType; 
        attachment.Name = bAttachment.fileName; 
        attachment.Body = bAttachment.body; 
        attachment.ParentId = p.Id; 
        insert attachment; 
        } 
      } 
 
      else if (email.textAttachments!=null && email.textAttachments.size() > 0) { 
        for (Messaging.Inboundemail.TextAttachment tAttachment :email.textAttachments) { 
        Attachment attachment = new Attachment(); 
        attachment.Name = tAttachment.fileName; 
        attachment.Body = Blob.valueOf(tAttachment.body); 
        attachment.ParentId = p.Id; 
        insert attachment; 
        } 
      }        

    }
    //Condition if there are more than one project ID match from email subject
    else if ([SELECT COUNT() FROM Project__c WHERE Name =:myMatcher.group()] > 1) {
    system.debug('More than 1 project ID found');
    } else {
      system.debug('No Match Found');
      }
    
    result.success = true;
    } catch (Exception e) {
      result.success = false;
      result.message = 'Oops, I failed.';
    }
   
    return result;
  }
}
My test class is as below:
 
@IsTest
public class CI_EmailToSalesForce_Test {
    static testMethod void testCI_EmailToSalesForce() {
        // Create a new email, envelope and attachment object
        Messaging.InboundEmail email  = new Messaging.InboundEmail();
        Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
        Messaging.InboundEmail.BinaryAttachment att = new Messaging.InboundEmail.BinaryAttachment();

        // Setup the data for the email
        email.subject = 'UKGWY0000000002 This is a test';
        email.plainTextBody = 'This should become a note';
        env.fromAddress ='test@test.com';
        String contactEmail = 'test@test.com';
        att.body = blob.valueOf('test attachment');
        att.fileName = 'testfile.txt';
        att.mimeTypeSubType = 'text/plain';
        
        email.binaryAttachments = new Messaging.InboundEmail.binaryAttachment[] {att};
        
        // Call the TSG_Email class and test this with the above data
        CI_EmailToSalesForce CI_EmailObjTst = new CI_EmailToSalesForce();

        Test.startTest();
        CI_EmailObjTst.handleInboundEmail(email, env);
        Test.stopTest();

    }
}


​Can anyone tell me what I have done wrong?

Kind regards,
Chris
Hi,

I have created a custom button in the case which opens up a visual force page to list all contacts in the account of the current case.  Is there a way to change these contact name into a link whereby on clicking, I can change the case contact?

My Visual Force Page:

<apex:page standardController="account" showHeader="false" sidebar="false">
<apex:pageBlock >
<apex:pageBlockTable value="{! account.contacts}" var="item">
    <apex:column value="{! item.name}"/>
    <apex:column value="{! item.email}"/>

</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>

Screen shot for my list contact button as below:

User-added image

Cheers,
Chris
Hi All,

I am having an issue when attempting to deploy a code from SF dev into production environment.  The test class has been successfully uploaded and deployed to production evnironment however I am having the below errors when deploying the trigger.  I have ran a test against the trigger and it worked in the dev box.

CalculateBusinessHoursAgesTest testBusinessHoursBucketer System.DmlException: Update failed. First exception on row 0 with id 5009000000WIPyQAAX; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CalculateBusinessHoursAges: execution of BeforeUpdate caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.CalculateBusinessHoursAges: line 40, column 1: []
Stack Trace: Class.CalculateBusinessHoursAgesTest.testBusinessHoursBucketer: line 25, column 1

Apex Trigger:

trigger CalculateBusinessHoursAges on Case (before insert, before update) {
    if (Trigger.isInsert) {
        for (Case updatedCase:System.Trigger.new) {
            updatedCase.Last_Status_Change__c = System.now();
        }
    } else {
        //Get the stop statuses
        Set<String> stopStatusSet = new Set<String>();
        for (Stop_Status__c stopStatus:[Select Name From Stop_Status__c]) {
            stopStatusSet.add(stopStatus.Name);
        }

        //Get the default business hours (we might need it)
        BusinessHours defaultHours = [select Id from BusinessHours where IsDefault=true];

        //Get the closed statuses (because at the point of this trigger Case.IsClosed won't be set yet)
        Set<String> closedStatusSet = new Set<String>();
        for (CaseStatus status:[Select MasterLabel From CaseStatus where IsClosed=true]) {
            closedStatusSet.add(status.MasterLabel);
        }

        //For any case where the status is changed, recalc the business hours in the buckets
        for (Case updatedCase:System.Trigger.new) {
            Case oldCase = System.Trigger.oldMap.get(updatedCase.Id);

            if (oldCase.Status!=updatedCase.Status && updatedCase.Last_Status_Change__c!=null) {
                //OK, the status has changed
                if (!oldCase.IsClosed) {
                    //We only update the buckets for open cases

                    //On the off-chance that the business hours on the case are null, use the default ones instead
                    Id hoursToUse = updatedCase.BusinessHoursId!=null?updatedCase.BusinessHoursId:defaultHours.Id;

                    //The diff method comes back in milliseconds, so we divide by 60000 to get minutes.
                    Double timeSinceLastStatus = BusinessHours.diff(hoursToUse, updatedCase.Last_Status_Change__c, System.now())/60000.0;
                    System.debug(timeSinceLastStatus);

                    //We decide which bucket to add it to based on whether it was in a stop status before
                    if (stopStatusSet.contains(oldCase.Status)) {
                        updatedCase.Time_With_Customer__c += timeSinceLastStatus;
                    } else {
                        //Calculate the different time with TNS in Minutes
                        if (oldCase.Status == 'In Progress') {
                            updatedCase.Time_In_Progress__c += timeSinceLastStatus;   
                        } else if (oldCase.Status == 'B2B Investigation') {
                            updatedCase.Time_With_B2B__c += timeSinceLastStatus;
                        } else if (oldCase.Status == 'CE Investigation') {
                            updatedCase.Time_With_CE__c += timeSinceLastStatus;
                        } else if (oldCase.Status == 'New') {
                            updatedCase.Time_in_New_State__c += timeSinceLastStatus;
                        } else if (oldCase.Status == 'Needs Reply') {
                            updatedCase.Time_Pending_Response__c += timeSinceLastStatus;
                        }
                       
                    }
                       

                    if (closedStatusSet.contains(updatedCase.Status)) {
                        updatedCase.Case_Age_In_Business_Minutes__c = updatedCase.Time_With_Customer__c + updatedCase.Time_With_Support__c + updatedCase.Time_With_CE__c + updatedCase.Time_With_B2B__c + updatedCase.Time_Pending_Response__c + updatedCase.Time_in_New_State__c;
                        updatedCase.Time_With_Support__c = updatedCase.Time_With_Support__c + updatedCase.Time_Pending_Response__c + updatedCase.Time_in_New_State__c;
                    }
                }

                updatedCase.Last_Status_Change__c = System.now();
            }
        }
    }
}

Apex test class:

@IsTest
public class CalculateBusinessHoursAgesTest {
    public static testMethod void testBusinessHoursBucketer() {
        Stop_Status__c ss = new Stop_Status__c(Name = 'On Hold');
        insert ss;

        Case c = new Case();
        c.Status = 'New';
        c.Category__c = 'Production Support';
        c.Sub_Category__c = 'Settlement';
        c.Last_Status_Change__c = System.Now();
        c.Subject = 'TEST';
        insert c;
       
        c.Status = 'In Progress';
        update c;

        c.Status = 'On Hold';
        update c;
       
        c.Status = 'On Hold';
        update c;
             
        c.Status = 'Pending Third Party';
        update c;
       
        c.Status = 'CE Investigation';
        update c;
       
        c.Status = 'B2B Investigation';
        update c;
       
        c.Status = 'Needs Reply';
        update c;
       
        c.Status = 'Needs More Info';
        update c;
    
        Case updatedCase = [select Status, Time_in_New_State__c, Time_With_Customer__c,Time_With_Support__c,Case_Age_In_Business_Minutes__c,Time_With_CE__c,Time_With_B2B__c,Time_Pending_Response__c from Case where Id=:c.Id];
       
        System.assert(updatedCase.Time_in_New_State__c!=0.000);
        System.assert(updatedCase.Time_Pending_Response__c!=0.000);
        System.assert(updatedCase.Time_With_B2B__c!=0.000);
        System.assert(updatedCase.Time_With_Customer__c!=0.000);
        System.assert(updatedCase.Time_With_CE__c!=0.000);
        System.assert(updatedCase.Time_With_Support__c!=0.010);
        System.assert(updatedCase.Case_Age_In_Business_Minutes__c==0);
   
        c.Status = 'Closed';
        update c;
       
        updatedCase = [select Status, Time_in_New_State__c, Time_With_Customer__c,Time_With_Support__c,Case_Age_In_Business_Minutes__c,Time_With_CE__c,Time_With_B2B__c,Time_Pending_Response__c from Case where Id=:c.Id];
       
        System.assert(updatedCase.Case_Age_In_Business_Minutes__c!=null);
        System.debug('TEST Completed'+ c.Status + c.Time_in_New_State__c + c.Time_With_Customer__c + c.Time_With_Support__c + c.Case_Age_In_Business_Hours__c + c.Time_With_CE__c + c.Time_With_B2B__c + c.Time_Pending_Response__c);       
    }
}