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
YaduYadu 

FIELD_CUSTOM_VALIDATION_EXCEPTION

Hi,

 

I am getting the below error in line 307 while deploying and doent show me any errors when I run it.Please help me out with this.

 

Failure Message: "System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Sales Opportunities must be linked to an Originating Officer but the system was not able to automatically determine your default officer code:

 

public class SalesTargetHandler {

// these class variables are used by the OnBeforeInsert and OnAfterInsert methods
Map<String, Sales_Target__c> offCodeToSalesTarget = new Map<String, Sales_Target__c>(); //map of officer codes to a new copy of a Sales Target object
Date salesTargetMaxEndDate;
Date salesTargetMinBegDate;

// these class variables are used by the OnBeforeInsert methods
set<Id> newRecordIds = new set<Id>();

// -------------------------------------------------------------------------------------------------------------------------------
// Constructor
public SalesTargetHandler(){
}

private void gatherQueryInfo(Sales_Target__c[] stRecords, Boolean createClones){
salesTargetMaxEndDate = system.today();
salesTargetMinBegDate = system.today();

if (stRecords.size()>0){
salesTargetMaxEndDate = stRecords.get(0).Target_Period_End__c;
salesTargetMinBegDate = stRecords.get(0).Target_Period_Start__c;
}

set<ID> officerCodeSfidSet = new set<ID>();
// first pass. get the data I need
for(Sales_Target__c st : stRecords){
officerCodeSfidSet.add(st.Officer_Code__c);
if(st.Target_Period_End__c > salesTargetMaxEndDate) salesTargetMaxEndDate = st.Target_Period_End__c;
if(st.Target_Period_Start__c < salesTargetMinBegDate) salesTargetMinBegDate = st.Target_Period_Start__c;
}

// retrieve the actual officer code values from the Officer_Code__c table
map<ID, Officer_Code__c> offCodeMap = new map<ID, Officer_Code__c>([select id, Officer_Code__c from Officer_Code__c where ID in :officerCodeSfidSet]);

for(Sales_Target__c st : stRecords){
Sales_Target__c mapST = st;
if (createClones){
mapST = st.Clone(true, true, true, true);
// we are going to depend on the object being configured to default these two fields to 0.
// The trigger code cannot handle null values for these fields
//if (mapST.Actual_Number_of_Calls__c==null) mapST.Actual_Number_of_Calls__c = 0;
//if (mapST.Actual_Number_of_Sales__c==null) mapST.Actual_Number_of_Sales__c = 0;
}
Officer_Code__c offCodeRec = offCodeMap.get(mapST.Officer_Code__c);
if (offCodeRec!=null) offCodeToSalesTarget.put(offCodeRec.Officer_Code__c, mapST);
}

}

private void checkSalesTargetOverlap(){
for(Sales_Target__c existST :[Select Id ,Officer_Code__c, Officer_Code__r.Officer_Code__c, Target_Period_Start__c ,Target_Period_End__c
from Sales_Target__c
where Officer_Code__r.Officer_Code__c IN :offCodeToSalesTarget.keySet()
and (Target_Period_End__c >= :salesTargetMinBegDate
or Target_Period_Start__c <= :salesTargetMaxEndDate) and Id NOT IN: newRecordIds])
{
Sales_Target__c newST = offCodeToSalesTarget.get(existST.Officer_Code__r.Officer_Code__c);

if(newST != null && existST.Officer_Code__c == newST.Officer_Code__c &&
((existST.Target_Period_Start__c <= newST.Target_Period_Start__c &&
existST.Target_Period_End__c >= newST.Target_Period_Start__c)
|| (existST.Target_Period_Start__c<= newST.Target_Period_End__c &&
existST.Target_Period_End__c>= newST.Target_Period_End__c) ||
(existST.Target_Period_Start__c<= newST.Target_Period_Start__c &&
existST.Target_Period_End__c >= newST.Target_Period_End__c)||
(existST.Target_Period_Start__c>= newST.Target_Period_Start__c &&
existST.Target_Period_End__c <= newST.Target_Period_End__c)

)){

String errorMsg = System.Label.Sales_Target_Error_Message;
newST.addError(errorMsg);
}
}
}

/**
*Method unlinks all the tasks and sales opp to the sales target.
*/
private void unlinkSOandTasks(Sales_Target__c[] stForUnlink){
set<Id> stIds = new set<Id>();
Map<Id,Sales_Target__c> oppStMap = new Map<Id,Sales_Target__c>();
Map<Id,Sales_Target__c> taskStMap = new Map<Id,Sales_Target__c>();
for(Sales_Target__c st : stForUnlink){
stIds.add(st.Id);
}
List<Sales_Opportunity__c> sopps = [Select Id, Sales_Target__c,Status__c,Referred_To__c,
Officer_Code__c, Product_Category__c
From Sales_Opportunity__c Where Sales_Target__c IN : stIds];

for(Sales_Opportunity__c sopp : sopps){
for(Sales_Target__c st : stForUnlink){
if(sopp.Sales_Target__c == st.Id){
oppStMap.put(sopp.Id,st);
}
}
}

for(Sales_Opportunity__c sopp : sopps){
sopp.Sales_Target__c = null;
if(sopp.Status__c == 'Closed Won'){
if(sopp.Product_Category__c == 'Loans'){
oppStMap.get(sopp.Id).Actual_Number_of_Sales__c--;
}else{
oppStMap.get(sopp.Id).Actual_Number_of_Sales_Non_Lending__c--;
}
if(sopp.Referred_To__c!=null && sopp.Referred_To__c!=sopp.Officer_Code__c)
oppStMap.get(sopp.Id).Actual_Number_of_Sales_Referred_By__c--;
}
}
update sopps;

List<Task> tasks = [Select Id, Sales_Target_Id__c,ActivityDate, Officer_Code__c, Type, Status, WhatId
From Task Where Sales_Target_Id__c IN : stIds];
for(Task t : tasks){
for(Sales_Target__c st : stForUnlink){
if(t.Sales_Target_Id__c == st.Id){
taskStMap.put(t.Id,st);
}
}
}
for(Task t : tasks){
t.Sales_Target_Id__c = null;
if((t.Type =='Call' || t.Type == 'In-Person Meeting') && t.Status=='Completed' && t.WhatId != null){
taskStMap.get(t.Id).Actual_Number_of_Calls_All__c--;
if(t.Type == 'In-Person Meeting')
taskStMap.get(t.Id).Actual_Number_of_Calls__c--;
}
}
update tasks;
}

private void linkSOandTasks(){
Sales_Opportunity__c[] salesOpp = new Sales_Opportunity__c[]{};
for(Sales_Opportunity__c opp : [SELECT id ,Officer_Code__c, Officer_Code__r.Officer_Code__c, Sales_Target__c,Count_Against_Targets__c,Close_Date__c,
Referred_To__c, Status__c, Product_Category__c FROM Sales_Opportunity__c
WHERE Count_Against_Targets__c = true
AND Sales_Target__c = null
AND Officer_Code__r.Officer_Code__c IN :offCodeToSalesTarget.keySet()
AND Close_Date__c <= :salesTargetMaxEndDate
AND Close_Date__c >= :salesTargetMinBegDate])
{
Sales_Target__c newST = offCodeToSalesTarget.get(opp.Officer_Code__r.Officer_Code__c);

if(newST != null && opp.Close_Date__c <= newST.Target_Period_End__c && opp.Close_Date__c >= newST.Target_Period_Start__c){
if(newST.Officer_Code__c == opp.Officer_Code__c
&& newST.Target_Period_End__c > opp.Close_Date__c && newST.Target_Period_Start__c < opp.Close_Date__c){//adding this if as a part of new changes.
opp.Sales_Target__c = newST.id;
salesOpp.add(opp);
System.debug('-----opp->>>>'+opp);
if(opp.Status__c == 'Closed Won'){
if(opp.Product_Category__c == 'Loans'){
newST.Actual_Number_of_Sales__c++;
}else{
newST.Actual_Number_of_Sales_Non_Lending__c++;
}
if(opp.Referred_To__c!=null && opp.Referred_To__c!=opp.Officer_Code__c)
newST.Actual_Number_of_Sales_Referred_By__c++;
}
}
}
}

if (!salesOpp.isEmpty())
update salesOpp;

Task[] tasksToUpdate = new Task[]{};
for(Task t : [SELECT Id, ActivityDate, Officer_Code__c, Type, Status,WhatId
FROM Task
WHERE Officer_Code__c IN :offCodeToSalesTarget.keySet()
AND ActivityDate <= :salesTargetMaxEndDate
AND ActivityDate >= :salesTargetMinBegDate]){

Sales_Target__c newST = offCodeToSalesTarget.get(t.Officer_Code__c);

if(newST != null && t.ActivityDate <= newST.Target_Period_End__c && t.ActivityDate >= newST.Target_Period_Start__c && (t.Type =='Call' || t.Type == 'In-Person Meeting') ){
t.Sales_Target_Id__c = newST.Id;
tasksToUpdate.add(t);
if((t.Type =='Call' || t.Type == 'In-Person Meeting') && t.Status=='Completed' &&
t.WhatId != Null){
newST.Actual_Number_of_Calls_All__c++;
if(t.Type == 'In-Person Meeting')
newST.Actual_Number_of_Calls__c++;
}
}
}

if(!tasksToUpdate.isEmpty())
update tasksToUpdate;
}

private void setVisibility(Sales_Target__c[] stRecords, map<Id, Sales_Target__c> oldRecordMap,String event){
//Checks if new record is added, calculates sharing for them.
if(event == 'Insert'){
Visibility_Utility vu = new Visibility_Utility();
vu.createShare('Sales_Target__c',stRecords);
}

//checks if the office code values has been updated and
//re-calculate the sharing if it is so.
if(event == 'Update'){
List<Sales_Target__c> reShareSt = new List<Sales_Target__c>();

for(Sales_Target__c st : stRecords){
if(oldRecordMap.get(st.Id).Officer_Code__c != st.Officer_Code__c){
reShareSt.add(st);
}
}
Visibility_Utility vu = new Visibility_Utility();
vu.createShare('Sales_Target__c',reShareSt);
}
}

public void OnBeforeInsert(Sales_Target__c[] workingList){
gatherQueryInfo(workingList, false);
checkSalesTargetOverlap();
}

public void OnAfterInsert(Sales_Target__c[] workingList){
gatherQueryInfo(workingList, true);
linkSOandTasks();
if(offCodeToSalesTarget.size() > 0)
update offCodeToSalesTarget.values();

setVisibility(workingList,null,'Insert');
}

public void onBeforeUpdate(Sales_Target__c[] stRecords, map<Id, Sales_Target__c> oldRecordMap){
Sales_Target__c[] workingList = new Sales_Target__c[]{};
Sales_Target__c oldRec;

for(Sales_Target__c st: stRecords){
//if(oldRecordMap != null)
oldRec = oldRecordMap.get(st.Id);
if(st.Officer_Code__c!=oldRec.Officer_Code__c || st.Target_Period_Start__c!=oldRec.Target_Period_Start__c || st.Target_Period_End__c!=oldRec.Target_Period_End__c){
workingList.add(st);
newRecordIds.add(st.Id);
}
}

if(!workingList.isEmpty()){
gatherQueryInfo(workingList, false);
checkSalesTargetOverlap();
unlinkSOandTasks(workingList);
linkSOandTasks();
}

}

public void OnAfterUpdate(Sales_Target__c[] workingList, map<Id, Sales_Target__c> oldRecordMap){
setVisibility(workingList,oldRecordMap,'Update');
}


//Test method for this class.
public static testMethod void testThisClass(){
string TYPE_ROCODE = 'Rep Officer Code';
string TYPE_AOCODE = 'Account Officer Code';
User testAOUser = [select id from User where id!=:UserInfo.getUserId() and Profile.Name='Rep Officer' limit 1];
User testROUser = [select id from User where id!=:UserInfo.getUserId() and Profile.Name='Account Officer' limit 1];

if (testAOUser==null || testROUser==null) return;

Officer_Code__c aoCode = new Officer_Code__c(Type__c=TYPE_AOCODE, Officer_Code__c='AAA', Assigned_To_Id__c=testAOUser.Id);
Officer_Code__c roCode = new Officer_Code__c(Type__c=TYPE_ROCODE, Officer_Code__c='RR', Assigned_To_Id__c=testROUser.Id);
List<Officer_Code__c> ocList = new List<Officer_Code__c>();
ocList.add(aoCode);
ocList.add(roCode);
insert ocList;

Office__c testOffice1 = new Office__c(Office_Code__c='OO1', Region__c='Brazil');
Office__c testOffice2 = new Office__c(Office_Code__c='OO2', Region__c='Brazil');
insert new Office__c[]{testOffice1, testOffice2};

// create the two test cases for RO visibility
// Office = 'OO1', RO Code = 'RR' ==> RO User
Data_Visibility__c testRODV1 = new Data_Visibility__c(Office_Id__c=testOffice1.Id, Officer_Code_Id__c=roCode.Id, User_Id__c=testROUser.Id);
// Office = 'OO2' ==> RO User
Data_Visibility__c testRODV2 = new Data_Visibility__c(Office_Id__c=testOffice2.Id, User_Id__c=testROUser.Id);

// create the test case for AO visibility
// AO Code = 'AAA' ==> AO User
Data_Visibility__c testAODV = new Data_Visibility__c(Officer_Code_Id__c=aoCode.Id, User_Id__c=testAOUser.Id);


insert new Data_Visibility__c[]{testRODV1, testRODV2, testAODV};



Sales_Opportunity__c so = new Sales_Opportunity__c();
List<Sales_Opportunity__c> soList = new List<Sales_Opportunity__c>();
so.Name = 'test';
so.Close_Date__c = System.Today();
so.Officer_Code__c= ocList[0].Id;
so.Product_Category__c = 'Domestic Deposits';
so.stage__c ='Closed Won';
soList.add(so);
insert soList;

Sales_Opportunity__c so1 = new Sales_Opportunity__c();
so.Name = 'test';
so.Close_Date__c = System.Today();
so.Officer_Code__c= ocList[0].Id;
so.Product_Category__c = 'Loans';
so.stage__c ='Closed Won';
insert so1;




Task t = new Task();
t.ActivityDate = System.Today();
// t.Officer_Code__c= ocList[0].Officer_Code__c;
t.status = 'Completed';
t.Type = 'In-Person Meeting';
t.WhatId = soList[0].Id;
insert t;


Sales_Target__c st = new Sales_Target__c();
List<Sales_Target__c> stList = new List<Sales_Target__c>();
st.Name = 'test';
st.Target_Period_Start__c = System.Today().addDays(-2);
st.Target_Period_End__c = System.Today().addDays(5);
st.Target_Number_of_Sales__c = 3;
st.Target_Number_of_Sales_Non_Lending__c= 3;
st.Target_Number_of_Calls_All__c = 3;
st.Target_Number_of_Calls__c = 3;
st.Officer_Code__c = ocList[0].Id;


Sales_Target__c st1 = new Sales_Target__c();
st1.Name = 'test';
st1.Target_Period_Start__c = System.Today();
st1.Target_Period_End__c = System.Today().addDays(2);
st1.Target_Number_of_Sales__c = 3;
st1.Target_Number_of_Sales_Non_Lending__c= 3;
st1.Target_Number_of_Calls_All__c = 3;
st1.Target_Number_of_Calls__c = 3;
st1.Officer_Code__c = ocList[0].Id;

stList.add(st1);
insert stList;

stList[0].Officer_Code__c = ocList[1].Id;
st1.Target_Period_End__c = System.Today();
update stList[0];

delete stList;
undelete stList;

}
}

kiranmutturukiranmutturu

u have the validation rule on the inserting object in your code... that needs to be bypassed ...

asish1989asish1989

Hi

    would you like to describe briefly what you actually trying to do with this huge code  ?

   I mean about your work flow...

 

 

 

 

 

  thanks

   asish