function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
DBManagerDBManager 

Custom Validation Exception being triggered when it shouldn't

I think I might be a little bit blind here, because I cannot see why a validation rule should be throwing up an exception.

 

The only thing that I can fathom that would create the error would be if the associated test class was setting an illegal date - i.e. one that is not on the first of the month.

 

However, the only Start Dates set are:

Start_Date__c=date.newinstance(2011, 1, 1)

Start_Date__c=date.newinstance(2011, 7, 1)

which are both on the first of the month!



 

So, first, the error:

Error:Apex trigger ItemandIPISubscriptionLinks caused an unexpected exception, contact your administrator: ItemandIPISubscriptionLinks: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a092000000KcY3sAAF; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, The Start Date must be the first of the month.: [Start_Date__c]: Trigger.ItemandIPISubscriptionLinks: line 223, column 1

 Now the validation rule:

AND (
NOT ( ISBLANK ( Start_Date__c )),
DAY ( Start_Date__c ) > 1
)

 Now the Trigger:

trigger ItemandIPISubscriptionLinks on Item__c (after update, after insert) {

Set<Id> itemIds = new Set<Id>();
Set<Id> eventIds = new Set<Id>();
Set<Id> itemCountIds = new Set<Id>();


//Put the list value ids in the set
if (Trigger.isUpdate){
    for (Integer i = 0; i < Trigger.new.size(); i++){
        if (Trigger.new[i].RecordTypeId == '01220000000AGp1' &&
            ((Trigger.new[i].Probability__c == 100 && Trigger.new[i].Cancelled__c == FALSE 
            && 
            ((Trigger.old[i].Probability__c <> 100 || Trigger.old[i].Cancelled__c <> FALSE)
            || 
            (Trigger.new[i].Start_Date__c <> Trigger.old[i].Start_Date__c ||
            Trigger.new[i].Term__c <> Trigger.old[i].Term__c ||
            Trigger.new[i].Full_Amount2__c <> Trigger.old[i].Full_Amount2__c)))
            
            ||
            
            (Trigger.new[i].Probability__c <> 100 || Trigger.new[i].Cancelled__c <> FALSE) 
            && 
            Trigger.old[i].Probability__c == 100 && Trigger.old[i].Cancelled__c == FALSE)
           )
        {
            itemIds.add(Trigger.new[i].id);
            eventIds.add(Trigger.new[i].Event_Issue__c);
        }
    }
}
if (Trigger.isInsert){
    for (Integer i = 0; i < Trigger.new.size(); i++){
        if (Trigger.new[i].RecordTypeId == '01220000000AGp1' && Trigger.new[i].Probability__c == 100 && Trigger.new[i].Cancelled__c == FALSE) {
            itemIds.add(Trigger.new[i].id);
            eventIds.add(Trigger.new[i].Event_Issue__c);
        }
    }
}

IPI_Subscription__c[] sub =
[SELECT Id, Event_Issue__c, Month__c FROM IPI_Subscription__c WHERE Event_Issue__c IN :eventIds];

Item__c[] ite =
[SELECT Id, Event_Issue__c, Probability__c, Cancelled__c, Start_Date__c, End_Date__c, Term__c, Amount_Formula__c, Monthly_Amount__c, Jan_Amount__c, Feb_Amount__c, Mar_Amount__c,
Apr_Amount__c, May_Amount__c, Jun_Amount__c, Jul_Amount__c, Aug_Amount__c, Sep_Amount__c, Oct_Amount__c, 
Nov_Amount__c, Dec_Amount__c FROM Item__c WHERE Event_Issue__c IN :eventIds];

for (IPI_Subscription__c subs :sub){
    Decimal amou = 0;
    Integer n = 0;

for (Item__c items :ite){
    
    if (items.Probability__c == 100 && items.Cancelled__c == FALSE){
    
    //January 
        if (subs.Month__c == 'Jan'){
            if (items.Jan_Amount__c>0){
                items.Jan_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                n += 1;
                subs.Amount_Sold2__c = amou;
            }
            else
                items.Jan_Subscription__c = NULL;
        }

    //February
        else if (subs.Month__c == 'Feb'){
            if (items.Feb_Amount__c>0){
                items.Feb_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Feb_Subscription__c = NULL;
        }
       
    //March
        else if (subs.Month__c == 'Mar'){
            if (items.Mar_Amount__c>0){
                items.Mar_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Mar_Subscription__c = NULL;
        }
    
    //April
        else if (subs.Month__c == 'Apr'){
            if (items.Apr_Amount__c>0){
                items.Apr_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Apr_Subscription__c = NULL;
        }
    
    //May
        else if (subs.Month__c == 'May'){
            if (items.May_Amount__c>0){
                items.May_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.May_Subscription__c = NULL;
        }
    
    //Jun
        else if (subs.Month__c == 'Jun'){
            if (items.Jun_Amount__c>0){
                items.Jun_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Jun_Subscription__c = NULL;
        }
    
    //July
        else if (subs.Month__c == 'Jul'){
            if (items.Jul_Amount__c>0){
                items.Jul_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Jul_Subscription__c = NULL;
        }
    
    //August
        else if (subs.Month__c == 'Aug'){
            if (items.Aug_Amount__c>0){
                items.Aug_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Aug_Subscription__c = NULL;
        }
    
    //September
        else if (subs.Month__c == 'Sep'){
            if (items.Sep_Amount__c>0){
                items.Sep_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Sep_Subscription__c = NULL;
        }
    
    //October
        else if (subs.Month__c == 'Oct'){
            if (items.Oct_Amount__c>0){
                items.Oct_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Oct_Subscription__c = NULL;
        }
    
    //November
        else if (subs.Month__c == 'Nov'){
            if (items.Nov_Amount__c>0){
                items.Nov_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Nov_Subscription__c = NULL;
        }
    
    //December
        else if (subs.Month__c == 'Dec'){
            if (items.Dec_Amount__c>0){
                items.Dec_Subscription__c = subs.Id;
                amou += items.Monthly_Amount__c;
                subs.Amount_Sold2__c = amou;
                n += 1;
            }
            else
                items.Dec_Subscription__c = NULL;
        }
    }
    
    else {
    items.Jan_Subscription__c = NULL;
    items.Feb_Subscription__c = NULL;
    items.Mar_Subscription__c = NULL;
    items.Apr_Subscription__c = NULL;
    items.May_Subscription__c = NULL;
    items.Jun_Subscription__c = NULL;
    items.Jul_Subscription__c = NULL;
    items.Aug_Subscription__c = NULL;
    items.Sep_Subscription__c = NULL;
    items.Oct_Subscription__c = NULL;
    items.Nov_Subscription__c = NULL;
    items.Dec_Subscription__c = NULL;
    }
}
    
    subs.Number_Sold__c = n;
    
}

update sub;
update ite;





}

 

And finally the Test class:

@isTest
private class TestIPITriggers {

static TestMethod void TestTotalItemAmount(){

Account company = new Account(Name='test company', BillingStreet='123 red', BillingCity='London', BillingPostalCode='123fgh', BillingCountry='United Kingdom');
insert company;

Contact contact = new Contact(LastName = 'test', AccountId = company.Id, Email = 'test@test.com', Phone='1234');
insert contact;

Opportunity deal = new Opportunity(Name='autofill', AccountId = company.Id, RecordTypeId ='01220000000AGqi', Contact_Delegate__c=contact.Id, CloseDate=date.today(), 
                    StageName='Closed - Awaiting Approval', Invoice_Address__c='Company', Address_Invoice_to_contact_above__c='Yes', 
                    Voucher_Copy_Address__c='Company', Address_Voucher_Copy_to_contact_above__c='Yes');
insert deal;

Issue_Year__c event = new Issue_Year__c(Name='LC11a', Date__c=date.newinstance(2011, 1, 1), Description__c='Leaders Council 2011', SUN_T3_Code__c = 'LC2011');
insert event;

IPI_Subscription__c subscription1 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Jan', Name='LCJan11a');
insert subscription1;

IPI_Subscription__c subscription2 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Feb', Name='LCFeb11a');
insert subscription2;

IPI_Subscription__c subscription3 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Mar', Name='LCMar11a');
insert subscription3;

IPI_Subscription__c subscription4 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Apr', Name='LCApr11a');
insert subscription4;

IPI_Subscription__c subscription5 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='May', Name='LCMay11a');
insert subscription5;

IPI_Subscription__c subscription6 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Jun', Name='LCJun11a');
insert subscription6;

IPI_Subscription__c subscription7 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Jul', Name='LCJul11a');
insert subscription7;

IPI_Subscription__c subscription8 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Aug', Name='LCAug11a');
insert subscription8;

IPI_Subscription__c subscription9 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Sep', Name='LCSep11a');
insert subscription9;

IPI_Subscription__c subscription10 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Oct', Name='LCOct11a');
insert subscription10;

IPI_Subscription__c subscription11 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Nov', Name='LCNov11a');
insert subscription11;

IPI_Subscription__c subscription12 = new IPI_Subscription__c(Event_Issue__c=event.Id, Month__c='Dec', Name='LCDec11a');
insert subscription12;

Item__c item1 = new Item__c(Name='.', Opportunity__c = deal.Id, Full_Amount2__c=6000, RecordTypeId='01220000000AGp1', Probability__c=100, 
                Event_Issue__c = event.Id, Start_Date__c=date.newinstance(2011, 1, 1), Term__c=6, Payment_Terms__c='28 days');
insert item1;

Item__c[] items = [SELECT Id, Amount__c, Amount_Formula__c, Jan_Subscription__r.Name, Jan_Amount__c, Event_Issue__r.Name FROM Item__c WHERE Event_Issue__r.Name = 'LC11a'];

for (Item__c it :items){
system.assertEquals(it.Jan_Amount__c, 1000);
system.assertEquals(it.Jan_Subscription__r.Name, 'LCJan11a');
}

item1.Start_Date__c=date.newinstance(2011, 7, 1);
update item1;

item1.Probability__c = 50;
update item1;

delete item1;


}

}

 

 

Hope you can help!

 

Best Answer chosen by Admin (Salesforce Developers) 
DBManagerDBManager

The final code included:

if (items.Deal_Date__c.year() < date.today().year()){
            items.Override_Ok__c = TRUE;
        }
    
        if(items.Deal_Date__c.year() == date.today().year() &&
        items.Deal_Date__c.month() < date.today().month()){
            items.Override_Ok__c = TRUE;
        }



This little loop ensures that any other Items that are being picked up are set to Override Ok = TRUE, which means the 'Deal Date' error does not occur.

 

Problem solved!

 

If this isn't clear to anyone, let me know and I will clarify.

All Answers

DBManagerDBManager

UPDATE:

 

After a few attempts at fixing this, I now have the following error:

Error:Apex trigger ItemandIPISubscriptionLinks caused an unexpected exception, contact your administrator: ItemandIPISubscriptionLinks: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id a092000000KcY3sAAF; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, The deal date can not be in a prior month.: []: Trigger.ItemandIPISubscriptionLinks: line 223, column 1

 

I.e. It is telling me that the trigger won't work because it is setting the Deal Date to a prior month (which it isn't).

 

I just ran all the tests in our SF org and none of them came up with the same error.

 

STILL CONFUSED!

spraetzspraetz

What is the validation rule that throws this error message? : "The deal date can not be in a prior month."

JayantJayant

Use a system.debug() to check what exactly is being set in the deal date, that can help you out.

Also check the validation condition, may be it's erraneous.

DBManagerDBManager

Thanks for the reply.

 

This is the validation rule:

 

AND(

(AND(

(OR(
YEAR( Deal_Date__c ) < YEAR(Today()),

AND(MONTH(Deal_Date__c ) < MONTH(Today()),
YEAR(Deal_Date__c ) = YEAR(Today()))
)),

(OR( Override_ok__c = false, $UserRole.Name <> "Super User"))
)),

(AND( RecordTypeId <> "01220000000DuQ6", RecordTypeId <> "01220000000DuQp"))
)

 

Rather convoluted, I know, but the deal date set in the class is the system date for today, so this should not cause an error (indeed it doesn't when you run the test itself).

DBManagerDBManager

Thanks for your reply.

 

I am fairly new to Apex and, though I have seen system debug's being used, I still don't know how to use them.

 

This, I suppose, is the time to learn!

DBManagerDBManager

So I added a system debug to the test, deployed it, re-ran it in the live system and it showed that the deal date was: 2011-09-27, which is fine.

 

I re-tested the item and it still gave the same error message.

 

I ran through the validation rule and that's all fine - it should only be triggered if the deal date is in a prior year or prior month of the same year, which the deal date in the test class isn't.

 

So what is triggering this validation rule?

 

Can anyone advise?

DBManagerDBManager

I think I've found the solution to this, but am still working out the nuts and bolts.

 

I think the validation rule is triggered by another item that the trigger is accessing.

 

I.e. the triggering Item passes the validation rule, and the test class passes the validation rule. However, since the trigger accesses and may update other items, one of those items could trigger the validation rule.

 

Which is why the test classes pass and the error cannot be replicated in the test system (as other items have not been created for previous months).

 

When I write the final code that works, I will post it here as a solution (if it works!).

DBManagerDBManager

The final code included:

if (items.Deal_Date__c.year() < date.today().year()){
            items.Override_Ok__c = TRUE;
        }
    
        if(items.Deal_Date__c.year() == date.today().year() &&
        items.Deal_Date__c.month() < date.today().month()){
            items.Override_Ok__c = TRUE;
        }



This little loop ensures that any other Items that are being picked up are set to Override Ok = TRUE, which means the 'Deal Date' error does not occur.

 

Problem solved!

 

If this isn't clear to anyone, let me know and I will clarify.

This was selected as the best answer
DeptonDepton

Hi can you please clarify? Does this means that the error might be caused by another record and not the one we are editing?

or you mean another value?

Thank you

DBManagerDBManager

Indeed.

 

When an Item record is updated, and certain field values are changed, the trigger is fired. The trigger then finds the parent of this record, and in turn finds all the Items that are children of that parent (including the original trigger item).

 

In other words, when an Item is updated, the trigger finds its siblings and updates them. If any validation errors are generated by the siblings, then the trigger will not be able to complete, and an error is generated.

 

So, with this trigger, updating one item can generate an error message from another item.

 

Hope that helps.