You need to sign in to do that
Don't have an account?
Kelly K
Dynamically assign values to multiple generic fields and use 1 DML statement
Hi All,
This article has been helpful on getting me started: http://salesforce.stackexchange.com/questions/4193/update-a-records-using-generic-fields
For my application I'm trying update several fields on a contract based on the products that are selected on an opportunity. I'm using a crosswalk object that has information on which field to update and with what kind of value. Here's a snippet of the code I'm working with and I know it works:
//Update Opportunity Products & Opportunity
for(Opportunity opportunity : opportunitiesMap.values()) {
//Update Opportunity with Contract Number
Opportunity opportunityForUpdate = new Opportunity(Id = opportunity.Id, Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id);
opportunitiesToUpdate.add(opportunityForUpdate);
//Update Opportunity Products with Contract Number
for(OpportunityLineItem oppProduct : opportunitiesToProductsMap.get(opportunity.Id)) {
oppProduct.Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id;
productsToUpdate.add(oppProduct);
for(Product_to_Contract_Matrix__c p2cm : productsToMatrixMap.get(oppProduct.PriceBookEntry.Product2Id)) {
Schema.SObjectField currentField = contractFields.get(p2cm.Contract_Field_to_Update__c);
Contract contract = new Contract(Id = opportunityToContractMap.get(opportunity.Id).Id);
if(p2cm.Update_Type__c == 'Text')
contract.put(currentField, p2cm.Update_Value_With__c);
else if(p2cm.Update_Type__c == 'Date')
contract.put(currentField, system.today());
else if(p2cm.Update_Type__c == 'Rate (String)')
contract.put(currentField, String.valueOf(oppProduct.UnitPrice));
else if(p2cm.Update_Type__c == 'Rate (Numeric)')
contract.put(currentField, oppProduct.UnitPrice);
//contractsToUpsert.put(contract.Id, contract);
upsert contract;
}
}
}
Problem is that the DML statement to update the contract is 3 for loops in and can potentially end up updating upwards of 30 to 50 fields for one contract record - easily hitting governor limits. I tried assigning it to a list as you can see with the commented out line just above, but I found that I using this method overwrites the previous field update in the loop.
Does anyone have any thoughts on how I can modify my code to where I only need 1 DML statement and still apply all the updates to my contract record?
Much appreciated!
This article has been helpful on getting me started: http://salesforce.stackexchange.com/questions/4193/update-a-records-using-generic-fields
For my application I'm trying update several fields on a contract based on the products that are selected on an opportunity. I'm using a crosswalk object that has information on which field to update and with what kind of value. Here's a snippet of the code I'm working with and I know it works:
//Update Opportunity Products & Opportunity
for(Opportunity opportunity : opportunitiesMap.values()) {
//Update Opportunity with Contract Number
Opportunity opportunityForUpdate = new Opportunity(Id = opportunity.Id, Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id);
opportunitiesToUpdate.add(opportunityForUpdate);
//Update Opportunity Products with Contract Number
for(OpportunityLineItem oppProduct : opportunitiesToProductsMap.get(opportunity.Id)) {
oppProduct.Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id;
productsToUpdate.add(oppProduct);
for(Product_to_Contract_Matrix__c p2cm : productsToMatrixMap.get(oppProduct.PriceBookEntry.Product2Id)) {
Schema.SObjectField currentField = contractFields.get(p2cm.Contract_Field_to_Update__c);
Contract contract = new Contract(Id = opportunityToContractMap.get(opportunity.Id).Id);
if(p2cm.Update_Type__c == 'Text')
contract.put(currentField, p2cm.Update_Value_With__c);
else if(p2cm.Update_Type__c == 'Date')
contract.put(currentField, system.today());
else if(p2cm.Update_Type__c == 'Rate (String)')
contract.put(currentField, String.valueOf(oppProduct.UnitPrice));
else if(p2cm.Update_Type__c == 'Rate (Numeric)')
contract.put(currentField, oppProduct.UnitPrice);
//contractsToUpsert.put(contract.Id, contract);
upsert contract;
}
}
}
Problem is that the DML statement to update the contract is 3 for loops in and can potentially end up updating upwards of 30 to 50 fields for one contract record - easily hitting governor limits. I tried assigning it to a list as you can see with the commented out line just above, but I found that I using this method overwrites the previous field update in the loop.
Does anyone have any thoughts on how I can modify my code to where I only need 1 DML statement and still apply all the updates to my contract record?
Much appreciated!
//Update Opportunity Products & Opportunity
for(Opportunity opportunity : opportunitiesMap.values()) {
//Update Opportunity with Contract Number
Opportunity opportunityForUpdate = new Opportunity(Id = opportunity.Id, Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id);
opportunitiesToUpdate.add(opportunityForUpdate);
//Update Opportunity Products with Contract Number
for(OpportunityLineItem oppProduct : opportunitiesToProductsMap.get(opportunity.Id)) {
oppProduct.Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id;
productsToUpdate.add(oppProduct);
Contract contract = new Contract(Id = opportunityToContractMap.get(opportunity.Id).Id);
for(Product_to_Contract_Matrix__c p2cm : productsToMatrixMap.get(oppProduct.PriceBookEntry.Product2Id)) {
Schema.SObjectField currentField = contractFields.get(p2cm.Contract_Field_to_Update__c);
if(p2cm.Update_Type__c == 'Text')
contract.put(currentField, p2cm.Update_Value_With__c);
else if(p2cm.Update_Type__c == 'Date')
contract.put(currentField, system.today());
else if(p2cm.Update_Type__c == 'Rate (String)')
contract.put(currentField, String.valueOf(oppProduct.UnitPrice));
else if(p2cm.Update_Type__c == 'Rate (Numeric)')
contract.put(currentField, oppProduct.UnitPrice);
contractsToUpsert.put(contract.Id, contract);
//upsert contract;
}
}