diff --git a/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSample.cls b/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSample.cls index 602fb1b..db34d14 100644 --- a/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSample.cls +++ b/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSample.cls @@ -39,19 +39,21 @@ public class ShippingCartCalculatorSample extends CartExtension.ShippingCartCalc } else { CartExtension.CartItemList cartItems = cart.getCartItems(); Integer numberOfUniqueItems = cartItems.size(); - + for (Integer i = (cartDeliveryGroups.size() - 1); i >= 0; i--) { CartExtension.CartDeliveryGroup cartDeliveryGroup = cartDeliveryGroups.get(i); CartExtension.CartDeliveryGroupMethodList cartDeliveryGroupMethods = cartDeliveryGroup.getCartDeliveryGroupMethods(); + CartExtension.CartDeliveryGroupMethod selectedDeliveryMethod = cartDeliveryGroup.getSelectedCartDeliveryGroupMethod(); - // Clean up the CartDeliveryGroupMethods + // Clean up the CartDeliveryGroupMethods except already selected Delivery method for (Integer j = (cartDeliveryGroupMethods.size() - 1); j >= 0; j--) { CartExtension.CartDeliveryGroupMethod method = cartDeliveryGroupMethods.get(j); - cartDeliveryGroupMethods.remove(method); + // remove cart delivery group methods if selectedDeliveryMethod is null or delivery method id not matching with selectedDeliveryMethodId + if(selectedDeliveryMethod==null || (selectedDeliveryMethod!=null && !method.getId().equals(selectedDeliveryMethod.getId()))) { + cartDeliveryGroupMethods.remove(method); + } } - // To clear selected Cart Delivery Group Method - cartDeliveryGroup.setSelectedCartDeliveryGroupMethod(null); - + // Get the Shipping Product List shippingProducts = [SELECT Id FROM Product2 WHERE ProductClass != 'VariationParent' LIMIT 1]; if(shippingProducts.size() == 0) { @@ -74,11 +76,23 @@ public class ShippingCartCalculatorSample extends CartExtension.ShippingCartCalc populateCartDeliveryGroupMethodWithShippingOptions( shippingOptionsAndRatesFromExternalService, cartDeliveryGroupMethods,shippingProduct, - cartValidationOutputList + cartValidationOutputList, selectedDeliveryMethod ); } } else { - CartExtension.CartDeliveryGroupMethod cartDeliveryGroupMethod01 = new CartExtension.CartDeliveryGroupMethod('Ground Shipping', 10.99, shippingProduct); + // this block is for static response for sample class + if(selectedDeliveryMethod==null || + (selectedDeliveryMethod!=null && + !('Ground Shipping'.equals(selectedDeliveryMethod.getName()) && + selectedDeliveryMethod.getShippingFee().equals(10.99) && + selectedDeliveryMethod.getCarrier().equals('USPS') && + selectedDeliveryMethod.getClassOfService().equals('Ground Shipping') && + selectedDeliveryMethod.getTransitTimeMin().equals(1) && + selectedDeliveryMethod.getTransitTimeMax().equals(3) && + selectedDeliveryMethod.getTransitTimeUnit().equals(CartExtension.TimeUnitEnum.DAYS) && + selectedDeliveryMethod.getProcessTime().equals(1) && + selectedDeliveryMethod.getProcessTimeUnit().equals(CartExtension.TimeUnitEnum.WEEKS)))) { + CartExtension.CartDeliveryGroupMethod cartDeliveryGroupMethod01 = new CartExtension.CartDeliveryGroupMethod('Ground Shipping', 10.99, shippingProduct); cartDeliveryGroupMethod01.setCarrier('USPS'); cartDeliveryGroupMethod01.setClassOfService('Ground Shipping'); cartDeliveryGroupMethod01.setTransitTimeMin(1); @@ -86,6 +100,20 @@ public class ShippingCartCalculatorSample extends CartExtension.ShippingCartCalc cartDeliveryGroupMethod01.setTransitTimeUnit(CartExtension.TimeUnitEnum.DAYS); cartDeliveryGroupMethod01.setProcessTime(1); cartDeliveryGroupMethod01.setProcessTimeUnit(CartExtension.TimeUnitEnum.WEEKS); + cartDeliveryGroupMethods.add(cartDeliveryGroupMethod01); + } + + if(selectedDeliveryMethod==null || + (selectedDeliveryMethod!=null && + !('Next Day Air'.equals(selectedDeliveryMethod.getName()) && + selectedDeliveryMethod.getShippingFee().equals(15.99) && + selectedDeliveryMethod.getCarrier().equals('UPS') && + selectedDeliveryMethod.getClassOfService().equals('Next Day Air') && + selectedDeliveryMethod.getTransitTimeMin().equals(1) && + selectedDeliveryMethod.getTransitTimeMax().equals(4) && + selectedDeliveryMethod.getTransitTimeUnit().equals(CartExtension.TimeUnitEnum.DAYS) && + selectedDeliveryMethod.getProcessTime().equals(1) && + selectedDeliveryMethod.getProcessTimeUnit().equals(CartExtension.TimeUnitEnum.DAYS)))) { CartExtension.CartDeliveryGroupMethod cartDeliveryGroupMethod02 = new CartExtension.CartDeliveryGroupMethod('Next Day Air', 15.99, shippingProduct); cartDeliveryGroupMethod02.setCarrier('UPS'); cartDeliveryGroupMethod02.setClassOfService('Next Day Air'); @@ -94,8 +122,8 @@ public class ShippingCartCalculatorSample extends CartExtension.ShippingCartCalc cartDeliveryGroupMethod02.setTransitTimeUnit(CartExtension.TimeUnitEnum.DAYS); cartDeliveryGroupMethod02.setProcessTime(1); cartDeliveryGroupMethod02.setProcessTimeUnit(CartExtension.TimeUnitEnum.DAYS); - cartDeliveryGroupMethods.add(cartDeliveryGroupMethod01); cartDeliveryGroupMethods.add(cartDeliveryGroupMethod02); + } } } } @@ -243,29 +271,71 @@ public class ShippingCartCalculatorSample extends CartExtension.ShippingCartCalc List shippingOptions, CartExtension.CartDeliveryGroupMethodList cartDeliveryGroupMethodCollection, String shippingProduct, - CartExtension.CartValidationOutputList cartValidationOutputCollection + CartExtension.CartValidationOutputList cartValidationOutputCollection, + CartExtension.CartDeliveryGroupMethod selectedDeliveryMethod ) { for (ShippingOptionsAndRatesFromExternalService shippingOption : shippingOptions) { - String carrier = shippingOption.serviceName; - String classOfService = shippingOption.provider; - // Create a CartDeliveryGroupMethod for every shipping option returned from the external - // service - CartExtension.CartDeliveryGroupMethod cartDeliveryGroupMethod = new CartExtension.CartDeliveryGroupMethod( - shippingOption.getName(), - shippingOption.getRate(), - shippingProduct - ); - cartDeliveryGroupMethod.setExternalProvider(shippingOption.getProvider()); - cartDeliveryGroupMethod.setCarrier(shippingOption.getCarrier()); - cartDeliveryGroupMethod.setClassOfService(shippingOption.getClassOfService()); - cartDeliveryGroupMethod.setIsActive(shippingOption.isActive()); - cartDeliveryGroupMethod.setReferenceNumber(shippingOption.getReferenceNumber()); - cartDeliveryGroupMethodCollection.add(cartDeliveryGroupMethod); - cartDeliveryGroupMethod.setTransitTimeMin(shippingOption.getTransitTimeMin()); - cartDeliveryGroupMethod.setTransitTimeMax(shippingOption.getTransitTimeMax()); - cartDeliveryGroupMethod.setTransitTimeUnit(shippingOption.getTransitTimeUnit()); - cartDeliveryGroupMethod.setProcessTime(shippingOption.getProcessTime()); - cartDeliveryGroupMethod.setProcessTimeUnit(shippingOption.getProcessTimeUnit()); + //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,selectedDeliveryMethod)){ + String carrier = shippingOption.serviceName; + String classOfService = shippingOption.provider; + // Create a CartDeliveryGroupMethod for every shipping option returned from the external + // service + CartExtension.CartDeliveryGroupMethod cartDeliveryGroupMethod = new CartExtension.CartDeliveryGroupMethod( + shippingOption.getName(), + shippingOption.getRate(), + shippingProduct + ); + cartDeliveryGroupMethod.setExternalProvider(shippingOption.getProvider()); + cartDeliveryGroupMethod.setCarrier(shippingOption.getCarrier()); + cartDeliveryGroupMethod.setClassOfService(shippingOption.getClassOfService()); + cartDeliveryGroupMethod.setIsActive(shippingOption.isActive()); + cartDeliveryGroupMethod.setReferenceNumber(shippingOption.getReferenceNumber()); + cartDeliveryGroupMethodCollection.add(cartDeliveryGroupMethod); + cartDeliveryGroupMethod.setTransitTimeMin(shippingOption.getTransitTimeMin()); + cartDeliveryGroupMethod.setTransitTimeMax(shippingOption.getTransitTimeMax()); + cartDeliveryGroupMethod.setTransitTimeUnit(shippingOption.getTransitTimeUnit()); + cartDeliveryGroupMethod.setProcessTime(shippingOption.getProcessTime()); + cartDeliveryGroupMethod.setProcessTimeUnit(shippingOption.getProcessTimeUnit()); + } } } + + /** + This method compares previous Selected Delivery method with current shipping options and if both matches returns ture + */ + private boolean isShippingOptionMatchingWithSelectedDM(ShippingOptionsAndRatesFromExternalService shippingOption, CartExtension.CartDeliveryGroupMethod previousSelectDeliveryMethod) { + if(previousSelectDeliveryMethod != null) { + // 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.getName().equals(shippingOption.getName()) && // compare name + previousSelectDeliveryMethod.getIsActive().equals(shippingOption.isActive()) && // compare isActive flag + + previousSelectDeliveryMethod.getShippingFee().equals(shippingOption.getRate()) && // compare shipping fee + + isNullOrEquals(previousSelectDeliveryMethod.getProcessTime(), shippingOption.getProcessTime()) && // compare time + isNullOrEquals(previousSelectDeliveryMethod.getProcessTimeUnit(), shippingOption.getProcessTimeUnit()) && // compare time unit + + // ideally reference number should match but in this sample we are generating random string so won't match + //previousSelectDeliveryMethod.getReferenceNumber().equals(shippingOption.getReferenceNumber()) && + previousSelectDeliveryMethod.getCarrier().equals(shippingOption.getCarrier()) && + previousSelectDeliveryMethod.getClassOfService().equals(shippingOption.getClassOfService()) && + previousSelectDeliveryMethod.getExternalProvider().equals(shippingOption.getProvider()) && + + isNullOrEquals(previousSelectDeliveryMethod.getTransitTimeMax(), shippingOption.getTransitTimeMax()) && // compare transit time + isNullOrEquals(previousSelectDeliveryMethod.getTransitTimeMin(), shippingOption.getTransitTimeMin()) && + isNullOrEquals(previousSelectDeliveryMethod.getTransitTimeUnit(), 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)); + } } diff --git a/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSampleTest.cls b/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSampleTest.cls index 51e07f5..5c82b7e 100644 --- a/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSampleTest.cls +++ b/commerce/domain/shipping/cart/calculator/classes/ShippingCartCalculatorSampleTest.cls @@ -58,9 +58,10 @@ global with sharing class ShippingCartCalculatorSampleTest { System.assertEquals('Ground Shipping', deliveryMethod01.getClassOfService()); System.assertEquals(1, deliveryMethod01.getTransitTimeMin()); System.assertEquals(3, deliveryMethod01.getTransitTimeMax()); - System.assertEquals('D', deliveryMethod01.getTransitTimeUnit()); + System.assertEquals('DAYS', deliveryMethod01.getTransitTimeUnit().toString()); System.assertEquals(1, deliveryMethod01.getProcessTime()); - System.assertEquals('W', deliveryMethod01.getProcessTimeUnit()); + System.assertEquals('WEEKS', deliveryMethod01.getProcessTimeUnit().toString()); + CartExtension.CartDeliveryGroupMethod deliveryMethod02 = deliveryMethods.get(1); System.assertEquals(15.99, deliveryMethod02.getShippingFee()); System.assertEquals('Next Day Air', deliveryMethod02.getName()); @@ -68,11 +69,11 @@ global with sharing class ShippingCartCalculatorSampleTest { System.assertEquals('Next Day Air', deliveryMethod02.getClassOfService()); System.assertEquals(1, deliveryMethod02.getTransitTimeMin()); System.assertEquals(4, deliveryMethod02.getTransitTimeMax()); - System.assertEquals('D', deliveryMethod02.getTransitTimeUnit()); + System.assertEquals('DAYS', deliveryMethod02.getTransitTimeUnit().toString()); System.assertEquals(1, deliveryMethod02.getProcessTime()); - System.assertEquals('D', deliveryMethod02.getProcessTimeUnit()); + System.assertEquals('DAYS', deliveryMethod02.getProcessTimeUnit().toString()); } - private Id getDefaultShippingChargeProduct2Id() { + private static Id getDefaultShippingChargeProduct2Id() { // Check to see if a Product2 with name 'Shipping Charge' already exists. // If it doesn't exist, create one. @@ -88,5 +89,76 @@ global with sharing class ShippingCartCalculatorSampleTest { } else { return shippingChargeProducts[0].Id; } + } + + @IsTest + static void testShippingMethodsAreCreated_retainSelectedDeliveryMethod() { + // Arrange + CartExtension.Cart cart = CartExtension.CartTestUtil.createCart(); + getDefaultShippingChargeProduct2Id(); + + // Act + Test.startTest(); + CartExtension.CartCalculateCalculatorRequest request = new CartExtension.CartCalculateCalculatorRequest(cart, CartExtension.OptionalBuyerActionDetails.empty()); + ShippingCartCalculatorSample calculator = new ShippingCartCalculatorSample(); + //calculator.calculate(request); + + // Assert + // Test if no CVO is created + CartExtension.CartValidationOutputList cartValidationOutputs = cart.getCartValidationOutputs(); + System.assertEquals(0, cartValidationOutputs.size()); + + //find prevSelectDeliveryMethod for first cart DG + CartExtension.CartDeliveryGroupList deliveryGroups = cart.getCartDeliveryGroups(); + CartExtension.CartDeliveryGroup deliveryGroup1 = deliveryGroups.get(0); + CartExtension.CartDeliveryGroupMethod prevSelectDeliveryMethod = deliveryGroup1.getSelectedCartDeliveryGroupMethod(); + + //find delivery methods + CartExtension.CartDeliveryGroupMethodList deliveryMethods = deliveryGroup1.getCartDeliveryGroupMethods(); + + //identify the delivery method id which is not matching with the selected delivery method id + CartExtension.CartDeliveryGroupMethod nonMatchingCDGM = null; + for (Integer j = (deliveryMethods.size() - 1); j >= 0; j--) { + CartExtension.CartDeliveryGroupMethod cdgm = deliveryMethods.get(j); + if(prevSelectDeliveryMethod==null || cdgm.getId() != prevSelectDeliveryMethod.getId()) { + nonMatchingCDGM = cdgm; + break; + } } + //udpate cart delivery group with new selected deliver method id which is not matching + deliveryGroup1.setSelectedCartDeliveryGroupMethod(nonMatchingCDGM); + + // call calculator + calculator.calculate(request); + + + // Test if CartDeliveryGroupMethod is created + deliveryGroups = cart.getCartDeliveryGroups(); + + CartExtension.CartDeliveryGroup deliveryGroup = deliveryGroups.get(0); + System.assertEquals(2, deliveryMethods.size()); + CartExtension.CartDeliveryGroupMethod deliveryMethod01 = deliveryMethods.get(0); + System.assertEquals(10.99, deliveryMethod01.getShippingFee()); + System.assertEquals('Ground Shipping', deliveryMethod01.getName()); + System.assertEquals('USPS', deliveryMethod01.getCarrier()); + System.assertEquals('Ground Shipping', deliveryMethod01.getClassOfService()); + System.assertEquals(1, deliveryMethod01.getTransitTimeMin()); + System.assertEquals(3, deliveryMethod01.getTransitTimeMax()); + System.assertEquals('DAYS', deliveryMethod01.getTransitTimeUnit().toString()); + System.assertEquals(1, deliveryMethod01.getProcessTime()); + System.assertEquals('WEEKS', deliveryMethod01.getProcessTimeUnit().toString()); + + CartExtension.CartDeliveryGroupMethod deliveryMethod02 = deliveryMethods.get(1); + System.assertEquals(15.99, deliveryMethod02.getShippingFee()); + System.assertEquals('Next Day Air', deliveryMethod02.getName()); + System.assertEquals('UPS', deliveryMethod02.getCarrier()); + System.assertEquals('Next Day Air', deliveryMethod02.getClassOfService()); + System.assertEquals(1, deliveryMethod02.getTransitTimeMin()); + System.assertEquals(4, deliveryMethod02.getTransitTimeMax()); + System.assertEquals('DAYS', deliveryMethod02.getTransitTimeUnit().toString()); + System.assertEquals(1, deliveryMethod02.getProcessTime()); + System.assertEquals('DAYS', deliveryMethod02.getProcessTimeUnit().toString()); + Test.stopTest(); + } + }