Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 57 additions & 7 deletions examples/b2c/checkout/integrations/classes/B2CDeliverySample.cls
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,28 @@ global class B2CDeliverySample implements sfdc_checkout.CartShippingCharges {
shippingOptionsAndRatesFromExternalService = getShippingOptionsAndRatesFromMockedService(siteLanguage);
}

// On re-entry of the checkout flow delete all previous CartDeliveryGroupMehods for the given cartDeliveryGroupId
delete [SELECT Id FROM CartDeliveryGroupMethod WHERE WebCartId = :cartId];

// Create a CartDeliveryGroupMethod record for every shipping option returned from the external service
Integer cdgmToBeCreated = 0;
CartDeliveryGroupMethod[] cdgmsToInsert = new CartDeliveryGroupMethod[]{};
for (ShippingOptionsAndRatesFromExternalService shippingOption: shippingOptionsAndRatesFromExternalService) {
for(CartDeliveryGroup curCartDeliveryGroup : cartDeliveryGroups){
CartDeliveryGroupMethod cdgm = populateCartDeliveryGroupMethodWithShippingOptions(shippingOption, curCartDeliveryGroup.Id, cartId);
cdgmsToInsert.add(cdgm);
// there can be multiple delivery groups so we will iterate thru DGs
for(CartDeliveryGroup curCartDeliveryGroup : cartDeliveryGroups){
// get selected Delivery method id for cart delivery groupId
ID previousSelectDeliveryMethodId = [SELECT SelectedDeliveryMethodId FROM CartDeliveryGroup WHERE Id = :curCartDeliveryGroup.Id][0].SelectedDeliveryMethodId;

if(previousSelectDeliveryMethodId != null) {
// delete all the cart delivery group method id except selected one
delete [SELECT Id FROM CartDeliveryGroupMethod WHERE CartDeliveryGroupId = :curCartDeliveryGroup.Id and Id!= :previousSelectDeliveryMethodId];
} else {
//Delete all the delivery methods if previousSelectDeliveryMethod is null
delete [SELECT Id FROM CartDeliveryGroupMethod WHERE CartDeliveryGroupId = :curCartDeliveryGroup.Id];
}
// iterate thru all shipping rates
for (ShippingOptionsAndRatesFromExternalService shippingOption: shippingOptionsAndRatesFromExternalService) {
//if selected CDGM is matching with shipping option then we don't need to create shipping option and existing can be reused
if(!isShippingOptionMatchingWithSelectedDM(shippingOption,previousSelectDeliveryMethodId)){
CartDeliveryGroupMethod cdgm = populateCartDeliveryGroupMethodWithShippingOptions(shippingOption, curCartDeliveryGroup.Id, cartId);
cdgmsToInsert.add(cdgm);
}
cdgmToBeCreated += 1;
}
}
Expand Down Expand Up @@ -83,6 +95,44 @@ global class B2CDeliverySample implements sfdc_checkout.CartShippingCharges {
return integStatus;
}

/**
This method compares previous Selected Delivery method with current shipping options and if both matches returns ture
*/
private boolean isShippingOptionMatchingWithSelectedDM(ShippingOptionsAndRatesFromExternalService shippingOption, String previousSelectDeliveryMethodId) {
if(previousSelectDeliveryMethodId != null && !previousSelectDeliveryMethodId.equals('')) {
// get delivery group method for seletctedDMId
CartDeliveryGroupMethod previousSelectDeliveryMethod = [SELECT Name, ShippingFee, WebCartId, Carrier, ClassOfService, ExternalProvider, ProductId, ReferenceNumber, IsActive, TransitTimeMin, TransitTimeMax, TransitTimeUnit, ProcessTime, ProcessTimeUnit FROM CartDeliveryGroupMethod WHERE Id= :previousSelectDeliveryMethodId];

// return if all fields of shipping option matches with selectedDM else return false
return (previousSelectDeliveryMethod.Name.equals(shippingOption.getName()) && // compare name
previousSelectDeliveryMethod.IsActive.equals(shippingOption.isActive()) && // compare isActive flag

previousSelectDeliveryMethod.ShippingFee.equals(shippingOption.getRate()) && // compare shipping fee

isNullOrEquals(previousSelectDeliveryMethod.ProcessTime, shippingOption.getProcessTime()) && // compare process time
isNullOrEquals(previousSelectDeliveryMethod.ProcessTimeUnit, shippingOption.getProcessTimeUnit()) && // compare time unit

// ideally reference number should match but in this sample we are generating random string so won't match
//previousSelectDeliveryMethod.ReferenceNumber.equals(shippingOption.getReferenceNumber()) &&
previousSelectDeliveryMethod.Carrier.equals(shippingOption.getCarrier()) && // compare carrier
previousSelectDeliveryMethod.ClassOfService.equals(shippingOption.getClassOfService()) &&
previousSelectDeliveryMethod.ExternalProvider.equals(shippingOption.getProvider()) && // compare external provider

isNullOrEquals(previousSelectDeliveryMethod.TransitTimeMax, shippingOption.getTransitTimeMax()) && // compare transit time
isNullOrEquals(previousSelectDeliveryMethod.TransitTimeMin, shippingOption.getTransitTimeMin()) &&
isNullOrEquals(previousSelectDeliveryMethod.TransitTimeUnit, shippingOption.getTransitTimeUnit())); // compare transit time unit
}
// we will return false so DM can be created if no previous selected DM is null
return false;
}

/**
This method compares two objects, if both are null or equals returns true
*/
private boolean isNullOrEquals(Object o1, Object o2) {
return (o1 == null && o2 == null) || (o1 != null && o1.equals(o2));
}

/**
This method provides a sample of how to call an external service to retrieve Shipping Options.
The heroku servie called in this method is just a reference implementation that responds back with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,71 @@ private class B2CDeliverySampleTest {

Test.stopTest();
}

@isTest static void testIntegrationRunsSuccessfully_toRetainPrevSelectedDeliveryMethod() {
Test.startTest();
init();
// Test: execute the integration for the test cart ID.
B2CDeliverySample apexSample = new B2CDeliverySample();
sfdc_checkout.IntegrationInfo integInfo = new sfdc_checkout.IntegrationInfo();
WebCart webCart = [SELECT Id FROM WebCart WHERE Name='Cart' LIMIT 1];
integInfo.jobId = null;
sfdc_checkout.IntegrationStatus integrationResult = apexSample.startCartProcessAsync(integInfo, webCart.Id);
// Verify: the integration executed successfully
System.assertEquals(sfdc_checkout.IntegrationStatus.Status.SUCCESS, integrationResult.status);

List<CartDeliveryGroupMethod> CDGMs = new List<CartDeliveryGroupMethod>([SELECT Id FROM CartDeliveryGroupMethod WHERE WebCartId = :webCart.Id]);
Integer expectedCDGMs = cartDeliveryGroupsNo * expectedCDGMInTheIntegrationMock;
System.assertEquals(expectedCDGMs, CDGMs.size(),'(MultipppleDeliveryGroups/MDG support validation) The expected ' + expectedCDGMs + ' CartDeliveryGroupMethods were not created by the integration');

//Till here first run completed and we got some selected delivery method for each Delivery group
//now we will update our selected delivery method and rerun the calculations and check even post completion of intgration our selected DM should remain same

//fetch all cart delivery groups
List<CartDeliveryGroup> cartDeliveryGroups = new List<CartDeliveryGroup>([SELECT Id FROM CartDeliveryGroup WHERE CartId = :webCart.Id]);

//fetch selected delivery method id for first cdg
Id previousSelectDeliveryMethodId = [SELECT SelectedDeliveryMethodId FROM CartDeliveryGroup WHERE Id = :cartDeliveryGroups[0].Id][0].SelectedDeliveryMethodId;

//find delivery method for same delivery group where id does not match with previous selected DM
List<CartDeliveryGroupMethod> cartDeliveryGroupMethods = new List<CartDeliveryGroupMethod>([SELECT Id FROM cartDeliveryGroupMethod WHERE CartDeliveryGroupId = :cartDeliveryGroups[0].Id]);
String nonSelectedId = null;
for( CartDeliveryGroupMethod cdgm : cartDeliveryGroupMethods) {
if(cdgm.Id != previousSelectDeliveryMethodId) {
nonSelectedId = cdgm.Id;
break;
}
}
//update cart delivery group with updated DM
CartDeliveryGroup cdgToUpdate = cartDeliveryGroups[0];
cdgToUpdate.SelectedDeliveryMethodId = nonSelectedId;
update cdgToUpdate;

// run integration again
integInfo.jobId = null;
integrationResult = apexSample.startCartProcessAsync(integInfo, webCart.Id);
// Verify: the integration executed successfully
System.assertEquals(sfdc_checkout.IntegrationStatus.Status.SUCCESS, integrationResult.status);

//fetch all cart delivery groups
cartDeliveryGroups = new List<CartDeliveryGroup>([SELECT Id FROM CartDeliveryGroup WHERE CartId = :webCart.Id]);
//update cart delivery group with updated DM
cdgToUpdate = cartDeliveryGroups[0];
cdgToUpdate.DeliverToPostalCode = '100001';
update cdgToUpdate;

// run integration again
integInfo.jobId = null;
integrationResult = apexSample.startCartProcessAsync(integInfo, webCart.Id);
// Verify: the integration executed successfully
System.assertEquals(sfdc_checkout.IntegrationStatus.Status.SUCCESS, integrationResult.status);

// verify that newPreviousSelectDeliveryMethodId should match with our selected DM id
Id newPreviousSelectDeliveryMethodId = [SELECT SelectedDeliveryMethodId FROM CartDeliveryGroup WHERE Id = :cartDeliveryGroups[0].Id][0].SelectedDeliveryMethodId;
System.assertEquals(nonSelectedId, newPreviousSelectDeliveryMethodId);

Test.stopTest();
}


}