@@ -31,7 +31,10 @@ import {
3131import { useCurrentBasket } from '@salesforce/retail-react-app/app/hooks/use-current-basket'
3232import { useCurrentCustomer } from '@salesforce/retail-react-app/app/hooks/use-current-customer'
3333import { useCurrency } from '@salesforce/retail-react-app/app/hooks'
34- import { isPickupShipment } from '@salesforce/retail-react-app/app/utils/shipment-utils'
34+ import {
35+ isPickupShipment ,
36+ isPickupMethod
37+ } from '@salesforce/retail-react-app/app/utils/shipment-utils'
3538import PropTypes from 'prop-types'
3639import { useToast } from '@salesforce/retail-react-app/app/hooks/use-toast'
3740
@@ -95,16 +98,26 @@ export default function ShippingOptions() {
9598
9699 // Calculate if we should show loading state immediately for auto-selection
97100 const shouldShowInitialLoading = useMemo ( ( ) => {
101+ const filteredMethods =
102+ shippingMethods ?. applicableShippingMethods ?. filter (
103+ ( method ) => ! isPickupMethod ( method )
104+ ) || [ ]
105+ const defaultMethodId = shippingMethods ?. defaultShippingMethodId
106+ const defaultMethod = defaultMethodId
107+ ? shippingMethods . applicableShippingMethods ?. find (
108+ ( method ) => method . id === defaultMethodId
109+ )
110+ : null
111+
98112 return (
99113 step === STEPS . SHIPPING_OPTIONS &&
100114 ! hasAutoSelected &&
101115 customer ?. isRegistered &&
102116 ! selectedShippingMethod ?. id &&
103- shippingMethods ?. applicableShippingMethods ?. length &&
104- shippingMethods . defaultShippingMethodId &&
105- shippingMethods . applicableShippingMethods . find (
106- ( method ) => method . id === shippingMethods . defaultShippingMethodId
107- )
117+ filteredMethods . length > 0 &&
118+ defaultMethodId &&
119+ defaultMethod &&
120+ ! isPickupMethod ( defaultMethod )
108121 )
109122 } , [ step , hasAutoSelected , customer , selectedShippingMethod , shippingMethods ] )
110123
@@ -119,17 +132,36 @@ export default function ShippingOptions() {
119132 } )
120133
121134 useEffect ( ( ) => {
135+ // Filter out pickup methods
136+ const filteredMethods =
137+ shippingMethods ?. applicableShippingMethods ?. filter (
138+ ( method ) => ! isPickupMethod ( method )
139+ ) || [ ]
140+
122141 const defaultMethodId = shippingMethods ?. defaultShippingMethodId
142+ // Only use default if it's not a pickup method
143+ const validDefaultMethodId =
144+ defaultMethodId &&
145+ ! isPickupMethod (
146+ shippingMethods . applicableShippingMethods ?. find ( ( m ) => m . id === defaultMethodId )
147+ )
148+ ? defaultMethodId
149+ : filteredMethods [ 0 ] ?. id
150+
123151 const methodId = form . getValues ( ) . shippingMethodId
124- if ( ! selectedShippingMethod && ! methodId && defaultMethodId ) {
125- form . reset ( { shippingMethodId : defaultMethodId } )
152+ if ( ! selectedShippingMethod && ! methodId && validDefaultMethodId ) {
153+ form . reset ( { shippingMethodId : validDefaultMethodId } )
126154 }
127155
128- if ( selectedShippingMethod && methodId !== selectedShippingMethod . id ) {
156+ if (
157+ selectedShippingMethod &&
158+ ! isPickupMethod ( selectedShippingMethod ) &&
159+ methodId !== selectedShippingMethod . id
160+ ) {
129161 form . reset ( { shippingMethodId : selectedShippingMethod . id } )
130162 }
131163 // If there are no applicable methods for the current address, clear the form selection
132- if ( ! shippingMethods ?. applicableShippingMethods ? .length && methodId ) {
164+ if ( ! filteredMethods . length && methodId ) {
133165 form . reset ( { shippingMethodId : '' } )
134166 }
135167 } , [ selectedShippingMethod , shippingMethods ] )
@@ -142,15 +174,19 @@ export default function ShippingOptions() {
142174 return
143175 }
144176
145- // Wait for shipping methods to load
146- if ( ! shippingMethods ?. applicableShippingMethods ?. length ) {
177+ // Wait for shipping methods to load and filter out pickup methods
178+ const applicable =
179+ shippingMethods ?. applicableShippingMethods ?. filter (
180+ ( method ) => ! isPickupMethod ( method )
181+ ) || [ ]
182+
183+ if ( ! applicable . length ) {
147184 return
148185 }
149186
150- const applicable = shippingMethods . applicableShippingMethods
151-
152187 // If we already have a shipping method on the basket, validate it against the new address' methods.
153- if ( selectedShippingMethod ?. id ) {
188+ // Skip validation if the current method is a pickup method
189+ if ( selectedShippingMethod ?. id && ! isPickupMethod ( selectedShippingMethod ) ) {
154190 const stillValid = applicable . some ( ( m ) => m . id === selectedShippingMethod . id )
155191 setHasAutoSelected ( true )
156192 if ( stillValid ) {
@@ -166,9 +202,17 @@ export default function ShippingOptions() {
166202 return
167203 }
168204
205+ // Find default method, but skip if it's a pickup method
169206 const defaultMethodId = shippingMethods . defaultShippingMethodId
170207 const defaultMethod =
171- applicable . find ( ( method ) => method . id === defaultMethodId ) || applicable [ 0 ]
208+ ( defaultMethodId &&
209+ ! isPickupMethod (
210+ shippingMethods . applicableShippingMethods . find (
211+ ( m ) => m . id === defaultMethodId
212+ )
213+ ) &&
214+ applicable . find ( ( method ) => method . id === defaultMethodId ) ) ||
215+ applicable [ 0 ]
172216
173217 if ( defaultMethod ) {
174218 //Auto-selecting default shipping method
@@ -230,10 +274,12 @@ export default function ShippingOptions() {
230274 shippingItem ?. priceAfterItemDiscount || 0
231275 )
232276
233- const hasApplicableMethods = Boolean (
234- shippingMethods ?. applicableShippingMethods &&
235- shippingMethods . applicableShippingMethods . length > 0
236- )
277+ // Filter out pickup methods for all shipments
278+ const filteredShippingMethods =
279+ shippingMethods ?. applicableShippingMethods ?. filter ( ( method ) => ! isPickupMethod ( method ) ) ||
280+ [ ]
281+
282+ const hasApplicableMethods = Boolean ( filteredShippingMethods . length > 0 )
237283 const isSelectedMethodValid =
238284 hasApplicableMethods &&
239285 Boolean (
@@ -309,7 +355,7 @@ export default function ShippingOptions() {
309355 data-testid = "sf-checkout-shipping-options-form"
310356 >
311357 < Stack spacing = { 6 } >
312- { shippingMethods ?. applicableShippingMethods ? .length > 0 && (
358+ { filteredShippingMethods . length > 0 && (
313359 < Controller
314360 name = "shippingMethodId"
315361 control = { form . control }
@@ -321,47 +367,43 @@ export default function ShippingOptions() {
321367 onChange = { onChange }
322368 >
323369 < Stack spacing = { 5 } >
324- { shippingMethods . applicableShippingMethods . map (
325- ( opt ) => (
326- < Radio value = { opt . id } key = { opt . id } >
327- < Flex justify = "space-between" w = "full" >
328- < Box >
329- < Text > { opt . name } </ Text >
330- < Text
331- fontSize = "sm"
332- color = "gray.600"
333- >
334- { opt . description }
335- </ Text >
336- </ Box >
337- < Text fontWeight = "bold" >
338- < FormattedNumber
339- value = { opt . price }
340- style = "currency"
341- currency = { currency }
342- />
370+ { filteredShippingMethods . map ( ( opt ) => (
371+ < Radio value = { opt . id } key = { opt . id } >
372+ < Flex justify = "space-between" w = "full" >
373+ < Box >
374+ < Text > { opt . name } </ Text >
375+ < Text
376+ fontSize = "sm"
377+ color = "gray.600"
378+ >
379+ { opt . description }
343380 </ Text >
344- </ Flex >
345- { opt . shippingPromotions ?. map (
346- ( promo ) => (
347- < Text
348- key = { promo . promotionId }
349- fontSize = "sm"
350- color = "green.600"
351- >
352- { promo . calloutMsg }
353- </ Text >
354- )
355- ) }
356- </ Radio >
357- )
358- ) }
381+ </ Box >
382+ < Text fontWeight = "bold" >
383+ < FormattedNumber
384+ value = { opt . price }
385+ style = "currency"
386+ currency = { currency }
387+ />
388+ </ Text >
389+ </ Flex >
390+ { opt . shippingPromotions ?. map ( ( promo ) => (
391+ < Text
392+ key = { promo . promotionId }
393+ fontSize = "sm"
394+ color = "green.600"
395+ >
396+ { promo . calloutMsg }
397+ </ Text >
398+ ) ) }
399+ </ Radio >
400+ ) ) }
359401 </ Stack >
360402 </ RadioGroup >
361403 ) }
362404 />
363405 ) }
364- { shippingMethods ?. applicableShippingMethods ? .length > 0 && (
406+ { filteredShippingMethods . length > 0 && (
365407 < Box >
366408 < Container variant = "form" >
367409 < Button w = "full" type = "submit" >
@@ -548,23 +590,32 @@ const ShipmentMethods = ({shipment, index, currency}) => {
548590
549591 useEffect ( ( ) => {
550592 // Only attempt auto-select when there are applicable methods available and we haven't already auto-selected
551- const applicableMethods = methods ?. applicableShippingMethods || [ ]
593+ // Filter out pickup methods for multi-shipments
594+ const applicableMethods =
595+ methods ?. applicableShippingMethods ?. filter ( ( method ) => ! isPickupMethod ( method ) ) || [ ]
552596 const applicableIds = applicableMethods . map ( ( m ) => m . id )
553597 if ( ! applicableIds . length || hasAutoSelected ) {
554598 return
555599 }
556600
557601 // Determine the method to select:
558- // 1. Use existing shipment method if still valid
559- // 2. Use default shipping method if available
602+ // 1. Use existing shipment method if still valid (and not pickup)
603+ // 2. Use default shipping method if available (and not pickup)
560604 // 3. Fall back to first available method
561605 const existingMethodId =
562- shipment ?. shippingMethod ?. id && applicableIds . includes ( shipment . shippingMethod . id )
606+ shipment ?. shippingMethod ?. id &&
607+ ! isPickupMethod ( shipment . shippingMethod ) &&
608+ applicableIds . includes ( shipment . shippingMethod . id )
563609 ? shipment . shippingMethod . id
564610 : undefined
565611 const defaultMethodId =
566612 methods ?. defaultShippingMethodId &&
567- applicableIds . includes ( methods . defaultShippingMethodId )
613+ applicableIds . includes ( methods . defaultShippingMethodId ) &&
614+ ! isPickupMethod (
615+ methods . applicableShippingMethods . find (
616+ ( m ) => m . id === methods . defaultShippingMethodId
617+ )
618+ )
568619 ? methods . defaultShippingMethodId
569620 : undefined
570621 const firstMethodId = applicableMethods [ 0 ] ?. id
@@ -618,53 +669,64 @@ const ShipmentMethods = ({shipment, index, currency}) => {
618669 </ Text >
619670 ) }
620671
621- { methods ?. applicableShippingMethods ?. length > 0 && (
622- < RadioGroup
623- name = { `shipping-options-${ shipment . shipmentId } ` }
624- value = { selected }
625- onChange = { async ( val ) => {
626- setSelected ( val )
627- try {
628- await updateShippingMethod . mutateAsync ( {
629- parameters : {
630- basketId : basket . basketId ,
631- shipmentId : shipment . shipmentId
632- } ,
633- body : { id : val }
634- } )
635- } catch {
636- // Ignore; allow user to retry selection
637- }
638- } }
639- >
640- < Stack spacing = { 5 } >
641- { methods . applicableShippingMethods . map ( ( opt ) => (
642- < Radio value = { opt . id } key = { opt . id } >
643- < Flex justify = "space-between" w = "full" >
644- < Box >
645- < Text > { opt . name } </ Text >
646- < Text fontSize = "sm" color = "gray.600" >
647- { opt . description }
672+ { ( ( ) => {
673+ // Filter out pickup methods for multi-shipments
674+ const filteredMethods =
675+ methods ?. applicableShippingMethods ?. filter (
676+ ( method ) => ! isPickupMethod ( method )
677+ ) || [ ]
678+ return filteredMethods . length > 0 ? (
679+ < RadioGroup
680+ name = { `shipping-options-${ shipment . shipmentId } ` }
681+ value = { selected }
682+ onChange = { async ( val ) => {
683+ setSelected ( val )
684+ try {
685+ await updateShippingMethod . mutateAsync ( {
686+ parameters : {
687+ basketId : basket . basketId ,
688+ shipmentId : shipment . shipmentId
689+ } ,
690+ body : { id : val }
691+ } )
692+ } catch {
693+ // Ignore; allow user to retry selection
694+ }
695+ } }
696+ >
697+ < Stack spacing = { 5 } >
698+ { filteredMethods . map ( ( opt ) => (
699+ < Radio value = { opt . id } key = { opt . id } >
700+ < Flex justify = "space-between" w = "full" >
701+ < Box >
702+ < Text > { opt . name } </ Text >
703+ < Text fontSize = "sm" color = "gray.600" >
704+ { opt . description }
705+ </ Text >
706+ </ Box >
707+ < Text fontWeight = "bold" >
708+ < FormattedNumber
709+ value = { opt . price }
710+ style = "currency"
711+ currency = { currency }
712+ />
648713 </ Text >
649- </ Box >
650- < Text fontWeight = "bold" >
651- < FormattedNumber
652- value = { opt . price }
653- style = "currency"
654- currency = { currency }
655- />
656- </ Text >
657- </ Flex >
658- { opt . shippingPromotions ?. map ( ( promo ) => (
659- < Text key = { promo . promotionId } fontSize = "sm" color = "green.600" >
660- { promo . calloutMsg }
661- </ Text >
662- ) ) }
663- </ Radio >
664- ) ) }
665- </ Stack >
666- </ RadioGroup >
667- ) }
714+ </ Flex >
715+ { opt . shippingPromotions ?. map ( ( promo ) => (
716+ < Text
717+ key = { promo . promotionId }
718+ fontSize = "sm"
719+ color = "green.600"
720+ >
721+ { promo . calloutMsg }
722+ </ Text >
723+ ) ) }
724+ </ Radio >
725+ ) ) }
726+ </ Stack >
727+ </ RadioGroup >
728+ ) : null
729+ } ) ( ) }
668730
669731 < Box mt = { 4 } >
670732 < Button variant = "link" size = "sm" rightIcon = { < ChevronDownIcon /> } >
0 commit comments