• Florian Dardelet 7
  • NEWBIE
  • 0 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 2
    Replies

Hello,

I have a process to harvest a price list that requires the orchestration of multiple Apex methods, including a callout to an external API and interpretation of its response. If you coordinate the series of operations through a back-end Apex for a single price request, this routinely exceeds the governor limit. In addition, each element in the orchestration has a dependency on its predecessors, meaning that I must call them synchronously. 

I've created a LWC that takes care of that orchestration from the browser. The benefit is that I can create multiple price requests and fire them one after the other, however I run into 2 issues: 

1. I often get a "communication error - no response from server" when I send too many requests in parallel, which I cannot explain at this point. I suspect it's driven by the limit of 100 simultaneous Apex operations active on the org, but I'm not sure.

2. I cannot find an efficient way to send a batch of pricing requests which would all get coordinated from the browser. 

Is there a best-practice in LWC for calling a series of apex sequentially? Or is there a best way to do it? 

In practice, this looks like this: 

1. User creates or uploads a series of price requests (up to 200 individual request). 

2. LWC lists all pending requests with a "Harvest" button which will fetch the price details to the supplier's API, then interprets and cascade the price to all records that require updating. We use formulas where possible, but a lot of records still need to be manipulated. 

3. Once the user clicks on harvest, this particular request gets orchestrated by a JS function until it's completed. At the end of the orchestration, the JS refreshes the list of price queries and the active one is removed from the list by the controller class. 

4. If the user harvests too many requests at the same time, it will trigger a server communication error.

This is preventing me from creating a "Harvest All" method that will go through the list in order. 

 

Thanks for any help

Hello,

I have to integrate with a SOAP API which isn't supported with WSDL2Apex. I have done the integration manually and it's working, but I'm stuck on getting the test class to mock the webservice callout. 

The method which invokes the webservice is defined below. The method takes 2 inputs: 
    webServiceCall__c contains the actual request details, including the payload which has been computed beforehand
    credentials__c contains the details for the webservice, including among others the endpoint and soapaction to use. 

The purpose of this method is to retrieve the response body and return it for interpretation.
 

public class FQDwebService{

	public static String invokeFQD(webServiceCall__c request, credentials__c credentials){

        HttpRequest req = new HttpRequest();
        req.setTimeout(30000);
        req.setEndpoint(credentials.endpoint__c);
        req.setMethod('POST');
        req.setBody(request.payloadRQ__c);
        req.setHeader('SOAPAction', credentials.headerSOAPAction__c);
        Http http = new Http();
        system.debug('Sending RQ');
        HTTPResponse res = http.send(req);
        
        return res.getBody();
    }	
}
I have tried various combinations but it just doesn't work. How should I write a mock and test class to get this working? 

Current Mock
@isTest
global class FQDwebServiceMock implements WebServiceMock{
	global void doInvoke(Object stub,
                         Object request,
                         Map<String, Object> response,
                         String endpoint,
                         String soapAction,
                         String requestName,
                         String responseNS,
                         String responseName,
                         String responseType){
                            string response_x = '<body>Success</body>';
                                 response.put('response_x',response_x);
                         }
}

And current test class
@isTest 
static void invokeFQDwebService(){
        Test.setMock(WebServiceMock.class, new FQDwebServiceMock());
		
		
        testDataFactory.generateTestData();
        webServiceCall__c testRequest = [SOQL retrieving the test request];
        
		credentials__c testCredentials = new credentials__c(
            headerSOAPAction__c = 'SOAPAction',
            endpoint__c = 'https://endpoint'
        );
        
        
        String testString = FQDwebService.invokeFQD(testRequest, testCredentials);
        String targetString = '<body>Success</body>';
        System.assertEquals(targetString, testString);
        
    }

Thank you for any help you can provide.
 



 

I need to integrate our Salesforce Org with a 3rd party SOAP API. However, the WSDL is too complex for SF to integrate using the WSDL2Apex function and I have to integrate it manually.

I am able to poll and receive a response, but I am struggling to create the Apex class that will parse that response. I have looked at ways to create the Apex Class manually but they are either oversimplistic or just referring to WSDL2Apex function, both of which do not work.

There are a lot of very good posts about this, but I haven't been able to make any of them work. The closest I got to was using this suggestion (https://developer.salesforce.com/forums/?id=9062I000000g7n9QAA), but while it works for test Strings written in Apex, it doesn't work when I interact with the body of the response.

My current sample code is below for your ref. Note that I'm also happy to use another solution to parse, but please explain how I should make it work as I've tried a lot and didn't get through.

Current Apex code snippet

[...]
// The response is saved under res
HTTPResponse res = http.send(req);

string xmlRS = res.getBody();
XPath xp = new XPath(res.getBody()); 

//This line is the one that seems to break Apex. All system.debug breaks as soon as that line is active.
Dom.XmlNode[] items = xp.find('/soap:Envelope/soap:Body/Price_ByProductName/productDetails/itemGrp');


//Then we are grabbing each of the components as per this. 
String item_class = xp.getText(item, '', './productAvailabilityStatus/bookingClassDetails/designator');
 

