-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
7Questions
-
12Replies
Traversing XML Trees using Apex
HI I'm trying top traverse an XML tree to get the Items Tag list. I was using iterative but the problem is that it seems that I can only get the lst item but I don;t get them all. Can someone p0leaswe help me? Thanks Here's the tree:
<Shipment id="103052074">
<ClientName>Awana</ClientName>
<OrderID>01061767</OrderID>
<PurchaseOrder />
<Name>SILVIA GIBSON</Name>
<FirstName>SILVIA</FirstName>
<LastName>GIBSON</LastName>
<Company />
<Address1>11900 TRADITION LN NE </Address1>
<Address2 />
<City>ALBUQUERQUE</City>
<State>NM</State>
<PostalCode>87111-8287</PostalCode>
<Country>UNITED STATES</Country>
<Email>silviagibson@mailinator.com</Email>
<Phone />
<OrderTimestamp>2019-01-18T00:00:00</OrderTimestamp>
<ReceivedTimestamp>2019-01-18T13:59:26.007</ReceivedTimestamp>
<ShipmentStatus>SHIPPED</ShipmentStatus>
<OrderType>Consumer</OrderType>
<ShippedDate>2019-01-18T14:16:37.550</ShippedDate>
<ExpectedDeliveryDate>2019-01-18T00:00:00</ExpectedDeliveryDate> <DeliveredTimestamp /> <DeliveryException />
<Warehouse id="160">
<Name>Greenwood, IN</Name>
<Address>1415 Collins Rd.</Address>
<City>Greenwood</City>
<State>IN</State>
<PostalCode>46143</PostalCode>
<Country>US</Country>
</Warehouse>
<ShipMethod>Newgistics Parcel Select</ShipMethod>
<ShipMethodCode>NGSPS</ShipMethodCode>
<Tracking>9200000000000629213249</Tracking> <TrackingUrl>http://shipment.co/tracking/2817/9200000000000629213249</TrackingUrl>
<Weight>4.000000</Weight>
<Postage />
<GiftWrap>false</GiftWrap>
<CustomFields>
<BillingAddress1>1620 N Penny Ln</BillingAddress1>
<BillingCity>Schaumburg</BillingCity>
<BillingCompany>Cherry Hills Community Church</BillingCompany>
<BillingCountry>United States</BillingCountry>
<BillingEmail>silviagibson@mailinator.com</BillingEmail>
<BillingFirstName>Heather</BillingFirstName>
<BillingLastName>Oliver</BillingLastName>
<BillingPhone>(866) 292-6227</BillingPhone>
<BillingState>IL</BillingState>
<BillingZip>60173</BillingZip>
<Shipping>17.87</Shipping>
<Total>190.52</Total>
</CustomFields>
<BackorderedItems />
<Items>
<Item id="1807577">
<SKU>94900</SKU>
<UPC />
<Description>Cubbies AppleSeed Handbook Music CD NIV</Description>
<Lot />
<Qty>2</Qty>
<CustomFields />
<AssemblyItems />
</Item>
<Item id="1807606">
<SKU>96543</SKU>
<UPC />
<Description>Cubbies HoneyComb Teaching Plans NKJV</Description>
<Lot />
<Qty>1</Qty>
<CustomFields />
<AssemblyItems />
</Item>
<Item id="1807670">
<SKU>96918</SKU>
<UPC />
<Description>Game Pin (4)</Description>
<Lot />
<Qty>4</Qty>
<CustomFields />
<AssemblyItems />
</Item>
<Item id="1807691">
<SKU>46421</SKU>
<UPC />
<Description>Gray Blouse, Leader Size 4X</Description> <Lot />
<Qty>3</Qty> <CustomFields />
<AssemblyItems />
</Item>
</Items>
<Packages>
<Package id="86892375">
<TrackingNumber>9200000000000629213249</TrackingNumber>
<Weight>4.30507</Weight>
<BillableWeight>4.00000</BillableWeight>
<Height>7.00000</Height>
<Width>4.00000</Width>
<Depth>6.00000</Depth>
</Package>
</Shipment>
-
- Tony Williams 9
- January 19, 2019
- Like
- 0
Polling and external web service every few hours
HI our company is doing order fulfillment using a remote warehouse.
I have created code to upload the orders to the Warehous's remote web service via HTTP Callout but I need to know:
Q) How can we create a batchable like Class that just polls the web service for results via GET every few hours?
I really don't need to use the database.querylocator start(Database.BatchableContext BC) method to batch load objects for the execute(Database.BatchableContext BC, List<scope> scope).
Thanks
I have created code to upload the orders to the Warehous's remote web service via HTTP Callout but I need to know:
Q) How can we create a batchable like Class that just polls the web service for results via GET every few hours?
I really don't need to use the database.querylocator start(Database.BatchableContext BC) method to batch load objects for the execute(Database.BatchableContext BC, List<scope> scope).
Thanks
-
- Tony Williams 9
- December 13, 2018
- Like
- 0
Problem when attempting to Activate Scheduled Actions in Process Builder
I created a Process BUilder that consolidates several processes based on the Acocunt object. All the processes within this consolidated process builder works fine except when I add a new process that fires off a Scheduled Action as the las process in the list. When I add this process the Activate button turns gray and I can no longer click on it to activate the consolidated process.
Does anyone know what I could be doing incorrectly with this scheduled action? I did make sure that I placed this as the last process in the lis t. Thanks
Does anyone know what I could be doing incorrectly with this scheduled action? I did make sure that I placed this as the last process in the lis t. Thanks
-
- Tony Williams 9
- November 05, 2018
- Like
- 0
VF Page Component Error: The dependent picklist 'Card Type' requires its controlling field 'Payment Method' to be present on the page.
I have enabled Payment Method picklist in my org . The dependent picklisst is called CardType. I am using thee two inputfields within a form inside of a VF Page Component called ForAddressVerfication. The component is embedded in the Visual Force Page called OrderEntry4. When this page loads it tries to pull in the compoennt and I get this error: "The dependent picklist 'Card Type' requires its controlling field 'Payment Method' to be present on the page."
===========VF Page Component: ForAddressVerification =================
<!-- <apex:form > -->
<div id="SelectAddressDetail" style="display:none;"> <!-- Removing this will give us SmartyStreets Verify -->
<apex:form >
<div id="AddCreditCardInput" class="credit-card-input" style="display:none;">
<h1>Enter and Save</h1><br/>
<h1>Credit Card Information</h1><br/><br/>
<div class="two-pixel-padding">
<label class="top-label"> Name on Credit Card</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardName" maxlength='30' />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Credit Card Type</label><span class="required">*</span><br />
<apex:inputfield value="{!Order.Chargent_Order__r.ChargentOrders__Card_Type__c}" id="AddCreditCardType" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Credit Payment Method</label><span class="required">*</span><br />
<apex:inputfield value="{!Order.Chargent_Order__r.ChargentOrders__Payment_Method__c}" id="AddPaymentMethod" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Number (16 digits)</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardNumber" maxlength="16" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Month (MM)</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardMonth" maxlength="2" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Year (YYYY)</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardYear" maxlength="4" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Security (XXX)</label><br />
<input type="text" id="AddCreditCardSecurity" maxlength="4" />
</div>
</div>
<div id="AddressInput" class="address-input" style="display:block;">
<h1>Enter or Select Address Information</h1><br/><br/>
<div><input type="hidden" id="SelectAddressType" /></div>
<div id="SelectAddressLoading" style="text-align:center;"></div>
<div id="SelectAddressList" >
<table id="SelectAddressListTable" cellpadding="3px" class="select-address-table" />
</div>
<div id="AddAddressInput" style="display:block;">
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> First Name</label><br />
<input type="text" id="AddAddressFirstName" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Last Name</label><span class="required">*</span><br />
<input type="text" id="AddAddressLastName" />
</div>
</div><br/>
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> Address Line One</label><span class="required">*</span><br />
<input type="text" id="AddAddressLineOne" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Address Line Two</label><br />
<input type="text" id="AddAddressLineTwo" />
</div>
</div><br/>
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> City</label><br />
<input type="text" id="AddAddressCity" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> State</label><br />
<input type="text" id="AddAddressState" maxlength="2" size="2" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Zip Code</label><span class="required">*</span><br />
<input type="text" id="AddAddressZipCode" maxlength="10" size="10" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> </label><br />
<input type="button" id="VerifyAddress" value="Verify" style="cursor:pointer;width:50px;height:30px;" onclick="showSaveButton();"/>
</div>
</div><br/>
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> County</label><br />
<input type="text" id="AddAddressCounty" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Country</label><br />
<select id="AddAddressCountry" style="width:200px;">
<option selected="selected">UNITED STATES</option>
</select>
</div>
<div><input type="hidden" id="AddAddressId"/></div>
</div><br/>
</div>
</div>
</apex:form>
============== Order Entry Page Segment =======================
<apex:pageBlockSectionItem >
<apex:outputLabel value="Shipping Address: " for="OrderShippingAddress" id="OrderShippingAddressLabel" />
<div id="OrderShippingAddressDetail" style="display:none;">
<span id="OrderShippingAddressFirstName"></span>
<span id="OrderShippingAddressLastName"></span><br/>
<span id="OrderShippingAddressLineOne"></span><br/>
<span id="OrderShippingAddressLineTwo"></span><br/>
<span id="OrderShippingAddressCity"></span>
<span id="OrderShippingAddressState"></span>
<span id="OrderShippingAddressZip"></span><br/>
<span id="OrderShippingAddressCounty"></span><br/>
<span id="OrderShippingAddressCountry"></span><br/>
</div>
<input type="button" style="cursor:pointer;" id="OrderShippingAddressChangeLink"
onclick="openSelectAddressDialog('Shipping');" value="Change Shipping Address" />
</apex:pageBlockSectionItem>
<c:ForSSAddressVerification Order="{!Order}"/>
</apex:pageBlockSection>
-
- Tony Williams 9
- September 05, 2018
- Like
- 0
Avalara for SF: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
Hi I'm working on the integration between AvaTax and our billing system, using the Salesforce Api.
We have changed to a newSalesforce Organization and are attempting to calculate tax on orders for Canadian customers. This has worked well on other Sandboxes we have tried.
Is there a reliable way to know why the parametr is not working when sending the Http Request?
I am noticing that for this new Sandbox org we are reciving this message when calculating the tax (See log file segment below) Thanks:
The Apex code that makes the call out to Avalara is this:
The AvalaraTaxJSON object looks like this:
We have changed to a newSalesforce Organization and are attempting to calculate tax on orders for Canadian customers. This has worked well on other Sandboxes we have tried.
Is there a reliable way to know why the parametr is not working when sending the Http Request?
I am noticing that for this new Sandbox org we are reciving this message when calculating the tax (See log file segment below) Thanks:
DEBUG|{"type":"SalesOrder","lines":[\{"quantity":1.00,"itemCode":"43490","description":"Freight","number":"1","amount":0.00},\{"quantity":1.00,"itemCode":"79345","description":"Puggles Backpack","number":"2","amount":4.1677967793}],"customerCode":"4","companyCode":"awana1","code":"988103","date":"2018-04-25 10:29:52","commit":"false","addresses":{"ShipTo":{"region":"BC","postalCode":"V4P 1H5","line1":"2430 King George Blvd Ste 101","country":null,"city":"Surrey"},"ShipFrom":{"region":"IL","postalCode":"60173","line1":"1620 N Penny Ln","country":"US","city":"Schaumburg"}}}
10:29:51.0 (36237563)|CALLOUT_REQUEST|[1747]|System.HttpRequest[Endpoint=callout:AvalaraTax, Method=POST]
10:29:51.0 (40289120)|EXCEPTION_THROWN|[1747]|System.UnexpectedException: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
10:29:51.0 (40477323)|FATAL_ERROR|System.UnexpectedException: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
The Apex code that makes the call out to Avalara is this:
webservice static Result CalculateTaxOnOpportunity(string OrderId)
{
decimal TaxAmount = null;
// Try to
try
{
// Convert the OpportunitySalesforceId argument provided to a Salesforce ID
ID TempId = OrderId;
// If converting fails, return failure and an error message.
} catch(Exception ex) { return new Result(false,'Please supply a valid Order (15 or 18 character) Salesforce Id. Error Message: '+ex.getMessage()); }
try
{
// Initialize the tax variable to zero.
TaxAmount = 0;
AvalaraTaxJSON Obj = new AvalaraTaxJSON(OrderId);
if(Obj.companyCode != null || Obj.companyCode !='') {
string jsonData = JSON.serialize(Obj);
jsonData = jsonData.replace('AvalaraCurrentDataTime','date');
jsonData = jsonData.replace('Avalara_Commit','commit');
jsonData = jsonData.replaceAll('Avalara_SeqNumber','number');
system.debug(jsonData);
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AvalaraTax');
req.setBody(jsonData);
req.setHeader('Content-Type','application/json');
req.setMethod('POST');
HttpResponse res = h.send(req);
system.debug(res.getBody());
JSONParser parser = JSON.createParser(res.getBody());
while (parser.nextToken() != null) {
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'totalTax')) {
parser.nextToken();
TaxAmount = parser.getDecimalValue();
}
}
return new Result(true,'Success, tax amount calculated',TaxAmount);
}
else
return new Result(false,'The Order must have a valid Shipping Country before calculating tax OR Country must be United States Or Canada');
}
// If an error occurred getting tax
catch (Exception ex)
{
// Return failure and an error message.
return new Result(false,'An error occurred when getting tax from the tax system. Error:'+ex.getMessage());
}
// Otherwise, return Success as true and the Tax Amount calculated by the tax web service.*/
return new Result(true,'Success, tax amount calculated',TaxAmount);
}
The AvalaraTaxJSON object looks like this:
public class AvalaraTaxJSON {
string code;
public string companyCode{get;set;}
string type;
string AvalaraCurrentDataTime;
string customerCode;
string Avalara_Commit;
address addresses;
list<lineItem> lines;
public class address{
public AddressCls ShipFrom;
public AddressCls ShipTo;
}
public class AddressCls{
string line1;
string city;
string region;
string country;
string postalCode;
public AddressCls(string line, string city, string reg, string country, string zipCode){
this.line1 = line;
this.city = city;
this.region = reg;
this.country = country;
this.postalCode = zipCode;
}
}
public class lineItem{
public string Avalara_SeqNumber;
public decimal quantity;
public decimal amount;
public string description;
public string itemCode;
public lineItem(string num,decimal qunt, decimal amt,string itemCode, string des){
this.Avalara_SeqNumber = num;
this.quantity = qunt;
this.amount =amt;
this.description = des;
this.itemCode = itemcode;
}
}
public AvalaraTaxJSON(string orderId){
string isoCode;
//Constructing JSON with OrderLine Items
lines = new list<LineItem>();
list<Order> orderLst = [SELECT ID, Name,Shipping_Street__c, Shipping_City__c,Shipping_State__c, Shipping_Zip_Code__c, Shipping_Country__c, TempOrderNumber__c, LastModifiedById, Error_Log__c,Account.IntacctID__c, Company__c,
(SELECT Line_Type__c, PricebookEntry.Product2Id, PricebookEntry.Product2.ProductCode, PricebookEntry.Product2.Name, Quantity, TotalPrice, Quantity_Given_Away__c FROM Order.OrderItems) FROM Order WHERE ID = :string.escapeSingleQuotes(orderId)];
if(orderLst!=null&& orderLst.size()>0){
Order Ord= orderLst.get(0);
if(Ord.Shipping_Country__c!=null && Ord.Shipping_Country__c.toLowerCase().contains('united states') || Ord.Shipping_Country__c.toLowerCase().contains('canada')){
list<Country__c> countryObj = [SELECT ISO_Code__c FROM Country__c WHERE Name = :Ord.Shipping_Country__c];
if(countryObj!=null && countryObj.size()>0){
isoCode = countryObj.get(0).ISO_Code__c;
}
Awana_Settings__c custSetting = Awana_Settings__c.getValues('AvalaraTaxCompany');
if(custSetting!=null)
this.companyCode = custSetting.value__c;
else
this.companyCode = 'awana1-sb2'; //default value
this.code = Ord.TempOrderNumber__c;
this.customerCode = Ord.Account.IntacctID__c;
this.type = 'SalesOrder';
this.AvalaraCurrentDataTime = String.valueOf(system.now());
this.Avalara_Commit = 'false';
addresses = new address();
addresses.ShipFrom = new AddressCls('1620 N Penny Ln','Schaumburg','IL','US','60173'); //Default Address Present in Cast iron
addresses.ShipTo = new AddressCls(Ord.Shipping_Street__c,Ord.Shipping_City__c,Ord.Shipping_State__c,isoCode,Ord.Shipping_Zip_Code__c);
integer itr =1;
for(OrderItem oli : Ord.OrderItems){
lines.add(new LineItem(string.valueOf(itr),oli.Quantity,Oli.TotalPrice,oli.PricebookEntry.Product2.ProductCode,oli.PricebookEntry.Product2.Name));
itr++;
}
}
}
}
}
-
- Tony Williams 9
- April 25, 2018
- Like
- 0
DML Limit 10000 Reached While Processing 9455 Account Team Objects
HI I am running a batch scirpt that has up to 9455 accounts. I need to update their acoucnt objects. The problem is that I have code that has to insert 3 Account Team Members per each Account record that is being iterated or 3 DML * 9455 = 28.365K. The Account Team Objects being updated don;t have any triggers that do any firing.
Q) How can I avoid this "DML Limit of 10000" issue?
Q) Should I increasemy batch limit? Currently this is what I am using: Database.executeBatch(job, 10);
Here is the code and Thanks.:
Q) How can I avoid this "DML Limit of 10000" issue?
Q) Should I increasemy batch limit? Currently this is what I am using: Database.executeBatch(job, 10);
Here is the code and Thanks.:
BATCH:
===================================================================
global class BatchUpdateAccountTeams implements Database.Batchable<sObject>,Database.AllowsCallouts, Database.Stateful {
global String query;
global Integer accountSize = 0;
List<Account> accountsToUpdate = new List<Account>();
global class UtilException extends Exception {}
global database.querylocator start(Database.BatchableContext BC){
//*****************************************************************************************************************************************************************************p
//Select All active US Accounts that have counties and states
//NOTE: You don't need to get all Physical address components just the city and state.
//*****************************************************************************************************************************************************************************
if(query == null)
{
query
= 'Select Id,Mailing_Address_Book__c,Physical_County__c,Physical_State__c '
+ ' From Account WHERE Status__c = \'Added\' '
+ ' And Physical_County__c <> null '
+ ' And Physical_State__c <> null '
+ ' And Registration_Level__c = \'R1\''
+ ' And Type = \'Church\''
+ ' And RecordType.Name like \'%US Organization%\' limit 10000';
}
system.debug('<< QUERY >> '+query);
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope){
List<Id> accountIDs = new List<Id>();
//List<RecordType> rec = [Select Id from RecordType where Name = 'US Organization' Limit 1];
//1. Get access to all Active US Organizations having Physical counties and states.
for(sObject s : scope){
Account thisAccount = (Account)s;
accountsToUpdate.add(thisAccount);
accountIDs.add(thisAccount.Id);
accountSize++;
}
//accountSize = accountsToUpdate.size();
system.debug('<< Max Accounts found>> '+accountSize);
//2. Update The Account Teams for these accounts with the most recent account team personnel including VP of US Missionaries
if(accountsToUpdate.size() > 0){
TeamMemberAccounts.handler(accountsToUpdate,accountIDs);
TeamMemberAccounts.handler(accountsToUpdate);
}
}
global void finish(Database.BatchableContext BC){
List<Messaging.SingleEmailMessage> emailList = new List<Messaging.SingleEmailMessage>();
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
//Send email to all in Account Teams Updates Group if any account team member objects were created/updated
if(accountSize > 0){
//3. Get User Ids for the Acocunt Team Updates Group.
Map<Id,User> users = new Map<Id, User>([SELECT Id, Email FROM User WHERE Id IN (
SELECT UserOrGroupId FROM GroupMember WHERE Group.Name = 'Account Team Updates')]);
List<String> userEmail = new List<String>();
//We need to make sure that the Test coverage will work when testing emails otherwise a REQUIRED_FIELD_MISSING, Missing exception will occur.
if(Test.isRunningTest()){
User tUser=[Select Email from User where Name Like 'MyAwana%' Limit 1];
userEmail.add(tUser.Email);
}else{
for(User someUser : users.values()){
userEmail.add(someUser.Email);
}
}
List<String> sendTo = new List<String>();
sendTo.addAll(userEmail);
//4. Assign the addresses for the To and CC lists to the mail object.
mail.setToAddresses(sendTo); // Specify the subject line for your email address.
//5. Set to True if you want to BCC yourself on the email.
mail.setBccSender(false);
//6.: Set who the email is sent from
mail.setReplyTo('noreply@awana.org');
mail.setSenderDisplayName('No Reply');
//7. Set email contents !
mail.setSubject('Accounts Process with Updated or New Account Teams');
String lines = '<br>';
Integer lineCounter = 0;
Integer lineLimit = 20;
for(Account an_account : accountsToUpdate){
lines = lines+an_account.Mailing_Address_Book__c+', ';
lineCounter++;
if(lineCounter == lineLimit - 1){
lines = lines+'<br>';
}
if(lineCounter == lineLimit){
lineCounter=0;
}
}//loop
system.debug('<<LINES>> '+lines);
mail.setHtmlbody('Total Accounts Processed:<b> '+ accountSize+'</b><br>'+lines+'</b><br>');
// Send the email you have created.' '+
emailList.add(mail);
Messaging.sendEmail(emailList);
}
}
}
====================== TEAM MEMBER ACCOUNTS.CLS==================
public with sharing class TeamMemberAccounts {
/*
* Method: handleOpportunityInsert
* Inputs: List of Accounts which have ownership updates to be matched with their ATMs (Account Team Member)
* Purpose: To verify that we will have a State Director whether due to updating the ATM or creating a new one.
* SOQL: 1
* DML: 2
*/
public class handlerException extends Exception{}
/***************************************************************************************************************************************************
Method: handler: Makes sure that Primary Missionaries are assigned as Account Team Memebrs programmatically
****************************************************************************************************************************************************/
public static void handler(List<Account> Accts,List<ID> acctIDS){
List<AccountTeamMember> insert_ATM_FieldDirs = new List<AccountTeamMember>();
List<AccountTeamMember> insert_ATM_WGroupLdrs = new List<AccountTeamMember>();
List<AccountTeamMember> insert_ATM_PMissions = new List<AccountTeamMember>();
List<Id> ownerIDs = new List<Id>();
Boolean foundStateDir = false;
// Old ATM Roles must go because we don't know how if these users are still available.
List<AccountTeamMember> delete_ATMS = [Select AccountID,UserId,TeamMemberRole from AccountTeamMember WHERE TeamMemberRole in ('Field Director','Work Group Leader','Primary Missionary') and AccountId in : acctIDs];
if(delete_ATMS.size() > 0){
delete delete_ATMS;
}
system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries());
//For each account selected go and get the Account Team Mebmers while updating the account owner.
List<US_Counties__c> uscs = [Select Name,State_Name__c,Field_Director__c, Work_Group_Leader__c, Primary_Missionary__c from US_Counties__c ORDER BY State_Name__c, Name Asc];
Map<String,List<US_Counties__c>> usCounties = new Map<String,List<US_Counties__c>>();
for(US_Counties__c usc : uscs){
if(!usCounties.containsKey(usc.Name)){
usCounties.put(usc.Name,new List<US_Counties__c>());
}
usCounties.get(usc.Name).add(usc);
}
for(Account a: Accts){
if(usCounties.containsKey(a.Physical_County__c)){
for(US_Counties__c a_county : usCounties.get(a.Physical_County__c)){
if(a_county.State_Name__c == a.Physical_State__c){
insert_ATM_FieldDirs.add(new AccountTeamMember(UserId=a_county.Field_Director__c, AccountId=a.Id,TeamMemberRole='Field Director'));
insert_ATM_WGroupLdrs.add(new AccountTeamMember(UserId=a_county.Work_Group_Leader__c, AccountId=a.Id,TeamMemberRole='Work Group Leader'));
insert_ATM_PMissions.add(new AccountTeamMember(UserId=a_county.Primary_Missionary__c, AccountId=a.Id,TeamMemberRole='Primary Missionary'));
ownerIDS.add(a_county.Primary_Missionary__c);
break;
}
}
}
}
//5. Insert all Permission Set Assignments for Account Health Permissionset using Future Method... this is a Setup DML object
if(ownerIDs.size() > 0){
accountHealthAccessHandler(ownerIDs);
}
//6. - Insert All ATMs
if(insert_ATM_FieldDirs.size() > 0){
Database.UpsertResult[] lsr = Database.upsert(insert_ATM_FieldDirs,false);
}
if(insert_ATM_WGroupLdrs.size() > 0){
Database.SaveResult[] lsr = Database.insert(insert_ATM_WGroupLdrs,false);
}
if(insert_ATM_PMissions.size() > 0){
Database.SaveResult[] lsr = Database.insert(insert_ATM_PMissions,false);
}
system.debug('ATMS FOR INSERTED State Dirs: '+insert_ATM_FieldDirs);
system.debug('ATMS FOR INSERTED Work Group Leaders: '+insert_ATM_WGroupLdrs);
system.debug('ATMS FOR INSERTED Primary Missionaries: '+insert_ATM_PMissions);
}//Handler 1
/***************************************************************************************************************************************************
Method: handler: VP for US Missionaries handler: Simply adds an ATM team role for VPs
****************************************************************************************************************************************************/
public static void handler(List<Account> newAccts){
system.debug('<<INSIDE VP Of US Missionaries Handler >> '+newAccts);
List<AccountTeamMember> insert_ATM_VPs = new List<AccountTeamMember>();
List<GroupMember> vpUser = [Select UserOrGroupId From GroupMember where Group.Name = 'VP of Account Team' limit 1];
for(Account someAccount : newAccts){
insert_ATM_VPs.add(new AccountTeamMember(UserId=vpUser[0].UserOrGroupId, AccountId=someAccount.Id,TeamMemberRole='VP of US Missionaries'));
}
if(insert_ATM_VPs.size() > 0){
Database.SaveResult[] lsr = Database.insert(insert_ATM_VPs,false);
}
}// Handler 2
/***************************************************************************************************************************************************
Method: accountHealthAccessHandler: Future Method for Setup DML so that Permission Set Account Health Access can be given to new account members
****************************************************************************************************************************************************/
//@future
public static void accountHealthAccessHandler(List<Id> ownerIDs){
PermissionSet pset = [Select Id From PermissionSet where name = 'Account_Health_Access' limit 1];
List<PermissionSetAssignment> account_health_access = new List<PermissionSetAssignment>();
Map<Id,String> filteredOutIDs = new Map<Id,String>();
for(PermissionSetAssignment dupePSAs : [Select AssigneeId from PermissionSetAssignment where PermissionSet.Name ='Account_Health_Access' and AssigneeId in: ownerIDs] ){
filteredOutIDs.put(dupePSAs.AssigneeId,'Account Health Access'); // Strain out unecessary owners if they already have this Health Account Permission. Example: State Director is account owner again replacing Prime Missionary
}// Loop
system.debug('<< OWNER LIST>> '+ownerIDs);
for(Id someOwnerId : ownerIDs){
if('Account Health Access' != filteredOutIDs.get(someOwnerId)){
account_health_access.add(new PermissionSetAssignment(AssigneeId = someOwnerId, PermissionSetId=pset.Id));
}
}//Loop
system.debug('<< ACCT HEALTH SIZE>> '+account_health_access.size());
if(account_health_access.size() > 0){
insert account_health_access;
}
}
}//Class
-
- Tony Williams 9
- March 29, 2018
- Like
- 0
Correctly Searching Map<String,List<Custom Object> over 3100 records
I We are using a Custom object calles US_Counties which includes county name, state, and a list of employee personnel with a max record size of 3,145.
1) Programmatically I want to be able to search the map Collection that stores this info by County name and pull out a list of US Counties objecsts and then based on the Account's Physical state, insert certain personnel into the Account's Account team Object.
Howvever when I search for the Accont's county name in the Map I get all 3,145 records returned. Can anyone help me find out what I am doing incorrectly?
2) Also how can I use this with a batch script and avoid the 10000 DML statements Governor Limit?
Thanks
Here is the code:
1) Programmatically I want to be able to search the map Collection that stores this info by County name and pull out a list of US Counties objecsts and then based on the Account's Physical state, insert certain personnel into the Account's Account team Object.
Howvever when I search for the Accont's county name in the Map I get all 3,145 records returned. Can anyone help me find out what I am doing incorrectly?
2) Also how can I use this with a batch script and avoid the 10000 DML statements Governor Limit?
Thanks
Here is the code:
system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries());
//For each account selected go and get the Account Team Mebmers while updating the account owner.
List<US_Counties__c> uscs = [Select Name,State_Name__c,Field_Director__c, Work_Group_Leader__c, Primary_Missionary__c from US_Counties__c ORDER BY State_Name__c, Name Asc];
Map<String,List<US_Counties__c>> usCounties = new Map<String,List<US_Counties__c>>();
List<US_Counties__c> all_counties = new List<US_Counties__c>();
for(US_Counties__c usc : uscs){
all_counties.add(usc);
usCounties.put(usc.Name,all_counties);
}
for(Account a: Accts){
system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries());
system.debug('<<ACCOUNT>> '+a);
//Make sure that the Physical Counties are searched on and not Phys state because the returned list size is much less on avg.
List<US_Counties__c> sampleCty = usCounties.get(a.Physical_County__c);
system.debug('<<GET COUNTIES SIZE>> '+sampleCty.size());//displays 3,145 records and not 8 for Orange County
system.debug('<<GET PHY COUNTY >> '+a.Physical_County__c);
List<US_Counties__c> countiesFound = new List<US_Counties__c>();
try{
countiesFound = usCounties.get(a.Physical_County__c);
system.debug('<<GET COUNTIES FOUND>> '+countiesFound);
for(US_Counties__c a_county : countiesFound){
if(a_county.State_Name__c == a.Physical_State__c){
system.debug('<< NUMBER OF QUERIES USED >> '+ Limits.getQueries());
insert_ATM_FieldDirs.add(new AccountTeamMember(UserId=countiesFound[0].Field_Director__c, AccountId=a.Id,TeamMemberRole='Field Director'));
insert_ATM_WGroupLdrs.add(new AccountTeamMember(UserId=countiesFound[0].Work_Group_Leader__c, AccountId=a.Id,TeamMemberRole='Work Group Leader'));
insert_ATM_PMissions.add(new AccountTeamMember(UserId=countiesFound[0].Primary_Missionary__c, AccountId=a.Id,TeamMemberRole='Primary Missionary'));
ownerIDS.add(countiesFound[0].Primary_Missionary__c);
break;
}
}
}catch(NullPointerException npex){ // TO test: 1)Create county that can be found or 2) that is mispelled 3) 1st letter not capitalized
system.debug(npex.getMessage());
}//CATCH
}//OUT FOR
-
- Tony Williams 9
- March 28, 2018
- Like
- 0
Traversing XML Trees using Apex
HI I'm trying top traverse an XML tree to get the Items Tag list. I was using iterative but the problem is that it seems that I can only get the lst item but I don;t get them all. Can someone p0leaswe help me? Thanks Here's the tree:
<Shipment id="103052074">
<ClientName>Awana</ClientName>
<OrderID>01061767</OrderID>
<PurchaseOrder />
<Name>SILVIA GIBSON</Name>
<FirstName>SILVIA</FirstName>
<LastName>GIBSON</LastName>
<Company />
<Address1>11900 TRADITION LN NE </Address1>
<Address2 />
<City>ALBUQUERQUE</City>
<State>NM</State>
<PostalCode>87111-8287</PostalCode>
<Country>UNITED STATES</Country>
<Email>silviagibson@mailinator.com</Email>
<Phone />
<OrderTimestamp>2019-01-18T00:00:00</OrderTimestamp>
<ReceivedTimestamp>2019-01-18T13:59:26.007</ReceivedTimestamp>
<ShipmentStatus>SHIPPED</ShipmentStatus>
<OrderType>Consumer</OrderType>
<ShippedDate>2019-01-18T14:16:37.550</ShippedDate>
<ExpectedDeliveryDate>2019-01-18T00:00:00</ExpectedDeliveryDate> <DeliveredTimestamp /> <DeliveryException />
<Warehouse id="160">
<Name>Greenwood, IN</Name>
<Address>1415 Collins Rd.</Address>
<City>Greenwood</City>
<State>IN</State>
<PostalCode>46143</PostalCode>
<Country>US</Country>
</Warehouse>
<ShipMethod>Newgistics Parcel Select</ShipMethod>
<ShipMethodCode>NGSPS</ShipMethodCode>
<Tracking>9200000000000629213249</Tracking> <TrackingUrl>http://shipment.co/tracking/2817/9200000000000629213249</TrackingUrl>
<Weight>4.000000</Weight>
<Postage />
<GiftWrap>false</GiftWrap>
<CustomFields>
<BillingAddress1>1620 N Penny Ln</BillingAddress1>
<BillingCity>Schaumburg</BillingCity>
<BillingCompany>Cherry Hills Community Church</BillingCompany>
<BillingCountry>United States</BillingCountry>
<BillingEmail>silviagibson@mailinator.com</BillingEmail>
<BillingFirstName>Heather</BillingFirstName>
<BillingLastName>Oliver</BillingLastName>
<BillingPhone>(866) 292-6227</BillingPhone>
<BillingState>IL</BillingState>
<BillingZip>60173</BillingZip>
<Shipping>17.87</Shipping>
<Total>190.52</Total>
</CustomFields>
<BackorderedItems />
<Items>
<Item id="1807577">
<SKU>94900</SKU>
<UPC />
<Description>Cubbies AppleSeed Handbook Music CD NIV</Description>
<Lot />
<Qty>2</Qty>
<CustomFields />
<AssemblyItems />
</Item>
<Item id="1807606">
<SKU>96543</SKU>
<UPC />
<Description>Cubbies HoneyComb Teaching Plans NKJV</Description>
<Lot />
<Qty>1</Qty>
<CustomFields />
<AssemblyItems />
</Item>
<Item id="1807670">
<SKU>96918</SKU>
<UPC />
<Description>Game Pin (4)</Description>
<Lot />
<Qty>4</Qty>
<CustomFields />
<AssemblyItems />
</Item>
<Item id="1807691">
<SKU>46421</SKU>
<UPC />
<Description>Gray Blouse, Leader Size 4X</Description> <Lot />
<Qty>3</Qty> <CustomFields />
<AssemblyItems />
</Item>
</Items>
<Packages>
<Package id="86892375">
<TrackingNumber>9200000000000629213249</TrackingNumber>
<Weight>4.30507</Weight>
<BillableWeight>4.00000</BillableWeight>
<Height>7.00000</Height>
<Width>4.00000</Width>
<Depth>6.00000</Depth>
</Package>
</Shipment>
- Tony Williams 9
- January 19, 2019
- Like
- 0
VF Page Component Error: The dependent picklist 'Card Type' requires its controlling field 'Payment Method' to be present on the page.
I have enabled Payment Method picklist in my org . The dependent picklisst is called CardType. I am using thee two inputfields within a form inside of a VF Page Component called ForAddressVerfication. The component is embedded in the Visual Force Page called OrderEntry4. When this page loads it tries to pull in the compoennt and I get this error: "The dependent picklist 'Card Type' requires its controlling field 'Payment Method' to be present on the page."
===========VF Page Component: ForAddressVerification =================
<!-- <apex:form > -->
<div id="SelectAddressDetail" style="display:none;"> <!-- Removing this will give us SmartyStreets Verify -->
<apex:form >
<div id="AddCreditCardInput" class="credit-card-input" style="display:none;">
<h1>Enter and Save</h1><br/>
<h1>Credit Card Information</h1><br/><br/>
<div class="two-pixel-padding">
<label class="top-label"> Name on Credit Card</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardName" maxlength='30' />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Credit Card Type</label><span class="required">*</span><br />
<apex:inputfield value="{!Order.Chargent_Order__r.ChargentOrders__Card_Type__c}" id="AddCreditCardType" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Credit Payment Method</label><span class="required">*</span><br />
<apex:inputfield value="{!Order.Chargent_Order__r.ChargentOrders__Payment_Method__c}" id="AddPaymentMethod" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Number (16 digits)</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardNumber" maxlength="16" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Month (MM)</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardMonth" maxlength="2" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Year (YYYY)</label><span class="required">*</span><br />
<input type="text" id="AddCreditCardYear" maxlength="4" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Card Security (XXX)</label><br />
<input type="text" id="AddCreditCardSecurity" maxlength="4" />
</div>
</div>
<div id="AddressInput" class="address-input" style="display:block;">
<h1>Enter or Select Address Information</h1><br/><br/>
<div><input type="hidden" id="SelectAddressType" /></div>
<div id="SelectAddressLoading" style="text-align:center;"></div>
<div id="SelectAddressList" >
<table id="SelectAddressListTable" cellpadding="3px" class="select-address-table" />
</div>
<div id="AddAddressInput" style="display:block;">
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> First Name</label><br />
<input type="text" id="AddAddressFirstName" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Last Name</label><span class="required">*</span><br />
<input type="text" id="AddAddressLastName" />
</div>
</div><br/>
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> Address Line One</label><span class="required">*</span><br />
<input type="text" id="AddAddressLineOne" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Address Line Two</label><br />
<input type="text" id="AddAddressLineTwo" />
</div>
</div><br/>
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> City</label><br />
<input type="text" id="AddAddressCity" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> State</label><br />
<input type="text" id="AddAddressState" maxlength="2" size="2" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Zip Code</label><span class="required">*</span><br />
<input type="text" id="AddAddressZipCode" maxlength="10" size="10" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> </label><br />
<input type="button" id="VerifyAddress" value="Verify" style="cursor:pointer;width:50px;height:30px;" onclick="showSaveButton();"/>
</div>
</div><br/>
<div class="input-container-left">
<div class="two-pixel-padding">
<label class="top-label"> County</label><br />
<input type="text" id="AddAddressCounty" />
</div>
<div class="two-pixel-padding">
<label class="top-label"> Country</label><br />
<select id="AddAddressCountry" style="width:200px;">
<option selected="selected">UNITED STATES</option>
</select>
</div>
<div><input type="hidden" id="AddAddressId"/></div>
</div><br/>
</div>
</div>
</apex:form>
============== Order Entry Page Segment =======================
<apex:pageBlockSectionItem >
<apex:outputLabel value="Shipping Address: " for="OrderShippingAddress" id="OrderShippingAddressLabel" />
<div id="OrderShippingAddressDetail" style="display:none;">
<span id="OrderShippingAddressFirstName"></span>
<span id="OrderShippingAddressLastName"></span><br/>
<span id="OrderShippingAddressLineOne"></span><br/>
<span id="OrderShippingAddressLineTwo"></span><br/>
<span id="OrderShippingAddressCity"></span>
<span id="OrderShippingAddressState"></span>
<span id="OrderShippingAddressZip"></span><br/>
<span id="OrderShippingAddressCounty"></span><br/>
<span id="OrderShippingAddressCountry"></span><br/>
</div>
<input type="button" style="cursor:pointer;" id="OrderShippingAddressChangeLink"
onclick="openSelectAddressDialog('Shipping');" value="Change Shipping Address" />
</apex:pageBlockSectionItem>
<c:ForSSAddressVerification Order="{!Order}"/>
</apex:pageBlockSection>
- Tony Williams 9
- September 05, 2018
- Like
- 0
Avalara for SF: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
Hi I'm working on the integration between AvaTax and our billing system, using the Salesforce Api.
We have changed to a newSalesforce Organization and are attempting to calculate tax on orders for Canadian customers. This has worked well on other Sandboxes we have tried.
Is there a reliable way to know why the parametr is not working when sending the Http Request?
I am noticing that for this new Sandbox org we are reciving this message when calculating the tax (See log file segment below) Thanks:
The Apex code that makes the call out to Avalara is this:
The AvalaraTaxJSON object looks like this:
We have changed to a newSalesforce Organization and are attempting to calculate tax on orders for Canadian customers. This has worked well on other Sandboxes we have tried.
Is there a reliable way to know why the parametr is not working when sending the Http Request?
I am noticing that for this new Sandbox org we are reciving this message when calculating the tax (See log file segment below) Thanks:
DEBUG|{"type":"SalesOrder","lines":[\{"quantity":1.00,"itemCode":"43490","description":"Freight","number":"1","amount":0.00},\{"quantity":1.00,"itemCode":"79345","description":"Puggles Backpack","number":"2","amount":4.1677967793}],"customerCode":"4","companyCode":"awana1","code":"988103","date":"2018-04-25 10:29:52","commit":"false","addresses":{"ShipTo":{"region":"BC","postalCode":"V4P 1H5","line1":"2430 King George Blvd Ste 101","country":null,"city":"Surrey"},"ShipFrom":{"region":"IL","postalCode":"60173","line1":"1620 N Penny Ln","country":"US","city":"Schaumburg"}}}
10:29:51.0 (36237563)|CALLOUT_REQUEST|[1747]|System.HttpRequest[Endpoint=callout:AvalaraTax, Method=POST]
10:29:51.0 (40289120)|EXCEPTION_THROWN|[1747]|System.UnexpectedException: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
10:29:51.0 (40477323)|FATAL_ERROR|System.UnexpectedException: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
The Apex code that makes the call out to Avalara is this:
webservice static Result CalculateTaxOnOpportunity(string OrderId)
{
decimal TaxAmount = null;
// Try to
try
{
// Convert the OpportunitySalesforceId argument provided to a Salesforce ID
ID TempId = OrderId;
// If converting fails, return failure and an error message.
} catch(Exception ex) { return new Result(false,'Please supply a valid Order (15 or 18 character) Salesforce Id. Error Message: '+ex.getMessage()); }
try
{
// Initialize the tax variable to zero.
TaxAmount = 0;
AvalaraTaxJSON Obj = new AvalaraTaxJSON(OrderId);
if(Obj.companyCode != null || Obj.companyCode !='') {
string jsonData = JSON.serialize(Obj);
jsonData = jsonData.replace('AvalaraCurrentDataTime','date');
jsonData = jsonData.replace('Avalara_Commit','commit');
jsonData = jsonData.replaceAll('Avalara_SeqNumber','number');
system.debug(jsonData);
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AvalaraTax');
req.setBody(jsonData);
req.setHeader('Content-Type','application/json');
req.setMethod('POST');
HttpResponse res = h.send(req);
system.debug(res.getBody());
JSONParser parser = JSON.createParser(res.getBody());
while (parser.nextToken() != null) {
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'totalTax')) {
parser.nextToken();
TaxAmount = parser.getDecimalValue();
}
}
return new Result(true,'Success, tax amount calculated',TaxAmount);
}
else
return new Result(false,'The Order must have a valid Shipping Country before calculating tax OR Country must be United States Or Canada');
}
// If an error occurred getting tax
catch (Exception ex)
{
// Return failure and an error message.
return new Result(false,'An error occurred when getting tax from the tax system. Error:'+ex.getMessage());
}
// Otherwise, return Success as true and the Tax Amount calculated by the tax web service.*/
return new Result(true,'Success, tax amount calculated',TaxAmount);
}
The AvalaraTaxJSON object looks like this:
public class AvalaraTaxJSON {
string code;
public string companyCode{get;set;}
string type;
string AvalaraCurrentDataTime;
string customerCode;
string Avalara_Commit;
address addresses;
list<lineItem> lines;
public class address{
public AddressCls ShipFrom;
public AddressCls ShipTo;
}
public class AddressCls{
string line1;
string city;
string region;
string country;
string postalCode;
public AddressCls(string line, string city, string reg, string country, string zipCode){
this.line1 = line;
this.city = city;
this.region = reg;
this.country = country;
this.postalCode = zipCode;
}
}
public class lineItem{
public string Avalara_SeqNumber;
public decimal quantity;
public decimal amount;
public string description;
public string itemCode;
public lineItem(string num,decimal qunt, decimal amt,string itemCode, string des){
this.Avalara_SeqNumber = num;
this.quantity = qunt;
this.amount =amt;
this.description = des;
this.itemCode = itemcode;
}
}
public AvalaraTaxJSON(string orderId){
string isoCode;
//Constructing JSON with OrderLine Items
lines = new list<LineItem>();
list<Order> orderLst = [SELECT ID, Name,Shipping_Street__c, Shipping_City__c,Shipping_State__c, Shipping_Zip_Code__c, Shipping_Country__c, TempOrderNumber__c, LastModifiedById, Error_Log__c,Account.IntacctID__c, Company__c,
(SELECT Line_Type__c, PricebookEntry.Product2Id, PricebookEntry.Product2.ProductCode, PricebookEntry.Product2.Name, Quantity, TotalPrice, Quantity_Given_Away__c FROM Order.OrderItems) FROM Order WHERE ID = :string.escapeSingleQuotes(orderId)];
if(orderLst!=null&& orderLst.size()>0){
Order Ord= orderLst.get(0);
if(Ord.Shipping_Country__c!=null && Ord.Shipping_Country__c.toLowerCase().contains('united states') || Ord.Shipping_Country__c.toLowerCase().contains('canada')){
list<Country__c> countryObj = [SELECT ISO_Code__c FROM Country__c WHERE Name = :Ord.Shipping_Country__c];
if(countryObj!=null && countryObj.size()>0){
isoCode = countryObj.get(0).ISO_Code__c;
}
Awana_Settings__c custSetting = Awana_Settings__c.getValues('AvalaraTaxCompany');
if(custSetting!=null)
this.companyCode = custSetting.value__c;
else
this.companyCode = 'awana1-sb2'; //default value
this.code = Ord.TempOrderNumber__c;
this.customerCode = Ord.Account.IntacctID__c;
this.type = 'SalesOrder';
this.AvalaraCurrentDataTime = String.valueOf(system.now());
this.Avalara_Commit = 'false';
addresses = new address();
addresses.ShipFrom = new AddressCls('1620 N Penny Ln','Schaumburg','IL','US','60173'); //Default Address Present in Cast iron
addresses.ShipTo = new AddressCls(Ord.Shipping_Street__c,Ord.Shipping_City__c,Ord.Shipping_State__c,isoCode,Ord.Shipping_Zip_Code__c);
integer itr =1;
for(OrderItem oli : Ord.OrderItems){
lines.add(new LineItem(string.valueOf(itr),oli.Quantity,Oli.TotalPrice,oli.PricebookEntry.Product2.ProductCode,oli.PricebookEntry.Product2.Name));
itr++;
}
}
}
}
}
- Tony Williams 9
- April 25, 2018
- Like
- 0
DML Limit 10000 Reached While Processing 9455 Account Team Objects
HI I am running a batch scirpt that has up to 9455 accounts. I need to update their acoucnt objects. The problem is that I have code that has to insert 3 Account Team Members per each Account record that is being iterated or 3 DML * 9455 = 28.365K. The Account Team Objects being updated don;t have any triggers that do any firing.
Q) How can I avoid this "DML Limit of 10000" issue?
Q) Should I increasemy batch limit? Currently this is what I am using: Database.executeBatch(job, 10);
Here is the code and Thanks.:
Q) How can I avoid this "DML Limit of 10000" issue?
Q) Should I increasemy batch limit? Currently this is what I am using: Database.executeBatch(job, 10);
Here is the code and Thanks.:
BATCH:
===================================================================
global class BatchUpdateAccountTeams implements Database.Batchable<sObject>,Database.AllowsCallouts, Database.Stateful {
global String query;
global Integer accountSize = 0;
List<Account> accountsToUpdate = new List<Account>();
global class UtilException extends Exception {}
global database.querylocator start(Database.BatchableContext BC){
//*****************************************************************************************************************************************************************************p
//Select All active US Accounts that have counties and states
//NOTE: You don't need to get all Physical address components just the city and state.
//*****************************************************************************************************************************************************************************
if(query == null)
{
query
= 'Select Id,Mailing_Address_Book__c,Physical_County__c,Physical_State__c '
+ ' From Account WHERE Status__c = \'Added\' '
+ ' And Physical_County__c <> null '
+ ' And Physical_State__c <> null '
+ ' And Registration_Level__c = \'R1\''
+ ' And Type = \'Church\''
+ ' And RecordType.Name like \'%US Organization%\' limit 10000';
}
system.debug('<< QUERY >> '+query);
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope){
List<Id> accountIDs = new List<Id>();
//List<RecordType> rec = [Select Id from RecordType where Name = 'US Organization' Limit 1];
//1. Get access to all Active US Organizations having Physical counties and states.
for(sObject s : scope){
Account thisAccount = (Account)s;
accountsToUpdate.add(thisAccount);
accountIDs.add(thisAccount.Id);
accountSize++;
}
//accountSize = accountsToUpdate.size();
system.debug('<< Max Accounts found>> '+accountSize);
//2. Update The Account Teams for these accounts with the most recent account team personnel including VP of US Missionaries
if(accountsToUpdate.size() > 0){
TeamMemberAccounts.handler(accountsToUpdate,accountIDs);
TeamMemberAccounts.handler(accountsToUpdate);
}
}
global void finish(Database.BatchableContext BC){
List<Messaging.SingleEmailMessage> emailList = new List<Messaging.SingleEmailMessage>();
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
//Send email to all in Account Teams Updates Group if any account team member objects were created/updated
if(accountSize > 0){
//3. Get User Ids for the Acocunt Team Updates Group.
Map<Id,User> users = new Map<Id, User>([SELECT Id, Email FROM User WHERE Id IN (
SELECT UserOrGroupId FROM GroupMember WHERE Group.Name = 'Account Team Updates')]);
List<String> userEmail = new List<String>();
//We need to make sure that the Test coverage will work when testing emails otherwise a REQUIRED_FIELD_MISSING, Missing exception will occur.
if(Test.isRunningTest()){
User tUser=[Select Email from User where Name Like 'MyAwana%' Limit 1];
userEmail.add(tUser.Email);
}else{
for(User someUser : users.values()){
userEmail.add(someUser.Email);
}
}
List<String> sendTo = new List<String>();
sendTo.addAll(userEmail);
//4. Assign the addresses for the To and CC lists to the mail object.
mail.setToAddresses(sendTo); // Specify the subject line for your email address.
//5. Set to True if you want to BCC yourself on the email.
mail.setBccSender(false);
//6.: Set who the email is sent from
mail.setReplyTo('noreply@awana.org');
mail.setSenderDisplayName('No Reply');
//7. Set email contents !
mail.setSubject('Accounts Process with Updated or New Account Teams');
String lines = '<br>';
Integer lineCounter = 0;
Integer lineLimit = 20;
for(Account an_account : accountsToUpdate){
lines = lines+an_account.Mailing_Address_Book__c+', ';
lineCounter++;
if(lineCounter == lineLimit - 1){
lines = lines+'<br>';
}
if(lineCounter == lineLimit){
lineCounter=0;
}
}//loop
system.debug('<<LINES>> '+lines);
mail.setHtmlbody('Total Accounts Processed:<b> '+ accountSize+'</b><br>'+lines+'</b><br>');
// Send the email you have created.' '+
emailList.add(mail);
Messaging.sendEmail(emailList);
}
}
}
====================== TEAM MEMBER ACCOUNTS.CLS==================
public with sharing class TeamMemberAccounts {
/*
* Method: handleOpportunityInsert
* Inputs: List of Accounts which have ownership updates to be matched with their ATMs (Account Team Member)
* Purpose: To verify that we will have a State Director whether due to updating the ATM or creating a new one.
* SOQL: 1
* DML: 2
*/
public class handlerException extends Exception{}
/***************************************************************************************************************************************************
Method: handler: Makes sure that Primary Missionaries are assigned as Account Team Memebrs programmatically
****************************************************************************************************************************************************/
public static void handler(List<Account> Accts,List<ID> acctIDS){
List<AccountTeamMember> insert_ATM_FieldDirs = new List<AccountTeamMember>();
List<AccountTeamMember> insert_ATM_WGroupLdrs = new List<AccountTeamMember>();
List<AccountTeamMember> insert_ATM_PMissions = new List<AccountTeamMember>();
List<Id> ownerIDs = new List<Id>();
Boolean foundStateDir = false;
// Old ATM Roles must go because we don't know how if these users are still available.
List<AccountTeamMember> delete_ATMS = [Select AccountID,UserId,TeamMemberRole from AccountTeamMember WHERE TeamMemberRole in ('Field Director','Work Group Leader','Primary Missionary') and AccountId in : acctIDs];
if(delete_ATMS.size() > 0){
delete delete_ATMS;
}
system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries());
//For each account selected go and get the Account Team Mebmers while updating the account owner.
List<US_Counties__c> uscs = [Select Name,State_Name__c,Field_Director__c, Work_Group_Leader__c, Primary_Missionary__c from US_Counties__c ORDER BY State_Name__c, Name Asc];
Map<String,List<US_Counties__c>> usCounties = new Map<String,List<US_Counties__c>>();
for(US_Counties__c usc : uscs){
if(!usCounties.containsKey(usc.Name)){
usCounties.put(usc.Name,new List<US_Counties__c>());
}
usCounties.get(usc.Name).add(usc);
}
for(Account a: Accts){
if(usCounties.containsKey(a.Physical_County__c)){
for(US_Counties__c a_county : usCounties.get(a.Physical_County__c)){
if(a_county.State_Name__c == a.Physical_State__c){
insert_ATM_FieldDirs.add(new AccountTeamMember(UserId=a_county.Field_Director__c, AccountId=a.Id,TeamMemberRole='Field Director'));
insert_ATM_WGroupLdrs.add(new AccountTeamMember(UserId=a_county.Work_Group_Leader__c, AccountId=a.Id,TeamMemberRole='Work Group Leader'));
insert_ATM_PMissions.add(new AccountTeamMember(UserId=a_county.Primary_Missionary__c, AccountId=a.Id,TeamMemberRole='Primary Missionary'));
ownerIDS.add(a_county.Primary_Missionary__c);
break;
}
}
}
}
//5. Insert all Permission Set Assignments for Account Health Permissionset using Future Method... this is a Setup DML object
if(ownerIDs.size() > 0){
accountHealthAccessHandler(ownerIDs);
}
//6. - Insert All ATMs
if(insert_ATM_FieldDirs.size() > 0){
Database.UpsertResult[] lsr = Database.upsert(insert_ATM_FieldDirs,false);
}
if(insert_ATM_WGroupLdrs.size() > 0){
Database.SaveResult[] lsr = Database.insert(insert_ATM_WGroupLdrs,false);
}
if(insert_ATM_PMissions.size() > 0){
Database.SaveResult[] lsr = Database.insert(insert_ATM_PMissions,false);
}
system.debug('ATMS FOR INSERTED State Dirs: '+insert_ATM_FieldDirs);
system.debug('ATMS FOR INSERTED Work Group Leaders: '+insert_ATM_WGroupLdrs);
system.debug('ATMS FOR INSERTED Primary Missionaries: '+insert_ATM_PMissions);
}//Handler 1
/***************************************************************************************************************************************************
Method: handler: VP for US Missionaries handler: Simply adds an ATM team role for VPs
****************************************************************************************************************************************************/
public static void handler(List<Account> newAccts){
system.debug('<<INSIDE VP Of US Missionaries Handler >> '+newAccts);
List<AccountTeamMember> insert_ATM_VPs = new List<AccountTeamMember>();
List<GroupMember> vpUser = [Select UserOrGroupId From GroupMember where Group.Name = 'VP of Account Team' limit 1];
for(Account someAccount : newAccts){
insert_ATM_VPs.add(new AccountTeamMember(UserId=vpUser[0].UserOrGroupId, AccountId=someAccount.Id,TeamMemberRole='VP of US Missionaries'));
}
if(insert_ATM_VPs.size() > 0){
Database.SaveResult[] lsr = Database.insert(insert_ATM_VPs,false);
}
}// Handler 2
/***************************************************************************************************************************************************
Method: accountHealthAccessHandler: Future Method for Setup DML so that Permission Set Account Health Access can be given to new account members
****************************************************************************************************************************************************/
//@future
public static void accountHealthAccessHandler(List<Id> ownerIDs){
PermissionSet pset = [Select Id From PermissionSet where name = 'Account_Health_Access' limit 1];
List<PermissionSetAssignment> account_health_access = new List<PermissionSetAssignment>();
Map<Id,String> filteredOutIDs = new Map<Id,String>();
for(PermissionSetAssignment dupePSAs : [Select AssigneeId from PermissionSetAssignment where PermissionSet.Name ='Account_Health_Access' and AssigneeId in: ownerIDs] ){
filteredOutIDs.put(dupePSAs.AssigneeId,'Account Health Access'); // Strain out unecessary owners if they already have this Health Account Permission. Example: State Director is account owner again replacing Prime Missionary
}// Loop
system.debug('<< OWNER LIST>> '+ownerIDs);
for(Id someOwnerId : ownerIDs){
if('Account Health Access' != filteredOutIDs.get(someOwnerId)){
account_health_access.add(new PermissionSetAssignment(AssigneeId = someOwnerId, PermissionSetId=pset.Id));
}
}//Loop
system.debug('<< ACCT HEALTH SIZE>> '+account_health_access.size());
if(account_health_access.size() > 0){
insert account_health_access;
}
}
}//Class
- Tony Williams 9
- March 29, 2018
- Like
- 0
Correctly Searching Map<String,List<Custom Object> over 3100 records
I We are using a Custom object calles US_Counties which includes county name, state, and a list of employee personnel with a max record size of 3,145.
1) Programmatically I want to be able to search the map Collection that stores this info by County name and pull out a list of US Counties objecsts and then based on the Account's Physical state, insert certain personnel into the Account's Account team Object.
Howvever when I search for the Accont's county name in the Map I get all 3,145 records returned. Can anyone help me find out what I am doing incorrectly?
2) Also how can I use this with a batch script and avoid the 10000 DML statements Governor Limit?
Thanks
Here is the code:
1) Programmatically I want to be able to search the map Collection that stores this info by County name and pull out a list of US Counties objecsts and then based on the Account's Physical state, insert certain personnel into the Account's Account team Object.
Howvever when I search for the Accont's county name in the Map I get all 3,145 records returned. Can anyone help me find out what I am doing incorrectly?
2) Also how can I use this with a batch script and avoid the 10000 DML statements Governor Limit?
Thanks
Here is the code:
system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries());
//For each account selected go and get the Account Team Mebmers while updating the account owner.
List<US_Counties__c> uscs = [Select Name,State_Name__c,Field_Director__c, Work_Group_Leader__c, Primary_Missionary__c from US_Counties__c ORDER BY State_Name__c, Name Asc];
Map<String,List<US_Counties__c>> usCounties = new Map<String,List<US_Counties__c>>();
List<US_Counties__c> all_counties = new List<US_Counties__c>();
for(US_Counties__c usc : uscs){
all_counties.add(usc);
usCounties.put(usc.Name,all_counties);
}
for(Account a: Accts){
system.debug('<<NUMBER OF QUERIES In TOTAL : '+Limits.getLimitQueries());
system.debug('<<ACCOUNT>> '+a);
//Make sure that the Physical Counties are searched on and not Phys state because the returned list size is much less on avg.
List<US_Counties__c> sampleCty = usCounties.get(a.Physical_County__c);
system.debug('<<GET COUNTIES SIZE>> '+sampleCty.size());//displays 3,145 records and not 8 for Orange County
system.debug('<<GET PHY COUNTY >> '+a.Physical_County__c);
List<US_Counties__c> countiesFound = new List<US_Counties__c>();
try{
countiesFound = usCounties.get(a.Physical_County__c);
system.debug('<<GET COUNTIES FOUND>> '+countiesFound);
for(US_Counties__c a_county : countiesFound){
if(a_county.State_Name__c == a.Physical_State__c){
system.debug('<< NUMBER OF QUERIES USED >> '+ Limits.getQueries());
insert_ATM_FieldDirs.add(new AccountTeamMember(UserId=countiesFound[0].Field_Director__c, AccountId=a.Id,TeamMemberRole='Field Director'));
insert_ATM_WGroupLdrs.add(new AccountTeamMember(UserId=countiesFound[0].Work_Group_Leader__c, AccountId=a.Id,TeamMemberRole='Work Group Leader'));
insert_ATM_PMissions.add(new AccountTeamMember(UserId=countiesFound[0].Primary_Missionary__c, AccountId=a.Id,TeamMemberRole='Primary Missionary'));
ownerIDS.add(countiesFound[0].Primary_Missionary__c);
break;
}
}
}catch(NullPointerException npex){ // TO test: 1)Create county that can be found or 2) that is mispelled 3) 1st letter not capitalized
system.debug(npex.getMessage());
}//CATCH
}//OUT FOR
- Tony Williams 9
- March 28, 2018
- Like
- 0