-
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