Sample XML below for reference

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://urlenvelope" xmlns:awsse="http://url2" xmlns:wsa="http://www.w3.org/2005/08/addressing">
	<soap:Header/>
	<soap:Body>
		<Price_ByProductName xmlns="http://url">
			<infoText>
				<freeTextQualification>
					<textSubjectQualifier>ADULT</textSubjectQualifier>
				</freeTextQualification>
				<freeText>PRODUCTNAME</freeText>
				<freeText>PRODUCTID</freeText>
			</infoText>
			<productDetails>
				<transportService>
					<companyIdentification>
						<marketingCompany>RETAILER</marketingCompany>
					</companyIdentification>
				</transportService>
				<odiGrp>
					<originDestination>
						<origin>London</origin>
						<destination>Manchester</destination>
					</originDestination>
					<flightDateAndTime>
						<dateAndTimeDetails>
							<qualifier>B</qualifier>
							<date>130122</date>
						</dateAndTimeDetails>
						<dateAndTimeDetails>
							<qualifier>A</qualifier>
							<date>130122</date>
						</dateAndTimeDetails>
					</flightDateAndTime>
				</odiGrp>
				<itemGrp>
					<itemNb>
						<itemNumberDetails>
							<number>01</number>
						</itemNumberDetails>
					</itemNb>
					<productAvailabilityStatus>
						<bookingClassDetails>
							<designator>A</designator>
						</bookingClassDetails>
					</productAvailabilityStatus>
					<fareQualifItem>
						<additionalFareDetails>
							<rateClass>IAMACODE1</rateClass>
						</additionalFareDetails>
						<discountDetails>
							<fareQualifier>NONREFUNDABLE</fareQualifier>
							<rateCategory>BASIC</rateCategory>
						</discountDetails>
					</fareQualifItem>
					<monetaryGrp>
						<monetaryValues>
							<monetaryDetails>
								<typeQualifier>Public</typeQualifier>
								<amount>40</amount>
							</monetaryDetails>
							<monetaryDetails>
								<typeQualifier>Negotiated</typeQualifier>
								<amount>35</amount>
							</monetaryDetails>
						</monetaryValues>
					</monetaryGrp>
				</itemGrp>
				<itemGrp>
					<itemNb>
						<itemNumberDetails>
							<number>02</number>
						</itemNumberDetails>
					</itemNb>
					<productAvailabilityStatus>
						<bookingClassDetails>
							<designator>B</designator>
						</bookingClassDetails>
					</productAvailabilityStatus>
					<fareQualifItem>
						<additionalFareDetails>
							<rateClass>IAMANOTHERCODE2</rateClass>
						</additionalFareDetails>
						<discountDetails>
							<fareQualifier>REFUNDABLE</fareQualifier>
							<rateCategory>BASIC</rateCategory>
						</discountDetails>
					</fareQualifItem>
					<monetaryGrp>
						<monetaryValues>
							<monetaryDetails>
								<typeQualifier>Public</typeQualifier>
								<amount>60</amount>
							</monetaryDetails>
							<monetaryDetails>
								<typeQualifier>Negotiated</typeQualifier>
								<amount>55</amount>
							</monetaryDetails>
						</monetaryValues>
					</monetaryGrp>
				</itemGrp>
				<itemGrp>
					<itemNb>
						<itemNumberDetails>
							<number>03</number>
						</itemNumberDetails>
					</itemNb>
					<productAvailabilityStatus>
						<bookingClassDetails>
							<designator>C</designator>
						</bookingClassDetails>
					</productAvailabilityStatus>
					<fareQualifItem>
						<additionalFareDetails>
							<rateClass>WHATSACODE3</rateClass>
						</additionalFareDetails>
						<discountDetails>
							<fareQualifier>REFUNDABLE</fareQualifier>
							<rateCategory>PREMIUM</rateCategory>
						</discountDetails>
					</fareQualifItem>
					<monetaryGrp>
						<monetaryValues>
							<monetaryDetails>
								<typeQualifier>Public</typeQualifier>
								<amount>70</amount>
							</monetaryDetails>
							<monetaryDetails>
								<typeQualifier>Negotiated</typeQualifier>
								<amount>60</amount>
							</monetaryDetails>
						</monetaryValues>
					</monetaryGrp>
				</itemGrp>
			</productDetails>
		</Price_ByProductName>
	</soap:Body>
</soap:Envelope>
 


 

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> 

 

I'm building a Lightning Component that includes a ui:scrollerWrapper, containing an aura:iteration. I want the scroller to default scrollTo the bottom. 

I found this documentation: https://developer.salesforce.com/docs/atlas.en-us.208.0.lightning.meta/lightning/aura_compref_ui_scrollerWrapper.htm? that lists the Methods, including scrollTo(destination) where destination is a string with options "top", "bottom", "left" and "right".  But I can't figure out where to put that method.

My component markup:
 

<ui:scrollerWrapper class="scrollerSize" aura:Id="scroller">

        <aura:iteration items="{!v.messages}" var="message">
            <c:MessageTile message="{!message}" inits="{!v.conversation.GroupInits__c}"/>
        </aura:iteration>

    </ui:scrollerWrapper>
My css:
.THIS.scrollerSize {
    height: 400px;
}
I tried this in the doInit handler:
var scroller = component.find("scroller");
scroller.scrollTo('bottom');
But it doesn't work.

Advice?