You need to sign in to do that
Don't have an account?

The larger I set the batch size the more duplicates I receive, Please help, kudos to anyone that solves this.
Public Class ContractFunctionsCloneContractAndOLIs
{
Public static void CloneMaintContractAndLineItems(Map<Id,Contract> oldMap, Map<Id,Contract> newMap)
{
List<Id> ContractToClone = new List<Id>();
List<Id> ContractLineItemsToClone = new List<Id>();
Date StartDate;
Date EndDate;
Integer NumberOfDays = 0;
Integer NumberOfMonths = 0;
Integer NumberOfYears = 0;
Double YearTerm = 0;
Integer NumberOfLeapYearDays = 0;
Integer TermsByMonth = 0;
Integer Prevcount =0;
Boolean MaintTermMisMatch;
String OriginalCase;
Date CurrentDay;
Date PrevCurrentDay;
Integer PrevNumberOfDays =0;
Date PrevStartDate;
Date PrevEndDate;
Integer PrevNumberOfLeapYearDays =0;
for(Contract c : newMap.Values())
{
ContractToClone.add(c.Id);
}
for(Contract_Line_Item__c CLI :[Select id from Contract_Line_Item__c where Contract__c in :ContractToClone])
{
ContractLineItemsToClone.add(CLI.id);
}
Contract newContract = new Contract();
if(ContractToClone.size() > 0 && ContractLineItemsToClone.size() > 0)
{
for(Contract c : [Select id, Status, Attn_To__c, Original_Case__c, Maintenance_out_of_sync__c, NewlyCreatedNumDays__c, DateFinal__c,PrevNumberOfDays__c, PrevStartDate__c, PrevEndDate__c, PrevNumberOfLeapYearDays__c, Term_In_Days__c, XNumberOfDays__c, AccountId, XNumberOfLeapYearDays__c, NumberOfLeapYearDays2__c, SpecialTerms, FEndDate__c, FCompareDayEndDate__c, Total_Maintenance_Price__c,Months_between_start_and_end__c,Override_Total_Price__c,StartDate, Contract_End_Date__c, Case__c, RecordTypeId from Contract where Id in :ContractToClone ])
{
List<Contract> ContractsToInsert = new List<Contract>();
newContract.Total_Maintenance_Price__c = c.Total_Maintenance_Price__c;
newContract.Status = 'Pending';
newContract.AccountId = c.AccountId;
newContract.StartDate = c.Contract_End_Date__c + 1;
newContract.RecordTypeId = ServiceClass.getRecordTypesNameMap('Contract').get('Maintenance Contract').Id;
newContract.Parent_Contract__c = c.id;
ContractsToInsert.add(newContract);
insert(ContractsToInsert);
List<Contract_Line_Item__c> ContractLineItemsToInsert = new List<Contract_Line_Item__c>();
String ContractId;
String AccountId;
String CaseId;
String CLIStatus;
for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert])
{
ContractId = insertedContracts.id;
AccountId = insertedContracts.AccountId;
CaseId = insertedContracts.Case__c;
CLIStatus = 'Pending';
}
for(Contract_Line_Item__c cc : [Select id, Maintenance_Sales_Price__c, Contract_Line_Item_Status__c, Product_LU__c, Quantity__c, List_Price__c from Contract_Line_Item__c where Id in :ContractLineItemsToClone])
{
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
newCLI.Contract_Line_Item_Status__c = CLIStatus;
newCLI.Contract__c = ContractId;
//newCLI.Case_Id__c = CaseId;
newCLI.Account__c = AccountId;
newCLI.Contract_Line_Item_Origin__c = 'Contract Clone Follow Up Contract';
newCLI.Product_LU__c = cc.Product_LU__c;
newCLI.Quantity__c = cc.Quantity__c;
newCLI.List_Price__c = cc.List_Price__c;
newCLI.Maintenance_Sales_Price__c = cc.Maintenance_Sales_Price__c;
if(cc.Contract_Line_Item_Status__c == 'Do Not Renew')
{
newCLI.Contract_Line_Item_Status__c = 'Do Not Renew';
}
if(cc.Contract_Line_Item_Status__c == 'Cancelled')
{
newCLI.Contract_Line_Item_Status__c = 'Cancelled';
}
ContractLineItemsToInsert.add(newCLI);
}
insert(ContractLineItemsToInsert);
update(ContractLineItemsToInsert);
}
}}}
{
Public static void CloneMaintContractAndLineItems(Map<Id,Contract> oldMap, Map<Id,Contract> newMap)
{
List<Id> ContractToClone = new List<Id>();
List<Id> ContractLineItemsToClone = new List<Id>();
Date StartDate;
Date EndDate;
Integer NumberOfDays = 0;
Integer NumberOfMonths = 0;
Integer NumberOfYears = 0;
Double YearTerm = 0;
Integer NumberOfLeapYearDays = 0;
Integer TermsByMonth = 0;
Integer Prevcount =0;
Boolean MaintTermMisMatch;
String OriginalCase;
Date CurrentDay;
Date PrevCurrentDay;
Integer PrevNumberOfDays =0;
Date PrevStartDate;
Date PrevEndDate;
Integer PrevNumberOfLeapYearDays =0;
for(Contract c : newMap.Values())
{
ContractToClone.add(c.Id);
}
for(Contract_Line_Item__c CLI :[Select id from Contract_Line_Item__c where Contract__c in :ContractToClone])
{
ContractLineItemsToClone.add(CLI.id);
}
Contract newContract = new Contract();
if(ContractToClone.size() > 0 && ContractLineItemsToClone.size() > 0)
{
for(Contract c : [Select id, Status, Attn_To__c, Original_Case__c, Maintenance_out_of_sync__c, NewlyCreatedNumDays__c, DateFinal__c,PrevNumberOfDays__c, PrevStartDate__c, PrevEndDate__c, PrevNumberOfLeapYearDays__c, Term_In_Days__c, XNumberOfDays__c, AccountId, XNumberOfLeapYearDays__c, NumberOfLeapYearDays2__c, SpecialTerms, FEndDate__c, FCompareDayEndDate__c, Total_Maintenance_Price__c,Months_between_start_and_end__c,Override_Total_Price__c,StartDate, Contract_End_Date__c, Case__c, RecordTypeId from Contract where Id in :ContractToClone ])
{
List<Contract> ContractsToInsert = new List<Contract>();
newContract.Total_Maintenance_Price__c = c.Total_Maintenance_Price__c;
newContract.Status = 'Pending';
newContract.AccountId = c.AccountId;
newContract.StartDate = c.Contract_End_Date__c + 1;
newContract.RecordTypeId = ServiceClass.getRecordTypesNameMap('Contract').get('Maintenance Contract').Id;
newContract.Parent_Contract__c = c.id;
ContractsToInsert.add(newContract);
insert(ContractsToInsert);
List<Contract_Line_Item__c> ContractLineItemsToInsert = new List<Contract_Line_Item__c>();
String ContractId;
String AccountId;
String CaseId;
String CLIStatus;
for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert])
{
ContractId = insertedContracts.id;
AccountId = insertedContracts.AccountId;
CaseId = insertedContracts.Case__c;
CLIStatus = 'Pending';
}
for(Contract_Line_Item__c cc : [Select id, Maintenance_Sales_Price__c, Contract_Line_Item_Status__c, Product_LU__c, Quantity__c, List_Price__c from Contract_Line_Item__c where Id in :ContractLineItemsToClone])
{
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
newCLI.Contract_Line_Item_Status__c = CLIStatus;
newCLI.Contract__c = ContractId;
//newCLI.Case_Id__c = CaseId;
newCLI.Account__c = AccountId;
newCLI.Contract_Line_Item_Origin__c = 'Contract Clone Follow Up Contract';
newCLI.Product_LU__c = cc.Product_LU__c;
newCLI.Quantity__c = cc.Quantity__c;
newCLI.List_Price__c = cc.List_Price__c;
newCLI.Maintenance_Sales_Price__c = cc.Maintenance_Sales_Price__c;
if(cc.Contract_Line_Item_Status__c == 'Do Not Renew')
{
newCLI.Contract_Line_Item_Status__c = 'Do Not Renew';
}
if(cc.Contract_Line_Item_Status__c == 'Cancelled')
{
newCLI.Contract_Line_Item_Status__c = 'Cancelled';
}
ContractLineItemsToInsert.add(newCLI);
}
insert(ContractLineItemsToInsert);
update(ContractLineItemsToInsert);
}
}}}
add
map<id, contract> originalContractMap = new map<id, contract>; //"source" id -> "source" contract
map<id, contract> originalToCloneMap = new map<id, contract>;;//"source" id -> "clone" contract
....
if (ContractsToInsertSET.add(s)) {
originalContractMap.put(c.id, c); //add this
originaltoCloneMap.put(c.id, s); //add this
ContractsToInsert.add(s);
}
...
insert(ContractsToInsert); //the key thing to now here is now is everything in originaltoclonemap.values() now has the id field appened as a result of the insert
....
//change
//for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert])
// {
//to
for (id originalID : originalContractMap.keyset()){
Contract srcContract = originalContractMap.get(originalID);//has all the fields of the original contract query
Contract clonedContract = originaltoCloneMap.get(originalID);//has all the fields that were in the insert + the id field due to the insert
this should get you going in the right directions.
All Answers
insert(ContractsToInsert);
is inside this loop
for(Contract_Line_Item__c CLI :[Select id from Contract_Line_Item__c where Contract__c in :ContractToClone])
{
ContractLineItemsToClone.add(CLI.id);
}
Since you are not mapping contract to contract line items, you are adding the full set to ever contract instead of the ones just related to the contract.
Public Class ContractFunctionsCloneContractAndOLIs
{
Public static void CloneMaintContractAndLineItems(Map<Id,Contract> oldMap, Map<Id,Contract> newMap)
{
List<Id> ContractToClone = new List<Id>();
List<Id> ContractLineItemsToClone = new List<Id>();
Date StartDate;
Date EndDate;
Integer NumberOfDays = 0;
Integer NumberOfMonths = 0;
Integer NumberOfYears = 0;
Double YearTerm = 0;
Integer NumberOfLeapYearDays = 0;
Integer TermsByMonth = 0;
Integer Prevcount =0;
Boolean MaintTermMisMatch;
String OriginalCase;
Date CurrentDay;
Date PrevCurrentDay;
Integer PrevNumberOfDays =0;
Date PrevStartDate;
Date PrevEndDate;
Integer CNT = 0;
Integer PrevNumberOfLeapYearDays =0;
for(Contract c : newMap.Values())
{
ContractToClone.add(c.Id);
CNT = CNT +1;
}
for(Contract_Line_Item__c CLI :[Select id from Contract_Line_Item__c where Contract__c in :ContractToClone])
{
ContractLineItemsToClone.add(CLI.id);
}
Contract newContract = new Contract();
List<Contract> ContractsToInsert1 = new List<Contract>();
SET<Contract> ContractsToInsertSET = new SET<Contract>();
List<Contract> ContractsToInsert = new List<Contract>();
if(ContractToClone.size() > 0 && ContractLineItemsToClone.size() > 0)
{
for(Contract c : [Select id, Status, Attn_To__c, Original_Case__c, Maintenance_out_of_sync__c, NewlyCreatedNumDays__c, DateFinal__c,PrevNumberOfDays__c,
PrevStartDate__c, PrevEndDate__c, PrevNumberOfLeapYearDays__c, Term_In_Days__c, XNumberOfDays__c, AccountId, XNumberOfLeapYearDays__c, NumberOfLeapYearDays2__c,
SpecialTerms, FEndDate__c, FCompareDayEndDate__c, Total_Maintenance_Price__c,Months_between_start_and_end__c,Override_Total_Price__c,StartDate,
Contract_End_Date__c, Case__c, RecordTypeId from Contract where Id in :ContractToClone ])
{
StartDate = c.StartDate;
PrevStartDate = c.StartDate;
PrevEndDate = c.Contract_End_Date__c;
EndDate = c.Contract_End_Date__c;
OriginalCase = c.Original_Case__c;
MaintTermMisMatch = c.Maintenance_out_of_sync__c;
PrevNumberOfDays = PrevStartDate.DaysBetween(PrevEndDate)+1;
while (Prevcount < (PrevNumberOfDays))
{
if(PrevStartDate.Month() == 2 && PrevStartDate.Day() == 29)
{
PrevNumberOfLeapYearDays = PrevNumberOfLeapYearDays + 1;
}
PrevCurrentDay = PrevStartDate.addDays(Prevcount);
if(PrevCurrentDay.Month() == 2 && PrevCurrentDay.Day() == 29)
{
PrevNumberOfLeapYearDays = PrevNumberOfLeapYearDays + 1;
}
Prevcount++;
}
newContract.SpecialTerms = c.SpecialTerms;
newContract.Override_Total_Price__c = c.Override_Total_Price__c;
newContract.Total_Maintenance_Price__c = c.Total_Maintenance_Price__c;
newContract.Status = 'Pending';
newContract.AccountId = c.AccountId;
newContract.StartDate = c.Contract_End_Date__c + 1;
newContract.Attn_To__c = c.Attn_To__c;
// newContract.Case__c = c.Case__c;
newContract.Original_Case__c = OriginalCase;
newContract.Maintenance_out_of_sync__c = MaintTermMisMatch;
newContract.PrevNumberOfDays__c = PrevNumberOfDays;
newContract.PrevStartDate__c = PrevStartDate;
newContract.PrevEndDate__c = PrevEndDate;
newContract.PrevNumberOfLeapYearDays__c = PrevNumberOfLeapYearDays;
newContract.Months_between_start_and_end__c = c.StartDate.monthsBetween((c.Contract_End_Date__c +1));
Integer count = 0;
NumberOfDays = StartDate.DaysBetween(EndDate)+1;
while (count < (NumberOfDays+1))
{
if(EndDate.Month() == 2 && EndDate.Day() == 29)
{
NumberOfLeapYearDays = NumberOfLeapYearDays + 1;
}
CurrentDay = EndDate.addDays(count);
if(CurrentDay.Month() == 2 && CurrentDay.Day() == 29)
{
NumberOfLeapYearDays = NumberOfLeapYearDays + 1;
}
count++;
}
newContract.NumberOfLeapYearDays2__c = NumberOfLeapYearDays;
newContract.Count__c = count;
newContract.PrevCount__c = Prevcount;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(NumberOfDays >= 365)
{
NumberOfDays = NumberOfDays + NumberOfLeapYearDays - PrevNumberOfLeapYearDays;
newContract.NewNumberOfDays__c = NumberOfDays;
newContract.NewlyCreatedNumDays__c = NumberOfDays - NumberOfLeapYearDays;
}
if(NumberOfDays < 365)
{
newContract.NewNumberOfDays__c = NumberOfDays;
newContract.NewlyCreatedNumDays__c = NumberOfDays;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - PrevNumberOfLeapYearDays
newContract.Contract_End_Date__c = c.Contract_End_Date__c.addDays((NumberOfDays));
newContract.RecordTypeId = ServiceClass.getRecordTypesNameMap('Contract').get('Maintenance Contract').Id;
newContract.Parent_Contract__c = c.id;
ContractsToInsert1.add(newContract);
for (Contract s : ContractsToInsert1) {
if (ContractsToInsertSET.add(s)) {
ContractsToInsert.add(s);
}
}}}
insert(ContractsToInsert);
List<Contract_Line_Item__c> ContractLineItemsToInsert = new List<Contract_Line_Item__c>();
String ContractId;
String AccountId;
String CaseId;
String CLIStatus;
for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert])
{
ContractId = insertedContracts.id;
AccountId = insertedContracts.AccountId;
CaseId = insertedContracts.Case__c;
CLIStatus = 'Pending';
for(Contract_Line_Item__c cc : [Select id, Maintenance_Sales_Price__c, Contract_Line_Item_Status__c, Product_LU__c, Quantity__c, List_Price__c from Contract_Line_Item__c where Id in :ContractLineItemsToClone])
{
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
newCLI.Contract_Line_Item_Status__c = CLIStatus;
newCLI.Contract__c = ContractId;
//newCLI.Case_Id__c = CaseId;
newCLI.Account__c = AccountId;
newCLI.Contract_Line_Item_Origin__c = 'Contract Clone Follow Up Contract';
newCLI.Product_LU__c = cc.Product_LU__c;
newCLI.Quantity__c = cc.Quantity__c;
newCLI.List_Price__c = cc.List_Price__c;
newCLI.Maintenance_Sales_Price__c = cc.Maintenance_Sales_Price__c;
if(cc.Contract_Line_Item_Status__c == 'Do Not Renew')
{
newCLI.Contract_Line_Item_Status__c = 'Do Not Renew';
}
if(cc.Contract_Line_Item_Status__c == 'Cancelled')
{
newCLI.Contract_Line_Item_Status__c = 'Cancelled';
}
ContractLineItemsToInsert.add(newCLI);
}}
insert(ContractLineItemsToInsert);
//update(ContractLineItemsToInsert);
}}
Changing:
StartDate = c.StartDate; to
Contract newContract = new Contract();
StartDate = c.StartDate;
newContract = new Contract();
since declare it outside of the loop
Here is the new code... Any ideas?
Public Class ContractFunctionsCloneContractAndOLIs
{
Public static void CloneMaintContractAndLineItems(Map<Id,Contract> oldMap, Map<Id,Contract> newMap)
{
List<Id> ContractToClone = new List<Id>();
List<Id> ContractLineItemsToClone = new List<Id>();
Date StartDate;
Date EndDate;
Integer NumberOfDays = 0;
Integer NumberOfMonths = 0;
Integer NumberOfYears = 0;
Double YearTerm = 0;
Integer NumberOfLeapYearDays = 0;
Integer TermsByMonth = 0;
Integer Prevcount =0;
Boolean MaintTermMisMatch;
String OriginalCase;
Date CurrentDay;
Date PrevCurrentDay;
Integer PrevNumberOfDays =0;
Date PrevStartDate;
Date PrevEndDate;
Integer CNT = 0;
Integer PrevNumberOfLeapYearDays =0;
for(Contract c : newMap.Values())
{
ContractToClone.add(c.Id);
CNT = CNT +1;
}
for(Contract_Line_Item__c CLI :[Select id from Contract_Line_Item__c where Contract__c in :ContractToClone])
{
ContractLineItemsToClone.add(CLI.id);
}
//Contract newContract = new Contract();
List<Contract> ContractsToInsert1 = new List<Contract>();
SET<Contract> ContractsToInsertSET = new SET<Contract>();
List<Contract> ContractsToInsert = new List<Contract>();
if(ContractToClone.size() > 0 && ContractLineItemsToClone.size() > 0)
{
for(Contract c : [Select id, Status, Attn_To__c, Original_Case__c, Maintenance_out_of_sync__c, NewlyCreatedNumDays__c, DateFinal__c,PrevNumberOfDays__c,
PrevStartDate__c, PrevEndDate__c, PrevNumberOfLeapYearDays__c, Term_In_Days__c, XNumberOfDays__c, AccountId, XNumberOfLeapYearDays__c, NumberOfLeapYearDays2__c,
SpecialTerms, FEndDate__c, FCompareDayEndDate__c, Total_Maintenance_Price__c,Months_between_start_and_end__c,Override_Total_Price__c,StartDate,
Contract_End_Date__c, Case__c, RecordTypeId from Contract where Id in :ContractToClone ])
{
Contract newContract = new Contract();
StartDate = c.StartDate;
PrevStartDate = c.StartDate;
PrevEndDate = c.Contract_End_Date__c;
EndDate = c.Contract_End_Date__c;
OriginalCase = c.Original_Case__c;
MaintTermMisMatch = c.Maintenance_out_of_sync__c;
PrevNumberOfDays = PrevStartDate.DaysBetween(PrevEndDate)+1;
while (Prevcount < (PrevNumberOfDays))
{
if(PrevStartDate.Month() == 2 && PrevStartDate.Day() == 29)
{
PrevNumberOfLeapYearDays = PrevNumberOfLeapYearDays + 1;
}
PrevCurrentDay = PrevStartDate.addDays(Prevcount);
if(PrevCurrentDay.Month() == 2 && PrevCurrentDay.Day() == 29)
{
PrevNumberOfLeapYearDays = PrevNumberOfLeapYearDays + 1;
}
Prevcount++;
}
newContract.SpecialTerms = c.SpecialTerms;
newContract.Override_Total_Price__c = c.Override_Total_Price__c;
newContract.Total_Maintenance_Price__c = c.Total_Maintenance_Price__c;
newContract.Status = 'Pending';
newContract.AccountId = c.AccountId;
newContract.StartDate = c.Contract_End_Date__c + 1;
newContract.Attn_To__c = c.Attn_To__c;
// newContract.Case__c = c.Case__c;
newContract.Original_Case__c = OriginalCase;
newContract.Maintenance_out_of_sync__c = MaintTermMisMatch;
newContract.PrevNumberOfDays__c = PrevNumberOfDays;
newContract.PrevStartDate__c = PrevStartDate;
newContract.PrevEndDate__c = PrevEndDate;
newContract.PrevNumberOfLeapYearDays__c = PrevNumberOfLeapYearDays;
newContract.Months_between_start_and_end__c = c.StartDate.monthsBetween((c.Contract_End_Date__c +1));
Integer count = 0;
NumberOfDays = StartDate.DaysBetween(EndDate)+1;
while (count < (NumberOfDays+1))
{
if(EndDate.Month() == 2 && EndDate.Day() == 29)
{
NumberOfLeapYearDays = NumberOfLeapYearDays + 1;
}
CurrentDay = EndDate.addDays(count);
if(CurrentDay.Month() == 2 && CurrentDay.Day() == 29)
{
NumberOfLeapYearDays = NumberOfLeapYearDays + 1;
}
count++;
}
newContract.NumberOfLeapYearDays2__c = NumberOfLeapYearDays;
newContract.Count__c = count;
newContract.PrevCount__c = Prevcount;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(NumberOfDays >= 365)
{
NumberOfDays = NumberOfDays + NumberOfLeapYearDays - PrevNumberOfLeapYearDays;
newContract.NewNumberOfDays__c = NumberOfDays;
newContract.NewlyCreatedNumDays__c = NumberOfDays - NumberOfLeapYearDays;
}
if(NumberOfDays < 365)
{
newContract.NewNumberOfDays__c = NumberOfDays;
newContract.NewlyCreatedNumDays__c = NumberOfDays;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - PrevNumberOfLeapYearDays
newContract.Contract_End_Date__c = c.Contract_End_Date__c.addDays((NumberOfDays));
newContract.RecordTypeId = ServiceClass.getRecordTypesNameMap('Contract').get('Maintenance Contract').Id;
newContract.Parent_Contract__c = c.id;
ContractsToInsert1.add(newContract);
for (Contract s : ContractsToInsert1) {
if (ContractsToInsertSET.add(s)) {
ContractsToInsert.add(s);
}
}}}
insert(ContractsToInsert);
List<Contract_Line_Item__c> ContractLineItemsToInsert = new List<Contract_Line_Item__c>();
String ContractId;
String AccountId;
String CaseId;
String CLIStatus;
for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert])
{
ContractId = insertedContracts.id;
AccountId = insertedContracts.AccountId;
CaseId = insertedContracts.Case__c;
CLIStatus = 'Pending';
for(Contract_Line_Item__c cc : [Select id, Maintenance_Sales_Price__c, Contract_Line_Item_Status__c, Product_LU__c, Quantity__c, List_Price__c from Contract_Line_Item__c where Id in :ContractLineItemsToClone])
{
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
newCLI.Contract_Line_Item_Status__c = CLIStatus;
newCLI.Contract__c = ContractId;
//newCLI.Case_Id__c = CaseId;
newCLI.Account__c = AccountId;
newCLI.Contract_Line_Item_Origin__c = 'Contract Clone Follow Up Contract';
newCLI.Product_LU__c = cc.Product_LU__c;
newCLI.Quantity__c = cc.Quantity__c;
newCLI.List_Price__c = cc.List_Price__c;
newCLI.Maintenance_Sales_Price__c = cc.Maintenance_Sales_Price__c;
if(cc.Contract_Line_Item_Status__c == 'Do Not Renew')
{
newCLI.Contract_Line_Item_Status__c = 'Do Not Renew';
}
if(cc.Contract_Line_Item_Status__c == 'Cancelled')
{
newCLI.Contract_Line_Item_Status__c = 'Cancelled';
}
ContractLineItemsToInsert.add(newCLI);
}}
insert(ContractLineItemsToInsert);
//update(ContractLineItemsToInsert);
}}
look at this code
for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert]){
.....
for(Contract_Line_Item__c cc : [Select id, Maintenance_Sales_Price__c, Contract_Line_Item_Status__c, Product_LU__c, Quantity__c, List_Price__c from Contract_Line_Item__c where Id in :ContractLineItemsToClone]){
....
ContractLineItemsToInsert.add(
newCLI);
}
}
you probable meant:
Id in :ContractLineItemsToClone
to be
id = :insertedContacts.id
though you want to do this whole thing... Calling SOQL in a loop (in this case the 2nd for loop) is bad form and under any kind of load, SFDC is going to complain
you want to go with something more like this psuedocode for these:
map<id, List<Contract_Line_Item__c>> contractToLineItem
for (Contract_Line_Item__c cc :) {
List<Contract_Line_Item__c> newList = contractToLineItem.containsKey(cc.contractID) == null ? contractToLineItem.get(cc.contractID) : new List<Contract_Line_Item__c>();
newList.add(cc)
contractToLineItem.put(cc.contractID, newList)
}
for Contracts insertedContracts : insertedContracts {
for contract_line_items : contractToLineItem.get(insertedContracts.id) {
<do cloning>
}
}
that way you get the list 1 instead of making x number of database calls to get that same list.
You'll want to check out this: https://developer.salesforce.com/page/Apex_Code_Best_Practices
add
map<id, contract> originalContractMap = new map<id, contract>; //"source" id -> "source" contract
map<id, contract> originalToCloneMap = new map<id, contract>;;//"source" id -> "clone" contract
....
if (ContractsToInsertSET.add(s)) {
originalContractMap.put(c.id, c); //add this
originaltoCloneMap.put(c.id, s); //add this
ContractsToInsert.add(s);
}
...
insert(ContractsToInsert); //the key thing to now here is now is everything in originaltoclonemap.values() now has the id field appened as a result of the insert
....
//change
//for(Contract insertedContracts : [Select Id, Case__c, AccountId from Contract where id in :ContractsToInsert])
// {
//to
for (id originalID : originalContractMap.keyset()){
Contract srcContract = originalContractMap.get(originalID);//has all the fields of the original contract query
Contract clonedContract = originaltoCloneMap.get(originalID);//has all the fields that were in the insert + the id field due to the insert
this should get you going in the right directions.
Trigger ContractTriggerCreatContractAndOLIs on Contract (after update)
{
map<id, contract> originalToCloneMap = new map<id, contract>();
Date StartDate;
Date EndDate;
String cAccountid;
String cContractId;
String cParentId;
List<Contract> ContractsToClone = [Select id, Parent_Contract__c, Status, Attn_To__c, Original_Case__c, Maintenance_out_of_sync__c, NewlyCreatedNumDays__c, DateFinal__c,PrevNumberOfDays__c,
PrevStartDate__c, PrevEndDate__c, PrevNumberOfLeapYearDays__c, Term_In_Days__c, XNumberOfDays__c, AccountId, XNumberOfLeapYearDays__c, NumberOfLeapYearDays2__c,
SpecialTerms, FEndDate__c, FCompareDayEndDate__c, Total_Maintenance_Price__c,Months_between_start_and_end__c,Override_Total_Price__c,StartDate,
Contract_End_Date__c, Case__c, RecordTypeId
from Contract where Test_Contract_Clone__c = TRUE and Processed_Renewal_Contract__c = False and Id in :Trigger.newMap.keySet()];
List<Contract> ContractsToInsert = new List<Contract>();
Contract newContract = new Contract();
for(Contract c: ContractsToClone)
{
NewContract = new Contract();
NewContract.StartDate = Date.Today();
NewContract.Contract_End_Date__c = Date.Today();
NewContract.Status = 'Pending';
NewContract.Accountid = c.AccountId;
NewContract.RecordTypeId = c.RecordTypeId;
NewContract.Parent_Contract__c = c.id;
originaltoCloneMap.put(c.id, NewContract);
ContractsToInsert.add(NewContract);
}
Insert ContractsToInsert;
List<Contract_Line_Item__c> CLIsToInsert = new List<Contract_Line_Item__c>();
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
for(id originalId: originaltoCloneMap.keyset()){
newCLI.Contract__c = originaltoCloneMap.get(originalId);
newCLI.Product_LU__c = originalid.Product_LU__c;
newCLI.Quantity__c = originalid.Quantity__c;
CLIsToInsert.add(NewCLI);
}
insert CLIsToInsert;
}
What's the issue you're having?
one thing that pops out is this:
newCLI.Contract__c = originaltoCloneMap.get(originalId);
should be
newCLI.Contract__c = originaltoCloneMap.get(originalId).id;
this
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
should be in the for loop.
and it doesn't look like you have anything that's processing the CLIs. You need to get all the CLIs and map them to a original contact ID (map<id, List<ContactrLineItems>>)
What you want to do is something like this
map<id, contract> originaltoCloneMap;
for(Contract c: ContractsToClone){
//clone contract
originaltoCloneMap.put(c.id, newContract);
contractsToClone.add(newContract);
}
insert contractToClone; //the thing to know here is that now that it is inserted, the completed ID is now in all the Contract Objectss in orginalToCloneMap
..
for ( ContratcLineItem origCLI : [Select ... from contractline item where contract__c in :originalToCloneMap.keyset()){
ContractLineItem newCLI = new ContractLineItem();
newCli.Contract__c = originalToCloneMap.get(origCLI.contract__c).id;//this is valid because the insert updated all the IDs of the contract objects in the map
....
}
...
The code has a bit of an issue, when I update in a batch greater than one using this trigger a collection of all line items across every contract in the batch gets created under each contract. Like if I have five line items under four different contracts when I use the following code each contract created has 20 line items. any ideas???
Trigger ContractTriggerCreatContractAndOLIs on Contract (after update)
{
map<id, contract> originalToCloneMap = new map<id, contract>();
map<id, contract> originalContractMap = new map<id, contract>();
Date StartDate;
Date EndDate;
String cAccountid;
String cContractId;
String cParentId;
List<Contract> ContractsToClone = [Select id, Parent_Contract__c, Status, Attn_To__c, Original_Case__c, Maintenance_out_of_sync__c, NewlyCreatedNumDays__c, DateFinal__c,PrevNumberOfDays__c,
PrevStartDate__c, PrevEndDate__c, PrevNumberOfLeapYearDays__c, Term_In_Days__c, XNumberOfDays__c, AccountId, XNumberOfLeapYearDays__c, NumberOfLeapYearDays2__c,
SpecialTerms, FEndDate__c, FCompareDayEndDate__c, Total_Maintenance_Price__c,Months_between_start_and_end__c,Override_Total_Price__c,StartDate,
Contract_End_Date__c, Case__c, RecordTypeId
from Contract where Test_Contract_Clone__c = TRUE and Processed_Renewal_Contract__c = False and Id in :Trigger.newMap.keySet()];
//List<id> Parent_ContractIds = new List<id>();
//Contract_Line_Item__c newCLI =
List<Contract> ContractsToInsert = new List<Contract>();
Contract newContract = new Contract();
for(Contract c: ContractsToClone)
{
NewContract = new Contract();
NewContract.StartDate = Date.Today();
NewContract.Contract_End_Date__c = Date.Today();
NewContract.Status = 'Pending';
NewContract.Accountid = c.AccountId;
NewContract.RecordTypeId = c.RecordTypeId;
NewContract.Parent_Contract__c = c.id;
originaltoCloneMap.put(c.id, NewContract);
ContractsToInsert.add(NewContract);
}
Insert ContractsToInsert;
// List<Contract_Line_Item__c> ContractCLIToClone = [Select Contract__c, List_Price__c, Product_LU__c, Quantity__c, Account__c from Contract_Line_Item__c where Contract__c in :ContractsToClone order by Contract__c];
Contract_Line_Item__c newCLI = new Contract_Line_Item__c();
for(id originalId: originaltoCloneMap.keyset())
{
List<Contract_Line_Item__c> CLIsToInsert = new List<Contract_Line_Item__c>();
// for(Contract_Line_Item__c cc:ContractCLIToClone)
for(Contract_Line_Item__c cc :[Select Contract__c, List_Price__c, Product_LU__c, Quantity__c, Account__c from Contract_Line_Item__c where Contract__c in :originalToCloneMap.keyset()])
{
newCLI = new Contract_Line_Item__c();
newCLI.Contract__c = originaltoCloneMap.get(originalId).id;
newCLI.Product_LU__c = '01t7000000170yy';
newCLI.List_Price__c = cc.List_Price__c;
newCLI.Product_LU__c = cc.Product_Lu__c;
newCLI.Quantity__c = cc.Quantity__c;
newCLI.Account__c = cc.Account__c;
newCLI.Contract_Line_Item_Origin__c = 'Contract Clone Follow Up Contract';
CLIsToInsert.add(newCLI);
}
insert CLIsToInsert;
}
}
{//delete
List<Contract_Line_Item__c> CLIsToInsert = new List<Contract_Line_Item__c>();
// for(Contract_Line_Item__c cc:ContractCLIToClone)
for(Contract_Line_Item__c cc :[Select Contract__c, List_Price__c, Product_LU__c, Quantity__c, Account__c from Contract_Line_Item__c where Contract__c in :originalToCloneMap.keyset()])
{
newCLI = new Contract_Line_Item__c();
newCLI.Contract__c = originaltoCloneMap.get(originalId).id;
newCLI.Product_LU__c = '01t7000000170yy';
newCLI.List_Price__c = cc.List_Price__c;
newCLI.Product_LU__c = cc.Product_Lu__c;
newCLI.Quantity__c = cc.Quantity__c;
newCLI.Account__c = cc.Account__c;
newCLI.Contract_Line_Item_Origin__c = 'Contract Clone Follow Up Contract';
CLIsToInsert.add(newCLI);
}
insert CLIsToInsert;
}//delete
You don't need the outter for loop (the stuff in bold) so delete that. It's what's causing the extra records. You are also not remapping the newCLI.contract correctly.
then change this line
newCLI.Contract__c = originaltoCloneMap.get(originalId).id;
to this
newCLI.Contract__c = originaltoCloneMap.get(cc.Contract).id;//this is why you created the originalToCloneMap so you could cross reference it in the loop based on the CLI to be cloned (cc)
I thing to know here is that since it is embedded and just download the Onedrive app, sync and use DuplicateFilesDeleter to find and remove duplicates.
Thanks