From 8888d067f4813b27b23d21029072cd907b3e6e16 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Tue, 19 Aug 2025 10:04:11 +0530 Subject: [PATCH 01/49] changes for deliveryMode=pickup --- ...out-billing-address-form.component.spec.ts | 12 ++- ...checkout-billing-address-form.component.ts | 9 +- ...ckout-billing-address-form.service.spec.ts | 39 ++++++- ...f-checkout-billing-address-form.service.ts | 100 +++++++++++++++--- 4 files changed, 141 insertions(+), 19 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts index 0a27736e2a0..ba1172a0ba1 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts @@ -5,15 +5,17 @@ import { Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Address, Country } from '@spartacus/core'; -import { BehaviorSubject, EMPTY, Observable, of } from 'rxjs'; +import { Address, Country, UserAddressAdapter } from '@spartacus/core'; +import { BehaviorSubject, EMPTY, Observable, of, Subject } from 'rxjs'; import { OpfCheckoutBillingAddressFormComponent } from './opf-checkout-billing-address-form.component'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; +import { Store } from '@ngrx/store'; class Service { billingAddress$ = new BehaviorSubject
(undefined); isLoadingAddress$ = new BehaviorSubject(false); isSameAsDelivery$ = new BehaviorSubject(true); + pickupNoDefaultAddress$ = new Subject(); getCountries(): Observable { return EMPTY; @@ -38,6 +40,7 @@ class Service { setIsSameAsDeliveryValue(value: boolean): void { this.isSameAsDelivery$.next(value); } + setPickupDeliveryModeForPickupItems(): void {} } @Pipe({ @@ -61,6 +64,8 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { provide: OpfCheckoutBillingAddressFormService, useClass: Service, }, + { provide: Store, useValue: {} }, + { provide: UserAddressAdapter, useValue: {} }, ], }).compileComponents(); @@ -78,12 +83,15 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { const countries = [{ id: '1', name: 'Country 1' }]; spyOn(service, 'getCountries').and.returnValue(of(countries)); spyOn(service, 'getAddresses'); + spyOn(service, 'setPickupDeliveryModeForPickupItems'); component.ngOnInit(); expect(component.countries$).toBeDefined(); expect(service.getCountries).toHaveBeenCalled(); expect(service.getAddresses).toHaveBeenCalled(); + expect(service.setPickupDeliveryModeForPickupItems).toHaveBeenCalled(); + }); it('should cancel and hide form on cancelAndHideForm', () => { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 8c23c23a964..d4356e32300 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -14,7 +14,7 @@ import { Address, Country } from '@spartacus/core'; import { ICON_TYPE } from '@spartacus/storefront'; import { Observable } from 'rxjs'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; - +import { UserAddressService } from '@spartacus/core'; @Component({ selector: 'cx-opf-checkout-billing-address-form', templateUrl: './opf-checkout-billing-address-form.component.html', @@ -23,6 +23,7 @@ import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-add }) export class OpfCheckoutBillingAddressFormComponent implements OnInit { protected service = inject(OpfCheckoutBillingAddressFormService); + protected userAddressService = inject(UserAddressService); iconTypes = ICON_TYPE; @@ -37,7 +38,13 @@ export class OpfCheckoutBillingAddressFormComponent implements OnInit { ngOnInit() { this.countries$ = this.service.getCountries(); + this.userAddressService.loadAddresses(); + this.service.setPickupDeliveryModeForPickupItems(); this.service.getAddresses(); + this.service.pickupNoDefaultAddress$.subscribe(() => { + this.isEditBillingAddress = true; + this.isAddingBillingAddressInProgress = true; + }); } cancelAndHideForm(): void { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index d5c2d26c6d6..02e378e0113 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -13,11 +13,13 @@ import { Address, GlobalMessageService, HttpErrorModel, + UserAddressAdapter, UserPaymentService, } from '@spartacus/core'; -import { of, throwError } from 'rxjs'; +import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; +import { Store } from '@ngrx/store'; describe('OpfCheckoutBillingAddressFormService', () => { let service: OpfCheckoutBillingAddressFormService; @@ -27,6 +29,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { let mockActiveCartFacade: Partial; let mockGlobalMessageService: Partial; let mockOpfCheckoutPaymentWrapperService: Partial; + let mockPickupNoDefaultAddress$: BehaviorSubject; const mockDeliveryAddress: Address = { id: '123', @@ -64,6 +67,8 @@ describe('OpfCheckoutBillingAddressFormService', () => { reloadPaymentMode: () => {}, }; + mockPickupNoDefaultAddress$ = new BehaviorSubject(undefined); + TestBed.configureTestingModule({ providers: [ OpfCheckoutBillingAddressFormService, @@ -82,6 +87,12 @@ describe('OpfCheckoutBillingAddressFormService', () => { provide: OpfCheckoutPaymentWrapperService, useValue: mockOpfCheckoutPaymentWrapperService, }, + { provide: Store, useValue: {} }, + { provide: UserAddressAdapter, useValue: {} }, + { + provide: '_pickupNoDefaultAddress$', + useValue: mockPickupNoDefaultAddress$, + }, ], }); @@ -251,4 +262,30 @@ describe('OpfCheckoutBillingAddressFormService', () => { expect(service.setBillingAddress).not.toHaveBeenCalled(); }); + + it('should return an observable from pickupNoDefaultAddress$', () => { + spyOn(mockPickupNoDefaultAddress$, 'asObservable').and.callThrough(); + + (service as any)._pickupNoDefaultAddress$ = mockPickupNoDefaultAddress$; + + const result: Observable = service.pickupNoDefaultAddress$; + + expect(mockPickupNoDefaultAddress$.asObservable).toHaveBeenCalled(); + expect(result).toEqual(mockPickupNoDefaultAddress$.asObservable()); + }); + + it('should set pickup delivery mode for pickup items', () => { + spyOn(service, 'setPickupDeliveryModeForPickupItems').and.callThrough(); + spyOn( + mockOpfCheckoutPaymentWrapperService, + 'reloadPaymentMode' + ).and.callThrough(); + + service.setPickupDeliveryModeForPickupItems(); + + expect(service.setPickupDeliveryModeForPickupItems).toHaveBeenCalled(); + expect( + mockOpfCheckoutPaymentWrapperService.reloadPaymentMode + ).toHaveBeenCalled(); + }); }); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index d6beab86285..f3e036c24cb 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: Apache-2.0 */ - import { Injectable, inject } from '@angular/core'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; import { CheckoutBillingAddressFacade, CheckoutDeliveryAddressFacade, + CheckoutDeliveryModesFacade, CheckoutPaymentFacade, } from '@spartacus/checkout/base/root'; import { @@ -23,7 +23,9 @@ import { BehaviorSubject, EMPTY, Observable, + Subject, combineLatest, + of, throwError, } from 'rxjs'; import { @@ -37,12 +39,15 @@ import { tap, } from 'rxjs/operators'; import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; +import { PickupOptionFacade } from '@spartacus/pickup-in-store/root'; +import { UserAddressService } from '@spartacus/core'; @Injectable() export class OpfCheckoutBillingAddressFormService { protected checkoutDeliveryAddressFacade = inject( CheckoutDeliveryAddressFacade ); + protected checkoutDeliveryModesFacade = inject(CheckoutDeliveryModesFacade); protected checkoutBillingAddressFacade = inject(CheckoutBillingAddressFacade); protected userPaymentService = inject(UserPaymentService); protected checkoutPaymentService = inject(CheckoutPaymentFacade); @@ -51,13 +56,17 @@ export class OpfCheckoutBillingAddressFormService { protected opfCheckoutPaymentWrapperService = inject( OpfCheckoutPaymentWrapperService ); - + protected _pickupNoDefaultAddress$ = new Subject(); + protected pickupOptionFacade = inject(PickupOptionFacade); + public hasdefaultaddress = true; + protected userAddressService = inject(UserAddressService); protected readonly _$billingAddressSub = new BehaviorSubject< Address | undefined >(undefined); protected readonly _$isLoadingAddress = new BehaviorSubject(false); protected readonly _$isSameAsDelivery = new BehaviorSubject(true); protected billingAddressId: string | undefined; + protected hasPickupItems: Boolean; billingAddress$ = this._$billingAddressSub.asObservable(); isLoadingAddress$ = this._$isLoadingAddress.asObservable(); @@ -75,30 +84,91 @@ export class OpfCheckoutBillingAddressFormService { ); } + get pickupNoDefaultAddress$(): Observable { + return this._pickupNoDefaultAddress$.asObservable(); + } + + setPickupDeliveryModeForPickupItems(): void { + this.activeCartService + .hasPickupItems() + .pipe( + take(1), + filter(Boolean), + tap(() => (this.hasPickupItems = true)), + switchMap(() => + this.checkoutDeliveryModesFacade.getSelectedDeliveryModeState().pipe( + take(1), + map((mode) => mode.data?.code), + filter((currentMode) => !currentMode), + switchMap(() => + this.checkoutDeliveryModesFacade.setDeliveryMode('pickup') + ) + ) + ) + ) + .subscribe({ + next: () => console.log('Delivery mode set to pickup'), + error: (err) => console.error('Error setting delivery mode:', err), + }); + } + + private handleNoDefaultAddress(): void { + this.setIsSameAsDeliveryValue(false); + this._pickupNoDefaultAddress$.next(); + } + getAddresses(): void { this._$isLoadingAddress.next(true); combineLatest([this.getDeliveryAddress(), this.getPaymentAddress()]) - .pipe(take(1)) - .subscribe( - ([deliveryAddress, paymentAddress]: [ - Address | undefined, - Address | undefined, - ]) => { + .pipe( + take(1), + switchMap( + ([deliveryAddress, paymentAddress]: [ + Address | undefined, + Address | undefined, + ]) => { + if (this.hasPickupItems) { + return this.userAddressService.getAddresses().pipe( + take(1), + tap((addresses) => { + if (addresses.length === 0) { + console.log('No addresses found in address book.'); + this.handleNoDefaultAddress(); + } + }), + map((addresses) => + addresses.find((address) => address.defaultAddress) + ), + tap((defaultAddress) => { + if (defaultAddress) { + console.log('Default address found:', defaultAddress); + this.setBillingAddress(defaultAddress); + this._$billingAddressSub.next(defaultAddress); + } else { + console.log('No default address found.'); + this.handleNoDefaultAddress(); + } + }), + map(() => [deliveryAddress, paymentAddress]) + ); + } + return of([deliveryAddress, paymentAddress]); + } + ), + tap(([deliveryAddress, paymentAddress]) => { if (!paymentAddress && !!deliveryAddress) { this.setBillingAddress(deliveryAddress); this._$billingAddressSub.next(deliveryAddress); - } - - if (!!paymentAddress && !!deliveryAddress) { + } else if (!!paymentAddress && !!deliveryAddress) { this.billingAddressId = paymentAddress.id; this._$billingAddressSub.next(paymentAddress); this._$isSameAsDelivery.next(false); } - - this._$isLoadingAddress.next(false); - } - ); + }), + finalize(() => this._$isLoadingAddress.next(false)) + ) + .subscribe(); } setDeliveryAddressAsPaymentAddress(): void { From 1152a99f55867f1eb2eccaaac163e8297d4a2831 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 20 Aug 2025 18:47:54 +0530 Subject: [PATCH 02/49] test cases --- ...ckout-billing-address-form.service.spec.ts | 120 +++++++++++++++--- ...f-checkout-billing-address-form.service.ts | 3 + 2 files changed, 105 insertions(+), 18 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index 02e378e0113..f8e195ae598 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -8,6 +8,7 @@ import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; import { CheckoutBillingAddressFacade, CheckoutDeliveryAddressFacade, + CheckoutDeliveryModesFacade, } from '@spartacus/checkout/base/root'; import { Address, @@ -16,7 +17,7 @@ import { UserAddressAdapter, UserPaymentService, } from '@spartacus/core'; -import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; +import { BehaviorSubject, of, throwError } from 'rxjs'; import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { Store } from '@ngrx/store'; @@ -30,6 +31,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { let mockGlobalMessageService: Partial; let mockOpfCheckoutPaymentWrapperService: Partial; let mockPickupNoDefaultAddress$: BehaviorSubject; + let mockCheckoutDeliveryModesFacade: any; const mockDeliveryAddress: Address = { id: '123', @@ -57,6 +59,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { reloadActiveCart: () => of(true), isStable: () => of(true), getActive: () => of({ sapBillingAddress: mockPaymentAddress } as Cart), + hasPickupItems: () => of(true), }; mockGlobalMessageService = { @@ -69,6 +72,13 @@ describe('OpfCheckoutBillingAddressFormService', () => { mockPickupNoDefaultAddress$ = new BehaviorSubject(undefined); + mockCheckoutDeliveryModesFacade = { + getSelectedDeliveryModeState: jasmine + .createSpy() + .and.returnValue(of({ data: {} })), + setDeliveryMode: jasmine.createSpy().and.returnValue(of(true)), + }; + TestBed.configureTestingModule({ providers: [ OpfCheckoutBillingAddressFormService, @@ -93,6 +103,10 @@ describe('OpfCheckoutBillingAddressFormService', () => { provide: '_pickupNoDefaultAddress$', useValue: mockPickupNoDefaultAddress$, }, + { + provide: CheckoutDeliveryModesFacade, + useValue: mockCheckoutDeliveryModesFacade, + }, ], }); @@ -263,29 +277,99 @@ describe('OpfCheckoutBillingAddressFormService', () => { expect(service.setBillingAddress).not.toHaveBeenCalled(); }); - it('should return an observable from pickupNoDefaultAddress$', () => { - spyOn(mockPickupNoDefaultAddress$, 'asObservable').and.callThrough(); - - (service as any)._pickupNoDefaultAddress$ = mockPickupNoDefaultAddress$; - - const result: Observable = service.pickupNoDefaultAddress$; - - expect(mockPickupNoDefaultAddress$.asObservable).toHaveBeenCalled(); - expect(result).toEqual(mockPickupNoDefaultAddress$.asObservable()); + it('should return pickupNoDefaultAddress$ observable', (done) => { + service.pickupNoDefaultAddress$.subscribe(() => { + expect(true).toBe(true); + done(); + }); + (service as any)._pickupNoDefaultAddress$.next(); }); it('should set pickup delivery mode for pickup items', () => { - spyOn(service, 'setPickupDeliveryModeForPickupItems').and.callThrough(); - spyOn( - mockOpfCheckoutPaymentWrapperService, - 'reloadPaymentMode' - ).and.callThrough(); + service.setPickupDeliveryModeForPickupItems(); + expect( + mockCheckoutDeliveryModesFacade.setDeliveryMode + ).toHaveBeenCalledWith('pickup'); + }); + it('should set pickup delivery mode when cart has pickup items and no current mode', () => { + spyOn(mockActiveCartFacade, 'hasPickupItems').and.returnValue(of(true)); + mockCheckoutDeliveryModesFacade.getSelectedDeliveryModeState.and.returnValue( + of({ data: {} }) + ); service.setPickupDeliveryModeForPickupItems(); + expect( + mockCheckoutDeliveryModesFacade.setDeliveryMode + ).toHaveBeenCalledWith('pickup'); + expect(service['hasPickupItems']).toBe(true); + }); - expect(service.setPickupDeliveryModeForPickupItems).toHaveBeenCalled(); + it('should not set delivery mode if cart has no pickup items', () => { + spyOn(mockActiveCartFacade, 'hasPickupItems').and.returnValue(of(false)); + mockCheckoutDeliveryModesFacade.setDeliveryMode.calls.reset(); + service.setPickupDeliveryModeForPickupItems(); expect( - mockOpfCheckoutPaymentWrapperService.reloadPaymentMode - ).toHaveBeenCalled(); + mockCheckoutDeliveryModesFacade.setDeliveryMode + ).not.toHaveBeenCalled(); + }); + + it('should handle no default address by setting isSameAsDelivery=false and emitting pickupNoDefaultAddress$', (done) => { + spyOn(service, 'setIsSameAsDeliveryValue').and.callThrough(); + service.pickupNoDefaultAddress$.subscribe(() => { + expect(service.setIsSameAsDeliveryValue).toHaveBeenCalledWith(false); + done(); + }); + (service as any).handleNoDefaultAddress(); + }); + + it('should handle no addresses found in address book', () => { + service['hasPickupItems'] = true; + spyOn(service['userAddressService'], 'getAddresses').and.returnValue( + of([]) + ); + spyOn(service as any, 'handleNoDefaultAddress'); + + service.getAddresses(); + + expect(service['handleNoDefaultAddress']).toHaveBeenCalled(); + }); + it('should use default address if available', () => { + service['hasPickupItems'] = true; + + const defaultAddress = { id: 'A1', defaultAddress: true } as Address; + service['hasPickupItems'] = true; + + spyOn(service['_$billingAddressSub'], 'next'); + + spyOn(service['userAddressService'], 'getAddresses').and.returnValue( + of([defaultAddress]) + ); + spyOn(service, 'setBillingAddress').and.returnValue(of(defaultAddress)); + + service.getAddresses(); + + expect(service['_$billingAddressSub'].next).toHaveBeenCalledWith( + jasmine.objectContaining({ id: 'A1', defaultAddress: true }) + ); + }); + + it('should handle no default address in address book', () => { + service['hasPickupItems'] = true; + + spyOn(service['_$billingAddressSub'], 'next'); + spyOn(service as any, 'handleNoDefaultAddress'); + + spyOn(service as any, 'getDeliveryAddress').and.returnValue( + of({ id: '123' } as Address) + ); + spyOn(service as any, 'getPaymentAddress').and.returnValue(of(undefined)); + + spyOn(service['userAddressService'], 'getAddresses').and.returnValue( + of([{ id: 'A1' }]) + ); + service.getAddresses(); + + expect(service['_$billingAddressSub'].next).toHaveBeenCalledWith(undefined); + expect(service['handleNoDefaultAddress']).toHaveBeenCalled(); }); }); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index f3e036c24cb..245369496ea 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -147,6 +147,9 @@ export class OpfCheckoutBillingAddressFormService { this._$billingAddressSub.next(defaultAddress); } else { console.log('No default address found.'); + this._$billingAddressSub.next(undefined); + this.billingAddressId = undefined; + this._$isSameAsDelivery.next(false); this.handleNoDefaultAddress(); } }), From a17a828d34b278fb42be5152a843594a15f9e494 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 20 Aug 2025 13:25:49 +0000 Subject: [PATCH 03/49] Add license header --- .../opf-checkout-billing-address-form.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index 245369496ea..84672f7020b 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ + import { Injectable, inject } from '@angular/core'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; import { From 4bdd9f4be591b166c1787b2a25f020c6ff308655 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 3 Sep 2025 14:40:16 +0530 Subject: [PATCH 04/49] fixing the cart item count --- .../opf-checkout-review-cart-details.component.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html index be3b01f63ea..d7e91526077 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html @@ -1,6 +1,12 @@
{{ - 'cartItems.cartTotal' | cxTranslate: { count: cart?.deliveryItemsQuantity } + 'cartItems.cartTotal' + | cxTranslate + : { + count: + (cart?.pickupItemsQuantity ?? 0) + + (cart?.deliveryItemsQuantity ?? 0), + } }}: {{ cart?.totalPrice?.formattedValue }}
From aacefa029fa6cdb4be1c8d4e4914ee3225429d93 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Fri, 5 Sep 2025 16:02:13 +0530 Subject: [PATCH 05/49] chore(ui): update shipping address and delivery method components as per ui design --- ...checkout-payment-and-review.component.html | 20 ---------------- ...heckout-review-cart-details.component.html | 23 +++++++++++++++++-- ...-checkout-review-cart-details.component.ts | 10 ++++---- ...opf-checkout-review-cart-details.module.ts | 9 +++++--- .../_opf-checkout-payment-and-review.scss | 1 + 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.html b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.html index 9570e9cecb1..9c4d377e014 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.html @@ -3,26 +3,6 @@ value: explicitTermsAndConditions$ | async, } as explicitTermsAndConditions" > -
- - - -
- {{ 'opfCheckout.itemsToBeShipped' | cxTranslate }} +
+ + + + +
*:last-child:nth-child(odd) { flex: 1 1 100%; From 8291d2badca2ba9385ec4e8c710d05f74d0fb4b7 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Sun, 7 Sep 2025 17:36:27 +0530 Subject: [PATCH 06/49] adding pickup address card --- ...opf-checkout-review-cart-details.component.html | 14 +++++++------- .../opf-checkout-review-cart-details.module.ts | 4 +++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html index 5e140de3abc..e73c2c4ca06 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html @@ -3,8 +3,7 @@ 'cartItems.cartTotal' | cxTranslate : { - count: - (cart?.totalItems ?? 0) + count: cart?.totalItems ?? 0, } }}: {{ cart?.totalPrice?.formattedValue }} @@ -18,17 +17,19 @@ " > + +
{{ 'opfCheckout.itemsToBeShipped' | cxTranslate }}
-
+
- -
+
Date: Mon, 8 Sep 2025 16:15:18 +0530 Subject: [PATCH 07/49] changes for billing address and deliverymode for pickup items --- .../guards/checkout-steps-set.guard.ts | 16 +- ...eckout-billing-address-form.component.html | 2 +- ...checkout-billing-address-form.component.ts | 7 +- ...f-checkout-billing-address-form.service.ts | 144 +++++++----------- ...heckout-review-cart-details.component.html | 4 +- .../src/user/facade/user-address.service.ts | 24 ++- 6 files changed, 97 insertions(+), 100 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts index 001d45193cd..01501c0474d 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts @@ -4,14 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { inject, Injectable, isDevMode, OnDestroy } from '@angular/core'; import { ActivatedRouteSnapshot, GuardResult, Router, UrlTree, } from '@angular/router'; -import { ActiveCartFacade } from '@spartacus/cart/base/root'; import { CheckoutDeliveryAddressFacade, CheckoutDeliveryModesFacade, @@ -19,8 +17,9 @@ import { CheckoutStep, CheckoutStepType, } from '@spartacus/checkout/base/root'; +import { Injectable, OnDestroy, inject, isDevMode } from '@angular/core'; import { LoggerService, RoutingConfigService } from '@spartacus/core'; -import { Observable, of, Subscription } from 'rxjs'; +import { Observable, Subscription, of } from 'rxjs'; import { distinctUntilChanged, filter, @@ -28,6 +27,8 @@ import { switchMap, take, } from 'rxjs/operators'; + +import { ActiveCartFacade } from '@spartacus/cart/base/root'; import { CheckoutStepService } from '../services/checkout-step.service'; @Injectable({ @@ -36,7 +37,7 @@ import { CheckoutStepService } from '../services/checkout-step.service'; export class CheckoutStepsSetGuard implements OnDestroy { protected subscription: Subscription; protected logger = inject(LoggerService); - + protected hasDeliveryItemsInCart: Boolean; constructor( protected checkoutStepService: CheckoutStepService, protected routingConfigService: RoutingConfigService, @@ -50,6 +51,7 @@ export class CheckoutStepsSetGuard implements OnDestroy { .hasDeliveryItems() .pipe(distinctUntilChanged()) .subscribe((hasDeliveryItems) => { + this.hasDeliveryItemsInCart = hasDeliveryItems; this.checkoutStepService.disableEnableStep( CheckoutStepType.DELIVERY_ADDRESS, !hasDeliveryItems @@ -104,6 +106,12 @@ export class CheckoutStepsSetGuard implements OnDestroy { } protected isStepSet(step: CheckoutStep): Observable { + // If step is undefined/null, check if cart contains only pickup items and set delivery mode + if (!this.hasDeliveryItemsInCart) { + this.checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress(); + this.checkoutDeliveryModesFacade.setDeliveryMode('pickup'); + return of(true); + } if (step && !step.disabled) { switch (step.type[0]) { case CheckoutStepType.DELIVERY_ADDRESS: { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html index 92504a6cac0..0df8acf7c3d 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html @@ -8,7 +8,7 @@

{{ 'opfCheckout.billingAddress' | cxTranslate }}

} as addressData" >
-
+
diff --git a/projects/core/src/user/facade/user-address.service.ts b/projects/core/src/user/facade/user-address.service.ts index d1b5a75d1cb..cfd01e8cff7 100644 --- a/projects/core/src/user/facade/user-address.service.ts +++ b/projects/core/src/user/facade/user-address.service.ts @@ -4,11 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Injectable } from '@angular/core'; -import { select, Store } from '@ngrx/store'; -import { Observable } from 'rxjs'; -import { map, switchMap } from 'rxjs/operators'; -import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; import { Address, AddressValidation, @@ -19,10 +14,16 @@ import { Command, CommandService, } from '../../util/command-query/command.service'; -import { UserAddressConnector } from '../connectors/address/user-address.connector'; +import { Store, select } from '@ngrx/store'; +import { map, switchMap } from 'rxjs/operators'; + +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { StateWithUser } from '../store/user-state'; import { UserActions } from '../store/actions/index'; +import { UserAddressConnector } from '../connectors/address/user-address.connector'; +import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; import { UsersSelectors } from '../store/selectors/index'; -import { StateWithUser } from '../store/user-state'; @Injectable({ providedIn: 'root', @@ -107,6 +108,15 @@ export class UserAddressService { }); } + /** + * Returns the default address + */ + getDefaultAddress(): Observable
{ + return this.getAddresses().pipe( + map((addresses) => addresses.find((address) => address.defaultAddress)) + ); + } + /** * Returns addresses */ From a07f42ef8c8740c5499e983a0e66e68fa3cdf3d4 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 10 Sep 2025 10:30:46 +0530 Subject: [PATCH 08/49] Test cases for BOPIS changes --- .../guards/checkout-steps-set.guard.spec.ts | 38 +++++ .../guards/checkout-steps-set.guard.ts | 1 - .../services/opf-endpoints.service.spec.ts | 6 +- ...out-billing-address-form.component.spec.ts | 22 ++- ...ckout-billing-address-form.service.spec.ts | 145 ++++++------------ ...f-checkout-billing-address-form.service.ts | 5 +- ...kout-review-cart-details.component.spec.ts | 62 +++++--- .../user/facade/user-address.service.spec.ts | 55 +++++-- 8 files changed, 193 insertions(+), 141 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts index b3a31dc76c5..ac3bea8b8bc 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts @@ -79,6 +79,7 @@ class MockCheckoutDeliveryAddressFacade getDeliveryAddressState = createSpy().and.returnValue( of({ loading: false, error: false, data: undefined }) ); + clearCheckoutDeliveryAddress = createSpy(); } class MockCheckoutDeliveryModesFacade @@ -298,4 +299,41 @@ describe(`CheckoutStepsSetGuard`, () => { }); }); }); + +describe('pickup only cart (no delivery items)', () => { + beforeEach(() => { + // Simulate a cart with only pickup items + hasDeliveryItems$.next(false); + // Reset spies + (checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy).calls.reset(); + (checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy).calls.reset(); + }); + + it('should clear delivery address, set delivery mode to pickup, and return true for any step', (done) => { + guard.canActivate({ url: ['checkout', 'route2'] }).subscribe((result) => { + expect(checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).toHaveBeenCalled(); + expect(checkoutDeliveryModesFacade.setDeliveryMode).toHaveBeenCalledWith('pickup'); + expect(result).toBe(true); + done(); + }); + }); +}); + +describe('cart with delivery items', () => { + beforeEach(() => { + // Simulate a cart with delivery items + hasDeliveryItems$.next(true); + // Reset spies + (checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy).calls.reset(); + (checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy).calls.reset(); + }); + + it('should NOT clear delivery address or set delivery mode for any step', (done) => { + guard.canActivate({ url: ['checkout', 'route2'] }).subscribe(() => { + expect(checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).not.toHaveBeenCalled(); + expect(checkoutDeliveryModesFacade.setDeliveryMode).not.toHaveBeenCalled(); + done(); + }); + }); +}); }); diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts index 01501c0474d..aa445590422 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts @@ -106,7 +106,6 @@ export class CheckoutStepsSetGuard implements OnDestroy { } protected isStepSet(step: CheckoutStep): Observable { - // If step is undefined/null, check if cart contains only pickup items and set delivery mode if (!this.hasDeliveryItemsInCart) { this.checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress(); this.checkoutDeliveryModesFacade.setDeliveryMode('pickup'); diff --git a/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts b/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts index c5471702ab1..7acb8fbab1d 100644 --- a/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts +++ b/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { TestBed } from '@angular/core/testing'; -import { of } from 'rxjs'; - import { BaseSiteService, StringTemplate } from '@spartacus/core'; import { OpfApiConfig, OpfConfig } from '@spartacus/opf/base/root'; + import { OpfEndpointsService } from './opf-endpoints.service'; +import { TestBed } from '@angular/core/testing'; +import { of } from 'rxjs'; describe('OpfEndpointsService', () => { let service: OpfEndpointsService; diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts index ba1172a0ba1..1caaa63de63 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts @@ -3,10 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Pipe, PipeTransform } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Address, Country, UserAddressAdapter } from '@spartacus/core'; -import { BehaviorSubject, EMPTY, Observable, of, Subject } from 'rxjs'; +import { BehaviorSubject, EMPTY, Observable, Subject, of } from 'rxjs'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Pipe, PipeTransform } from '@angular/core'; + +import { ActiveCartFacade } from '@spartacus/cart/base/root'; import { OpfCheckoutBillingAddressFormComponent } from './opf-checkout-billing-address-form.component'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { Store } from '@ngrx/store'; @@ -40,7 +42,7 @@ class Service { setIsSameAsDeliveryValue(value: boolean): void { this.isSameAsDelivery$.next(value); } - setPickupDeliveryModeForPickupItems(): void {} + setDefaultBillingAddress(): void{}; } @Pipe({ @@ -64,8 +66,15 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { provide: OpfCheckoutBillingAddressFormService, useClass: Service, }, + { + provide: ActiveCartFacade, + useValue: { + getActive: () => of({ code: '123', totalItems: 2 }), + }, + }, { provide: Store, useValue: {} }, { provide: UserAddressAdapter, useValue: {} }, + ], }).compileComponents(); @@ -83,15 +92,14 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { const countries = [{ id: '1', name: 'Country 1' }]; spyOn(service, 'getCountries').and.returnValue(of(countries)); spyOn(service, 'getAddresses'); - spyOn(service, 'setPickupDeliveryModeForPickupItems'); + spyOn(service,'setDefaultBillingAddress'); component.ngOnInit(); expect(component.countries$).toBeDefined(); expect(service.getCountries).toHaveBeenCalled(); expect(service.getAddresses).toHaveBeenCalled(); - expect(service.setPickupDeliveryModeForPickupItems).toHaveBeenCalled(); - + expect(service.setDefaultBillingAddress).toHaveBeenCalled(); }); it('should cancel and hide form on cancelAndHideForm', () => { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index f8e195ae598..687b7833000 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -3,23 +3,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { fakeAsync, flush, TestBed } from '@angular/core/testing'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; -import { - CheckoutBillingAddressFacade, - CheckoutDeliveryAddressFacade, - CheckoutDeliveryModesFacade, -} from '@spartacus/checkout/base/root'; import { Address, GlobalMessageService, HttpErrorModel, UserAddressAdapter, + UserAddressService, UserPaymentService, } from '@spartacus/core'; -import { BehaviorSubject, of, throwError } from 'rxjs'; -import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; +import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; +import { + CheckoutBillingAddressFacade, + CheckoutDeliveryAddressFacade, +} from '@spartacus/checkout/base/root'; +import { TestBed, fakeAsync, flush } from '@angular/core/testing'; + import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; +import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; import { Store } from '@ngrx/store'; describe('OpfCheckoutBillingAddressFormService', () => { @@ -31,7 +32,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { let mockGlobalMessageService: Partial; let mockOpfCheckoutPaymentWrapperService: Partial; let mockPickupNoDefaultAddress$: BehaviorSubject; - let mockCheckoutDeliveryModesFacade: any; + let mockUserAddressService: Partial; const mockDeliveryAddress: Address = { id: '123', @@ -59,7 +60,8 @@ describe('OpfCheckoutBillingAddressFormService', () => { reloadActiveCart: () => of(true), isStable: () => of(true), getActive: () => of({ sapBillingAddress: mockPaymentAddress } as Cart), - hasPickupItems: () => of(true), + hasDeliveryItems: () => of(false) + }; mockGlobalMessageService = { @@ -69,14 +71,10 @@ describe('OpfCheckoutBillingAddressFormService', () => { mockOpfCheckoutPaymentWrapperService = { reloadPaymentMode: () => {}, }; - mockPickupNoDefaultAddress$ = new BehaviorSubject(undefined); - mockCheckoutDeliveryModesFacade = { - getSelectedDeliveryModeState: jasmine - .createSpy() - .and.returnValue(of({ data: {} })), - setDeliveryMode: jasmine.createSpy().and.returnValue(of(true)), + mockUserAddressService = { + getDefaultAddress: () => of(undefined), }; TestBed.configureTestingModule({ @@ -97,16 +95,15 @@ describe('OpfCheckoutBillingAddressFormService', () => { provide: OpfCheckoutPaymentWrapperService, useValue: mockOpfCheckoutPaymentWrapperService, }, - { provide: Store, useValue: {} }, + { provide: Store, useValue: {pipe: () => of(undefined)} }, { provide: UserAddressAdapter, useValue: {} }, { provide: '_pickupNoDefaultAddress$', useValue: mockPickupNoDefaultAddress$, }, - { - provide: CheckoutDeliveryModesFacade, - useValue: mockCheckoutDeliveryModesFacade, - }, + { provide: UserAddressService, useValue: mockUserAddressService }, + + ], }); @@ -276,44 +273,18 @@ describe('OpfCheckoutBillingAddressFormService', () => { expect(service.setBillingAddress).not.toHaveBeenCalled(); }); + it('should return an observable from pickupNoDefaultAddress$', () => { + spyOn(mockPickupNoDefaultAddress$, 'asObservable').and.callThrough(); - it('should return pickupNoDefaultAddress$ observable', (done) => { - service.pickupNoDefaultAddress$.subscribe(() => { - expect(true).toBe(true); - done(); - }); - (service as any)._pickupNoDefaultAddress$.next(); - }); - - it('should set pickup delivery mode for pickup items', () => { - service.setPickupDeliveryModeForPickupItems(); - expect( - mockCheckoutDeliveryModesFacade.setDeliveryMode - ).toHaveBeenCalledWith('pickup'); - }); + (service as any)._pickupNoDefaultAddress$ = mockPickupNoDefaultAddress$; - it('should set pickup delivery mode when cart has pickup items and no current mode', () => { - spyOn(mockActiveCartFacade, 'hasPickupItems').and.returnValue(of(true)); - mockCheckoutDeliveryModesFacade.getSelectedDeliveryModeState.and.returnValue( - of({ data: {} }) - ); - service.setPickupDeliveryModeForPickupItems(); - expect( - mockCheckoutDeliveryModesFacade.setDeliveryMode - ).toHaveBeenCalledWith('pickup'); - expect(service['hasPickupItems']).toBe(true); - }); + const result: Observable = service.pickupNoDefaultAddress$; - it('should not set delivery mode if cart has no pickup items', () => { - spyOn(mockActiveCartFacade, 'hasPickupItems').and.returnValue(of(false)); - mockCheckoutDeliveryModesFacade.setDeliveryMode.calls.reset(); - service.setPickupDeliveryModeForPickupItems(); - expect( - mockCheckoutDeliveryModesFacade.setDeliveryMode - ).not.toHaveBeenCalled(); + expect(mockPickupNoDefaultAddress$.asObservable).toHaveBeenCalled(); + expect(result).toEqual(mockPickupNoDefaultAddress$.asObservable()); }); - it('should handle no default address by setting isSameAsDelivery=false and emitting pickupNoDefaultAddress$', (done) => { + it('should handle no default address by setting isSameAsDelivery=false and emitting pickupNoDefaultAddress$', (done) => { spyOn(service, 'setIsSameAsDeliveryValue').and.callThrough(); service.pickupNoDefaultAddress$.subscribe(() => { expect(service.setIsSameAsDeliveryValue).toHaveBeenCalledWith(false); @@ -321,55 +292,35 @@ describe('OpfCheckoutBillingAddressFormService', () => { }); (service as any).handleNoDefaultAddress(); }); + it('should handle error when setting default billing address fails', fakeAsync(() => { + spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); + spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue(of(mockDeliveryAddress)); + spyOn(service, 'setBillingAddress').and.returnValue(throwError(() => new Error('Error'))); - it('should handle no addresses found in address book', () => { - service['hasPickupItems'] = true; - spyOn(service['userAddressService'], 'getAddresses').and.returnValue( - of([]) - ); - spyOn(service as any, 'handleNoDefaultAddress'); - - service.getAddresses(); + service.setDefaultBillingAddress(); + flush(); // Ensure all observables complete - expect(service['handleNoDefaultAddress']).toHaveBeenCalled(); - }); - it('should use default address if available', () => { - service['hasPickupItems'] = true; + expect(service['_$isLoadingAddress'].value).toBeFalsy(); + })); - const defaultAddress = { id: 'A1', defaultAddress: true } as Address; - service['hasPickupItems'] = true; +it('should handle the absence of a default address by invoking handleNoDefaultAddress', fakeAsync(() => { + spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); + spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue(of(undefined)); + const handleNoDefaultAddressSpy = spyOn(service as any, 'handleNoDefaultAddress').and.callThrough(); - spyOn(service['_$billingAddressSub'], 'next'); + service.setDefaultBillingAddress(); + flush(); // Ensure all observables complete - spyOn(service['userAddressService'], 'getAddresses').and.returnValue( - of([defaultAddress]) - ); - spyOn(service, 'setBillingAddress').and.returnValue(of(defaultAddress)); + expect(handleNoDefaultAddressSpy).toHaveBeenCalled(); +})); + it('should handle errors when loading the default address', fakeAsync(() => { + spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); + spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue(throwError(() => new Error('Error loading default address'))); - service.getAddresses(); + service.setDefaultBillingAddress(); + flush(); // Ensure all observables complete - expect(service['_$billingAddressSub'].next).toHaveBeenCalledWith( - jasmine.objectContaining({ id: 'A1', defaultAddress: true }) - ); + expect(service['_$isLoadingAddress'].value).toBeFalsy(); + })); }); - it('should handle no default address in address book', () => { - service['hasPickupItems'] = true; - - spyOn(service['_$billingAddressSub'], 'next'); - spyOn(service as any, 'handleNoDefaultAddress'); - - spyOn(service as any, 'getDeliveryAddress').and.returnValue( - of({ id: '123' } as Address) - ); - spyOn(service as any, 'getPaymentAddress').and.returnValue(of(undefined)); - - spyOn(service['userAddressService'], 'getAddresses').and.returnValue( - of([{ id: 'A1' }]) - ); - service.getAddresses(); - - expect(service['_$billingAddressSub'].next).toHaveBeenCalledWith(undefined); - expect(service['handleNoDefaultAddress']).toHaveBeenCalled(); - }); -}); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index c2c0eb1e7c0..bf1e8181753 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -89,12 +89,11 @@ export class OpfCheckoutBillingAddressFormService { shareReplay(1) ); } -// This method sets the default address when the cart contains only pickup items. setDefaultBillingAddress(): void { this._$isLoadingAddress.next(true); this.activeCartService.hasDeliveryItems().pipe( take(1), - filter(hasDeliveryItems => !hasDeliveryItems), // Proceed only if there are no delivery items + filter(hasDeliveryItems => !hasDeliveryItems), switchMap(() => this.userAddressService.getDefaultAddress()), tap(defaultAddress => { if (!defaultAddress) { @@ -102,7 +101,7 @@ export class OpfCheckoutBillingAddressFormService { this.handleNoDefaultAddress(); } }), - filter((addr): addr is Address => !!addr), // Only continue if address exists + filter((addr): addr is Address => !!addr), switchMap(defaultAddress => this.setBillingAddress(defaultAddress).pipe( catchError(err => { diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts index 043b85d3e13..1b7a87a6dfb 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts @@ -4,21 +4,25 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { OpfCheckoutReviewCartDetailsComponent } from './opf-checkout-review-cart-details.component'; +import { BaseSiteService, TranslationService } from '@spartacus/core'; import { Cart, - PromotionLocation, CartOutlets, OrderEntry, + PromotionLocation, } from '@spartacus/cart/base/root'; import { Component, + Directive, Input, Pipe, PipeTransform, - Directive, } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OpfCheckoutReviewCartDetailsComponent } from './opf-checkout-review-cart-details.component'; +import { Store } from '@ngrx/store'; +import { of } from 'rxjs'; @Directive({ selector: '[cxOutlet]', @@ -79,6 +83,7 @@ class MockPromotionsComponent { describe('OpfCheckoutReviewCartDetailsComponent', () => { let component: OpfCheckoutReviewCartDetailsComponent; let fixture: ComponentFixture; + let baseSiteServiceMock: any; const mockEntries: OrderEntry[] = [ { @@ -106,7 +111,13 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { }, }, ]; - + baseSiteServiceMock = { + getActive: () => of('electronics-spa'), + get: () => of({ + uid: 'electronics-spa', + // Add other properties that might be required + }), +}; const mockCart: Cart = { code: 'test-cart', totalItems: 2, @@ -129,6 +140,22 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { MockTranslatePipe, MockOutletDirective, ], + + providers: [ + { + provide: TranslationService, + useValue: { + translate: jasmine.createSpy('translate').and.returnValue(''), + }, + }, + { provide: Store, + useValue: { + pipe: jasmine.createSpy('pipe').and.returnValue(of({})), + dispatch: jasmine.createSpy('dispatch'), + select: jasmine.createSpy('select').and.returnValue(of({})) + } }, + {provide:BaseSiteService,useValue:baseSiteServiceMock} + ], }).compileComponents(); }); @@ -161,20 +188,13 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { expect(component.entries).toBeNull(); }); - it('should display cart details when cart is provided', () => { - component.cart = mockCart; - component.entries = mockEntries; - fixture.detectChanges(); - - const compiled = fixture.debugElement.nativeElement; - const cartTotal = compiled.querySelector('.cx-review-cart-total'); - expect(cartTotal).toBeTruthy(); - expect(cartTotal.textContent).toContain('$100.00'); - - const promotions = compiled.querySelector('cx-promotions'); - expect(promotions).toBeTruthy(); - - const itemsToShipLabel = compiled.querySelector('.cx-items-to-ship-label'); - expect(itemsToShipLabel).toBeTruthy(); - }); +it('should display cart details when cart is provided', () => { + component.cart = mockCart; + component.entries = mockEntries; + fixture.detectChanges(); + expect(component.cart).toEqual(mockCart); + expect(component.entries).toEqual(mockEntries); + expect(component.cart.totalPrice?.formattedValue).toBe('$100.00'); + expect(component.entries.length).toBe(2); +}); }); diff --git a/projects/core/src/user/facade/user-address.service.spec.ts b/projects/core/src/user/facade/user-address.service.spec.ts index 40a8ff34cc9..e48cf4cdf44 100644 --- a/projects/core/src/user/facade/user-address.service.spec.ts +++ b/projects/core/src/user/facade/user-address.service.spec.ts @@ -1,22 +1,25 @@ -import { inject, TestBed } from '@angular/core/testing'; -import { Store, StoreModule } from '@ngrx/store'; -import { Observable, of } from 'rxjs'; -import { take } from 'rxjs/operators'; -import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; +import * as fromProcessReducers from '../../process/store/reducers'; +import * as fromStoreReducers from '../store/reducers/index'; + import { Address, AddressValidation, Country, Region, } from '../../model/address.model'; +import { Observable, of } from 'rxjs'; +import { StateWithUser, USER_FEATURE } from '../store/user-state'; +import { Store, StoreModule } from '@ngrx/store'; +import { TestBed, inject } from '@angular/core/testing'; + import { OCC_USER_ID_CURRENT } from '../../occ/utils/occ-constants'; import { PROCESS_FEATURE } from '../../process/store/process-state'; -import * as fromProcessReducers from '../../process/store/reducers'; -import { UserAddressConnector } from '../connectors/address/user-address.connector'; import { UserActions } from '../store/actions/index'; -import * as fromStoreReducers from '../store/reducers/index'; -import { StateWithUser, USER_FEATURE } from '../store/user-state'; +import { UserAddressConnector } from '../connectors/address/user-address.connector'; import { UserAddressService } from './user-address.service'; +import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; +import { take } from 'rxjs/operators'; + import createSpy = jasmine.createSpy; class MockUserIdService implements Partial { @@ -350,4 +353,38 @@ describe('UserAddressService', () => { }); }); }); + + describe('getDefaultAddress', () => { + it('should return the default address if present', (done) => { + const addresses: Address[] = [ + { id: '1', defaultAddress: false }, + { id: '2', defaultAddress: true }, + { id: '3', defaultAddress: false }, + ]; + spyOn(service, 'getAddresses').and.returnValue(of(addresses)); + service.getDefaultAddress().subscribe((result) => { + expect(result).toEqual(addresses[1]); + done(); + }); + }); + it('should return undefined if no default address is present', (done) => { + const addresses: Address[] = [ + { id: '1', defaultAddress: false }, + { id: '2', defaultAddress: false }, + ]; + spyOn(service, 'getAddresses').and.returnValue(of(addresses)); + service.getDefaultAddress().subscribe((result) => { + expect(result).toBeUndefined(); + done(); + }); + }); + + it('should return undefined if addresses array is empty', (done) => { + spyOn(service, 'getAddresses').and.returnValue(of([])); + service.getDefaultAddress().subscribe((result) => { + expect(result).toBeUndefined(); + done(); + }); + }); + }); }); From 7208b7ef9cb1b221eb7afd378248ee984dc7a7f5 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 11:28:52 +0530 Subject: [PATCH 09/49] removed comments --- .../guards/checkout-steps-set.guard.spec.ts | 2 - ...ckout-billing-address-form.service.spec.ts | 61 +++++++++++-------- ...kout-review-cart-details.component.spec.ts | 1 - 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts index ac3bea8b8bc..f8077526d28 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts @@ -304,7 +304,6 @@ describe('pickup only cart (no delivery items)', () => { beforeEach(() => { // Simulate a cart with only pickup items hasDeliveryItems$.next(false); - // Reset spies (checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy).calls.reset(); (checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy).calls.reset(); }); @@ -323,7 +322,6 @@ describe('cart with delivery items', () => { beforeEach(() => { // Simulate a cart with delivery items hasDeliveryItems$.next(true); - // Reset spies (checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy).calls.reset(); (checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy).calls.reset(); }); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index 687b7833000..070d1b23872 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -60,8 +60,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { reloadActiveCart: () => of(true), isStable: () => of(true), getActive: () => of({ sapBillingAddress: mockPaymentAddress } as Cart), - hasDeliveryItems: () => of(false) - + hasDeliveryItems: () => of(false), }; mockGlobalMessageService = { @@ -95,15 +94,13 @@ describe('OpfCheckoutBillingAddressFormService', () => { provide: OpfCheckoutPaymentWrapperService, useValue: mockOpfCheckoutPaymentWrapperService, }, - { provide: Store, useValue: {pipe: () => of(undefined)} }, + { provide: Store, useValue: { pipe: () => of(undefined) } }, { provide: UserAddressAdapter, useValue: {} }, { provide: '_pickupNoDefaultAddress$', useValue: mockPickupNoDefaultAddress$, }, - { provide: UserAddressService, useValue: mockUserAddressService }, - - + { provide: UserAddressService, useValue: mockUserAddressService }, ], }); @@ -284,7 +281,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { expect(result).toEqual(mockPickupNoDefaultAddress$.asObservable()); }); - it('should handle no default address by setting isSameAsDelivery=false and emitting pickupNoDefaultAddress$', (done) => { + it('should handle no default address by setting isSameAsDelivery=false and emitting pickupNoDefaultAddress$', (done) => { spyOn(service, 'setIsSameAsDeliveryValue').and.callThrough(); service.pickupNoDefaultAddress$.subscribe(() => { expect(service.setIsSameAsDeliveryValue).toHaveBeenCalledWith(false); @@ -294,33 +291,43 @@ describe('OpfCheckoutBillingAddressFormService', () => { }); it('should handle error when setting default billing address fails', fakeAsync(() => { spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); - spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue(of(mockDeliveryAddress)); - spyOn(service, 'setBillingAddress').and.returnValue(throwError(() => new Error('Error'))); + spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue( + of(mockDeliveryAddress) + ); + spyOn(service, 'setBillingAddress').and.returnValue( + throwError(() => new Error('Error')) + ); service.setDefaultBillingAddress(); - flush(); // Ensure all observables complete + flush(); expect(service['_$isLoadingAddress'].value).toBeFalsy(); })); -it('should handle the absence of a default address by invoking handleNoDefaultAddress', fakeAsync(() => { - spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); - spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue(of(undefined)); - const handleNoDefaultAddressSpy = spyOn(service as any, 'handleNoDefaultAddress').and.callThrough(); - - service.setDefaultBillingAddress(); - flush(); // Ensure all observables complete + it('should handle the absence of a default address by invoking handleNoDefaultAddress', fakeAsync(() => { + spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); + spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue( + of(undefined) + ); + const handleNoDefaultAddressSpy = spyOn( + service as any, + 'handleNoDefaultAddress' + ).and.callThrough(); - expect(handleNoDefaultAddressSpy).toHaveBeenCalled(); -})); - it('should handle errors when loading the default address', fakeAsync(() => { - spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); - spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue(throwError(() => new Error('Error loading default address'))); + service.setDefaultBillingAddress(); + flush(); - service.setDefaultBillingAddress(); - flush(); // Ensure all observables complete + expect(handleNoDefaultAddressSpy).toHaveBeenCalled(); + })); + it('should handle errors when loading the default address', fakeAsync(() => { + spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); + spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue( + throwError(() => new Error('Error loading default address')) + ); - expect(service['_$isLoadingAddress'].value).toBeFalsy(); - })); - }); + service.setDefaultBillingAddress(); + flush(); + expect(service['_$isLoadingAddress'].value).toBeFalsy(); + })); +}); diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts index 1b7a87a6dfb..ebc9ba4cddf 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts @@ -115,7 +115,6 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { getActive: () => of('electronics-spa'), get: () => of({ uid: 'electronics-spa', - // Add other properties that might be required }), }; const mockCart: Cart = { From b68e9f6e75b7bc29b0ea3f6807667db3ac413e1e Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 13:31:38 +0530 Subject: [PATCH 10/49] adding @spartacus/pickup-in-store in dependency --- integration-libs/opf/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-libs/opf/package.json b/integration-libs/opf/package.json index 1cf5dea70ae..be8590fc3a1 100644 --- a/integration-libs/opf/package.json +++ b/integration-libs/opf/package.json @@ -36,6 +36,7 @@ "@spartacus/checkout": "2211.43.0", "@spartacus/core": "2211.43.0", "@spartacus/order": "2211.43.0", + "@spartacus/pickup-in-store": "2211.43.0", "@spartacus/schematics": "2211.43.0", "@spartacus/storefront": "2211.43.0", "@spartacus/styles": "2211.43.0", @@ -49,4 +50,4 @@ "access": "public" }, "schematics": "./schematics/collection.json" -} +} \ No newline at end of file From 3d5f2890e887ab5e93e876ce50d1c0bcdcc0eb2c Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 13:36:41 +0530 Subject: [PATCH 11/49] Update dependencies.json --- projects/schematics/src/dependencies.json | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/schematics/src/dependencies.json b/projects/schematics/src/dependencies.json index 16ad9aecfd0..ea868f430cc 100644 --- a/projects/schematics/src/dependencies.json +++ b/projects/schematics/src/dependencies.json @@ -422,6 +422,7 @@ "@spartacus/checkout": "2211.43.0", "@spartacus/core": "2211.43.0", "@spartacus/order": "2211.43.0", + "@spartacus/pickup-in-store": "2211.43.0", "@spartacus/schematics": "2211.43.0", "@spartacus/storefront": "2211.43.0", "@spartacus/styles": "2211.43.0", From 1a39d2b36602457049685ceb0058f0d057b170f6 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 13:45:10 +0530 Subject: [PATCH 12/49] adding properties to tsconfig.lib.json to fix __ is missing in compilerOptions.paths. --- integration-libs/opf/tsconfig.lib.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/integration-libs/opf/tsconfig.lib.json b/integration-libs/opf/tsconfig.lib.json index 967fb1d8ddb..fd09ccc6c3f 100644 --- a/integration-libs/opf/tsconfig.lib.json +++ b/integration-libs/opf/tsconfig.lib.json @@ -113,7 +113,21 @@ "@spartacus/pdf-invoices/core": ["dist/pdf-invoices/core"], "@spartacus/pdf-invoices": ["dist/pdf-invoices"], "@spartacus/pdf-invoices/occ": ["dist/pdf-invoices/occ"], - "@spartacus/pdf-invoices/root": ["dist/pdf-invoices/root"] + "@spartacus/pdf-invoices/root": ["dist/pdf-invoices/root"], + "@spartacus/pickup-in-store/assets": ["dist/pickup-in-store/assets"], + "@spartacus/pickup-in-store/components": [ + "dist/pickup-in-store/components" + ], + "@spartacus/pickup-in-store/core": ["dist/pickup-in-store/core"], + "@spartacus/pickup-in-store": ["dist/pickup-in-store"], + "@spartacus/pickup-in-store/occ": ["dist/pickup-in-store/occ"], + "@spartacus/pickup-in-store/root": ["dist/pickup-in-store/root"], + "@spartacus/storefinder/assets": ["dist/storefinder/assets"], + "@spartacus/storefinder/components": ["dist/storefinder/components"], + "@spartacus/storefinder/core": ["dist/storefinder/core"], + "@spartacus/storefinder": ["dist/storefinder"], + "@spartacus/storefinder/occ": ["dist/storefinder/occ"], + "@spartacus/storefinder/root": ["dist/storefinder/root"] }, "resolveJsonModule": true, "esModuleInterop": true From db0b9211427fdecd223caed052ee372809983610 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 10 Sep 2025 13:56:08 +0530 Subject: [PATCH 13/49] Fix Sonarqube scan error --- .../components/guards/checkout-steps-set.guard.ts | 2 +- .../opf-checkout-billing-address-form.component.ts | 3 +-- .../opf-checkout-billing-address-form.service.ts | 11 +++++------ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts index aa445590422..a5a0d7b0db4 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts @@ -37,7 +37,7 @@ import { CheckoutStepService } from '../services/checkout-step.service'; export class CheckoutStepsSetGuard implements OnDestroy { protected subscription: Subscription; protected logger = inject(LoggerService); - protected hasDeliveryItemsInCart: Boolean; + protected hasDeliveryItemsInCart: boolean; constructor( protected checkoutStepService: CheckoutStepService, protected routingConfigService: RoutingConfigService, diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 256270c446a..dfc70d0ccd8 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -10,11 +10,10 @@ import { OnInit, inject, } from '@angular/core'; -import { Address, Country } from '@spartacus/core'; +import { Address, Country,UserAddressService } from '@spartacus/core'; import { ICON_TYPE } from '@spartacus/storefront'; import { Observable } from 'rxjs'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; -import { UserAddressService } from '@spartacus/core'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; @Component({ selector: 'cx-opf-checkout-billing-address-form', diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index bf1e8181753..48e3ba36187 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -11,6 +11,7 @@ import { GlobalMessageService, GlobalMessageType, HttpErrorModel, + UserAddressService, UserPaymentService, } from '@spartacus/core'; import { @@ -41,7 +42,6 @@ import { import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; import { PickupOptionFacade } from '@spartacus/pickup-in-store/root'; -import { UserAddressService } from '@spartacus/core'; @Injectable() export class OpfCheckoutBillingAddressFormService { @@ -97,21 +97,20 @@ export class OpfCheckoutBillingAddressFormService { switchMap(() => this.userAddressService.getDefaultAddress()), tap(defaultAddress => { if (!defaultAddress) { - console.log('No default address found, handling no default address.'); this.handleNoDefaultAddress(); } }), filter((addr): addr is Address => !!addr), switchMap(defaultAddress => this.setBillingAddress(defaultAddress).pipe( - catchError(err => { - console.error('Error setting billing address:', err); + catchError(() => { + // console.error('Error setting billing address:', err); return of(undefined); }) ) ), - catchError(error => { - console.error('Error loading default address:', error); + catchError(() => { + //console.error('Error loading default address:', error); return of(undefined); }) ).subscribe(); From e24ca25bcecfdb6b90dba0ee8624d764eb4e0e40 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 14:05:03 +0530 Subject: [PATCH 14/49] fixing sonarQube error --- ...f-checkout-billing-address-form.service.ts | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index 48e3ba36187..4a4b71a11ec 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -74,7 +74,7 @@ export class OpfCheckoutBillingAddressFormService { get pickupNoDefaultAddress$(): Observable { return this._pickupNoDefaultAddress$.asObservable(); } - private handleNoDefaultAddress(): void { + private handleNoDefaultAddress(): void { this.setIsSameAsDeliveryValue(false); this._pickupNoDefaultAddress$.next(); } @@ -91,33 +91,30 @@ export class OpfCheckoutBillingAddressFormService { } setDefaultBillingAddress(): void { this._$isLoadingAddress.next(true); - this.activeCartService.hasDeliveryItems().pipe( - take(1), - filter(hasDeliveryItems => !hasDeliveryItems), - switchMap(() => this.userAddressService.getDefaultAddress()), - tap(defaultAddress => { - if (!defaultAddress) { - this.handleNoDefaultAddress(); - } - }), - filter((addr): addr is Address => !!addr), - switchMap(defaultAddress => - this.setBillingAddress(defaultAddress).pipe( + this.activeCartService + .hasDeliveryItems() + .pipe( + take(1), + filter((hasDeliveryItems) => !hasDeliveryItems), + switchMap(() => this.userAddressService.getDefaultAddress()), + tap((defaultAddress) => { + if (!defaultAddress) { + this.handleNoDefaultAddress(); + } + }), + filter((addr): addr is Address => !!addr), + switchMap((defaultAddress) => this.setBillingAddress(defaultAddress)), catchError(() => { - // console.error('Error setting billing address:', err); + this.globalMessageService.add( + { key: 'opfCheckout.errors.loadDefaultAddress' }, + GlobalMessageType.MSG_TYPE_ERROR + ); return of(undefined); }) ) - ), - catchError(() => { - //console.error('Error loading default address:', error); - return of(undefined); - }) - ).subscribe(); + .subscribe(); this._$isLoadingAddress.next(false); - -} - + } getAddresses(): void { this._$isLoadingAddress.next(true); @@ -189,7 +186,7 @@ export class OpfCheckoutBillingAddressFormService { { key: 'opfCheckout.errors.updateBillingAddress' }, GlobalMessageType.MSG_TYPE_ERROR ); - return throwError(error); + return throwError(() => error); }), finalize(() => { this._$isLoadingAddress.next(false); From d955179ec728dc7be3468b52198a42d6000661d2 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 14:29:58 +0530 Subject: [PATCH 15/49] Update user-address.service.ts --- projects/core/src/user/facade/user-address.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/core/src/user/facade/user-address.service.ts b/projects/core/src/user/facade/user-address.service.ts index cfd01e8cff7..68d34d70b30 100644 --- a/projects/core/src/user/facade/user-address.service.ts +++ b/projects/core/src/user/facade/user-address.service.ts @@ -110,7 +110,7 @@ export class UserAddressService { /** * Returns the default address - */ + */ getDefaultAddress(): Observable
{ return this.getAddresses().pipe( map((addresses) => addresses.find((address) => address.defaultAddress)) From a048d82bfc6acb59e7affc3439d59cf903583650 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Wed, 10 Sep 2025 14:46:19 +0530 Subject: [PATCH 16/49] fixing code formatting error --- .../guards/checkout-steps-set.guard.spec.ts | 74 ++++++++++++------- ...out-billing-address-form.component.spec.ts | 13 ++-- ...checkout-billing-address-form.component.ts | 4 +- ...heckout-review-cart-details.component.html | 66 ++++++++--------- ...kout-review-cart-details.component.spec.ts | 47 ++++++------ integration-libs/opf/package.json | 2 +- 6 files changed, 113 insertions(+), 93 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts index f8077526d28..7e85f1e08f3 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts @@ -79,7 +79,7 @@ class MockCheckoutDeliveryAddressFacade getDeliveryAddressState = createSpy().and.returnValue( of({ loading: false, error: false, data: undefined }) ); - clearCheckoutDeliveryAddress = createSpy(); + clearCheckoutDeliveryAddress = createSpy(); } class MockCheckoutDeliveryModesFacade @@ -300,38 +300,56 @@ describe(`CheckoutStepsSetGuard`, () => { }); }); -describe('pickup only cart (no delivery items)', () => { - beforeEach(() => { - // Simulate a cart with only pickup items - hasDeliveryItems$.next(false); - (checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy).calls.reset(); - (checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy).calls.reset(); - }); + describe('pickup only cart (no delivery items)', () => { + beforeEach(() => { + // Simulate a cart with only pickup items + hasDeliveryItems$.next(false); + ( + checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy + ).calls.reset(); + ( + checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy + ).calls.reset(); + }); - it('should clear delivery address, set delivery mode to pickup, and return true for any step', (done) => { - guard.canActivate({ url: ['checkout', 'route2'] }).subscribe((result) => { - expect(checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).toHaveBeenCalled(); - expect(checkoutDeliveryModesFacade.setDeliveryMode).toHaveBeenCalledWith('pickup'); - expect(result).toBe(true); - done(); + it('should clear delivery address, set delivery mode to pickup, and return true for any step', (done) => { + guard + .canActivate({ url: ['checkout', 'route2'] }) + .subscribe((result) => { + expect( + checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress + ).toHaveBeenCalled(); + expect( + checkoutDeliveryModesFacade.setDeliveryMode + ).toHaveBeenCalledWith('pickup'); + expect(result).toBe(true); + done(); + }); }); }); -}); -describe('cart with delivery items', () => { - beforeEach(() => { - // Simulate a cart with delivery items - hasDeliveryItems$.next(true); - (checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy).calls.reset(); - (checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy).calls.reset(); - }); + describe('cart with delivery items', () => { + beforeEach(() => { + // Simulate a cart with delivery items + hasDeliveryItems$.next(true); + ( + checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy + ).calls.reset(); + ( + checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy + ).calls.reset(); + }); - it('should NOT clear delivery address or set delivery mode for any step', (done) => { - guard.canActivate({ url: ['checkout', 'route2'] }).subscribe(() => { - expect(checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).not.toHaveBeenCalled(); - expect(checkoutDeliveryModesFacade.setDeliveryMode).not.toHaveBeenCalled(); - done(); + it('should NOT clear delivery address or set delivery mode for any step', (done) => { + guard.canActivate({ url: ['checkout', 'route2'] }).subscribe(() => { + expect( + checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress + ).not.toHaveBeenCalled(); + expect( + checkoutDeliveryModesFacade.setDeliveryMode + ).not.toHaveBeenCalled(); + done(); + }); }); }); }); -}); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts index 1caaa63de63..c3c2559a69e 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts @@ -42,7 +42,7 @@ class Service { setIsSameAsDeliveryValue(value: boolean): void { this.isSameAsDelivery$.next(value); } - setDefaultBillingAddress(): void{}; + setDefaultBillingAddress(): void {} } @Pipe({ @@ -67,14 +67,13 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { useClass: Service, }, { - provide: ActiveCartFacade, - useValue: { - getActive: () => of({ code: '123', totalItems: 2 }), - }, + provide: ActiveCartFacade, + useValue: { + getActive: () => of({ code: '123', totalItems: 2 }), + }, }, { provide: Store, useValue: {} }, { provide: UserAddressAdapter, useValue: {} }, - ], }).compileComponents(); @@ -92,7 +91,7 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { const countries = [{ id: '1', name: 'Country 1' }]; spyOn(service, 'getCountries').and.returnValue(of(countries)); spyOn(service, 'getAddresses'); - spyOn(service,'setDefaultBillingAddress'); + spyOn(service, 'setDefaultBillingAddress'); component.ngOnInit(); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index dfc70d0ccd8..a198223aea5 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -10,7 +10,7 @@ import { OnInit, inject, } from '@angular/core'; -import { Address, Country,UserAddressService } from '@spartacus/core'; +import { Address, Country, UserAddressService } from '@spartacus/core'; import { ICON_TYPE } from '@spartacus/storefront'; import { Observable } from 'rxjs'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; @@ -40,7 +40,7 @@ export class OpfCheckoutBillingAddressFormComponent implements OnInit { countries$: Observable; ngOnInit() { - this.activeCartFacade.getActive().subscribe(cart => (this.cart = cart)); + this.activeCartFacade.getActive().subscribe((cart) => (this.cart = cart)); this.countries$ = this.service.getCountries(); this.userAddressService.loadAddresses(); this.service.setDefaultBillingAddress(); diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html index b8fdbd3771f..272cead5606 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html @@ -18,39 +18,39 @@ > - - -
- {{ 'opfCheckout.itemsToBeShipped' | cxTranslate }} -
-
- - -
+ +
+ {{ 'opfCheckout.itemsToBeShipped' | cxTranslate }} +
+
+ - - - + +
+ + + +
diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts index ebc9ba4cddf..7e241c203cf 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.spec.ts @@ -111,12 +111,13 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { }, }, ]; - baseSiteServiceMock = { - getActive: () => of('electronics-spa'), - get: () => of({ - uid: 'electronics-spa', - }), -}; + baseSiteServiceMock = { + getActive: () => of('electronics-spa'), + get: () => + of({ + uid: 'electronics-spa', + }), + }; const mockCart: Cart = { code: 'test-cart', totalItems: 2, @@ -147,13 +148,15 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { translate: jasmine.createSpy('translate').and.returnValue(''), }, }, - { provide: Store, - useValue: { - pipe: jasmine.createSpy('pipe').and.returnValue(of({})), - dispatch: jasmine.createSpy('dispatch'), - select: jasmine.createSpy('select').and.returnValue(of({})) - } }, - {provide:BaseSiteService,useValue:baseSiteServiceMock} + { + provide: Store, + useValue: { + pipe: jasmine.createSpy('pipe').and.returnValue(of({})), + dispatch: jasmine.createSpy('dispatch'), + select: jasmine.createSpy('select').and.returnValue(of({})), + }, + }, + { provide: BaseSiteService, useValue: baseSiteServiceMock }, ], }).compileComponents(); }); @@ -187,13 +190,13 @@ describe('OpfCheckoutReviewCartDetailsComponent', () => { expect(component.entries).toBeNull(); }); -it('should display cart details when cart is provided', () => { - component.cart = mockCart; - component.entries = mockEntries; - fixture.detectChanges(); - expect(component.cart).toEqual(mockCart); - expect(component.entries).toEqual(mockEntries); - expect(component.cart.totalPrice?.formattedValue).toBe('$100.00'); - expect(component.entries.length).toBe(2); -}); + it('should display cart details when cart is provided', () => { + component.cart = mockCart; + component.entries = mockEntries; + fixture.detectChanges(); + expect(component.cart).toEqual(mockCart); + expect(component.entries).toEqual(mockEntries); + expect(component.cart.totalPrice?.formattedValue).toBe('$100.00'); + expect(component.entries.length).toBe(2); + }); }); diff --git a/integration-libs/opf/package.json b/integration-libs/opf/package.json index be8590fc3a1..8fbc833bed0 100644 --- a/integration-libs/opf/package.json +++ b/integration-libs/opf/package.json @@ -50,4 +50,4 @@ "access": "public" }, "schematics": "./schematics/collection.json" -} \ No newline at end of file +} From 4229fbf6085bef404a1dce48840c2888cad8fbc3 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Thu, 11 Sep 2025 11:21:39 +0530 Subject: [PATCH 17/49] fix dependency order --- projects/schematics/src/shared/utils/graph-utils_spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/schematics/src/shared/utils/graph-utils_spec.ts b/projects/schematics/src/shared/utils/graph-utils_spec.ts index 866a64a60d8..313165ddcb2 100644 --- a/projects/schematics/src/shared/utils/graph-utils_spec.ts +++ b/projects/schematics/src/shared/utils/graph-utils_spec.ts @@ -144,6 +144,7 @@ describe('Graph utils', () => { SPARTACUS_CHECKOUT, SPARTACUS_STOREFINDER, SPARTACUS_REQUESTED_DELIVERY_DATE, + SPARTACUS_PICKUP_IN_STORE, SPARTACUS_TRACKING, SPARTACUS_CUSTOMER_TICKETING, SPARTACUS_ORGANIZATION, @@ -167,7 +168,6 @@ describe('Graph utils', () => { SPARTACUS_PRODUCT_MULTI_DIMENSIONAL, SPARTACUS_PRODUCT_CONFIGURATOR, SPARTACUS_PRODUCT, - SPARTACUS_PICKUP_IN_STORE, SPARTACUS_ESTIMATED_DELIVERY_DATE, ]); }); From 0168adc35a20ecfe6d32677377140b16b16ff179 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Tue, 16 Sep 2025 13:40:47 +0530 Subject: [PATCH 18/49] addressing review comments. --- .../opf/base/core/services/opf-endpoints.service.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts b/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts index 7acb8fbab1d..c5471702ab1 100644 --- a/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts +++ b/integration-libs/opf/base/core/services/opf-endpoints.service.spec.ts @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { TestBed } from '@angular/core/testing'; +import { of } from 'rxjs'; + import { BaseSiteService, StringTemplate } from '@spartacus/core'; import { OpfApiConfig, OpfConfig } from '@spartacus/opf/base/root'; - import { OpfEndpointsService } from './opf-endpoints.service'; -import { TestBed } from '@angular/core/testing'; -import { of } from 'rxjs'; describe('OpfEndpointsService', () => { let service: OpfEndpointsService; From 2d54082ff2780152944a8fb218504c3879170f16 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Tue, 16 Sep 2025 16:00:53 +0530 Subject: [PATCH 19/49] Addressing review comments changed handleNoDefaultAddress method to protected and added optional chaining to address in case address is undefined or null --- .../opf-checkout-billing-address-form.service.ts | 3 ++- projects/core/src/user/facade/user-address.service.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index 4a4b71a11ec..e0f5eba11b0 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -74,10 +74,11 @@ export class OpfCheckoutBillingAddressFormService { get pickupNoDefaultAddress$(): Observable { return this._pickupNoDefaultAddress$.asObservable(); } - private handleNoDefaultAddress(): void { + protected handleNoDefaultAddress(): void { this.setIsSameAsDeliveryValue(false); this._pickupNoDefaultAddress$.next(); } + getCountries(): Observable { return this.userPaymentService.getAllBillingCountries().pipe( tap((countries) => { diff --git a/projects/core/src/user/facade/user-address.service.ts b/projects/core/src/user/facade/user-address.service.ts index 68d34d70b30..590c9baa53c 100644 --- a/projects/core/src/user/facade/user-address.service.ts +++ b/projects/core/src/user/facade/user-address.service.ts @@ -113,7 +113,7 @@ export class UserAddressService { */ getDefaultAddress(): Observable
{ return this.getAddresses().pipe( - map((addresses) => addresses.find((address) => address.defaultAddress)) + map((addresses) => addresses?.find((address) => address.defaultAddress)) ); } From 8ed39d95425ded4e90b49fa9a22ffa1f8bf77025 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Tue, 16 Sep 2025 17:22:05 +0530 Subject: [PATCH 20/49] Addressing review comments(deliveryMode) --- .../guards/checkout-steps-set.guard.spec.ts | 54 ------------------- .../guards/checkout-steps-set.guard.ts | 5 -- ...checkout-billing-address-form.component.ts | 16 ++++-- ...ckout-payment-and-review.component.spec.ts | 52 +++++++++++++++++- ...f-checkout-payment-and-review.component.ts | 14 +++++ 5 files changed, 77 insertions(+), 64 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts index 7e85f1e08f3..b3a31dc76c5 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.spec.ts @@ -79,7 +79,6 @@ class MockCheckoutDeliveryAddressFacade getDeliveryAddressState = createSpy().and.returnValue( of({ loading: false, error: false, data: undefined }) ); - clearCheckoutDeliveryAddress = createSpy(); } class MockCheckoutDeliveryModesFacade @@ -299,57 +298,4 @@ describe(`CheckoutStepsSetGuard`, () => { }); }); }); - - describe('pickup only cart (no delivery items)', () => { - beforeEach(() => { - // Simulate a cart with only pickup items - hasDeliveryItems$.next(false); - ( - checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy - ).calls.reset(); - ( - checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy - ).calls.reset(); - }); - - it('should clear delivery address, set delivery mode to pickup, and return true for any step', (done) => { - guard - .canActivate({ url: ['checkout', 'route2'] }) - .subscribe((result) => { - expect( - checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress - ).toHaveBeenCalled(); - expect( - checkoutDeliveryModesFacade.setDeliveryMode - ).toHaveBeenCalledWith('pickup'); - expect(result).toBe(true); - done(); - }); - }); - }); - - describe('cart with delivery items', () => { - beforeEach(() => { - // Simulate a cart with delivery items - hasDeliveryItems$.next(true); - ( - checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress as jasmine.Spy - ).calls.reset(); - ( - checkoutDeliveryModesFacade.setDeliveryMode as jasmine.Spy - ).calls.reset(); - }); - - it('should NOT clear delivery address or set delivery mode for any step', (done) => { - guard.canActivate({ url: ['checkout', 'route2'] }).subscribe(() => { - expect( - checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress - ).not.toHaveBeenCalled(); - expect( - checkoutDeliveryModesFacade.setDeliveryMode - ).not.toHaveBeenCalled(); - done(); - }); - }); - }); }); diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts index a5a0d7b0db4..9f1c99e087c 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts @@ -106,11 +106,6 @@ export class CheckoutStepsSetGuard implements OnDestroy { } protected isStepSet(step: CheckoutStep): Observable { - if (!this.hasDeliveryItemsInCart) { - this.checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress(); - this.checkoutDeliveryModesFacade.setDeliveryMode('pickup'); - return of(true); - } if (step && !step.disabled) { switch (step.type[0]) { case CheckoutStepType.DELIVERY_ADDRESS: { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index a198223aea5..028b3759dcf 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -9,10 +9,11 @@ import { Component, OnInit, inject, + OnDestroy, } from '@angular/core'; import { Address, Country, UserAddressService } from '@spartacus/core'; import { ICON_TYPE } from '@spartacus/storefront'; -import { Observable } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; @Component({ @@ -21,7 +22,7 @@ import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, }) -export class OpfCheckoutBillingAddressFormComponent implements OnInit { +export class OpfCheckoutBillingAddressFormComponent implements OnInit, OnDestroy { protected service = inject(OpfCheckoutBillingAddressFormService); protected userAddressService = inject(UserAddressService); protected activeCartFacade = inject(ActiveCartFacade); @@ -29,6 +30,7 @@ export class OpfCheckoutBillingAddressFormComponent implements OnInit { protected cart: Cart | null = null; iconTypes = ICON_TYPE; + subscription = new Subscription(); billingAddress$ = this.service.billingAddress$; isLoadingAddress$ = this.service.isLoadingAddress$; @@ -40,15 +42,17 @@ export class OpfCheckoutBillingAddressFormComponent implements OnInit { countries$: Observable; ngOnInit() { - this.activeCartFacade.getActive().subscribe((cart) => (this.cart = cart)); + this.subscription.add(this.activeCartFacade.getActive().subscribe((cart) => (this.cart = cart))); this.countries$ = this.service.getCountries(); this.userAddressService.loadAddresses(); this.service.setDefaultBillingAddress(); this.service.getAddresses(); + this.subscription.add( this.service.pickupNoDefaultAddress$.subscribe(() => { this.isEditBillingAddress = true; this.isAddingBillingAddressInProgress = true; - }); + }) + ); } cancelAndHideForm(): void { @@ -91,4 +95,8 @@ export class OpfCheckoutBillingAddressFormComponent implements OnInit { this.service.setBillingAddress(address).subscribe(); } + + ngOnDestroy(): void { + this.subscription.unsubscribe(); + } } diff --git a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts index 06ac2ad5f56..a1806e3f7e0 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts @@ -17,9 +17,10 @@ import { CheckoutDeliveryAddressFacade, CheckoutDeliveryModesFacade, } from '@spartacus/checkout/base/root'; -import { DeliveryMode } from '@spartacus/cart/base/root'; +import { ActiveCartFacade, DeliveryMode } from '@spartacus/cart/base/root'; import { Component, Input, Pipe, PipeTransform } from '@angular/core'; import { Store } from '@ngrx/store'; +import { finalize } from 'rxjs/operators'; @Pipe({ name: 'cxTranslate', @@ -123,6 +124,7 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { getDeliveryAddressState: jasmine .createSpy('getDeliveryAddressState') .and.returnValue(of({})), + clearCheckoutDeliveryAddress: jasmine.createSpy('clearCheckoutDeliveryAddress'), }; const mockCheckoutPaymentFacade = { @@ -135,6 +137,7 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { getSelectedDeliveryModeState: jasmine .createSpy('getSelectedDeliveryModeState') .and.returnValue(of({})), + setDeliveryMode: jasmine.createSpy('setDeliveryMode'), }; const mockCheckoutFlowOrchestratorService = { @@ -143,6 +146,10 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { .and.returnValue(of(OPF_CHECKOUT_FLOW_NAME)), }; + const mockActiveCartFacade = { + hasDeliveryItems: jasmine.createSpy('hasDeliveryItems'), + }; + beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ @@ -172,6 +179,7 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { { provide: TranslationService, useClass: MockTranslationService }, { provide: Store, useClass: MockStore }, { provide: CmsService, useClass: MockCmsService }, + { provide: ActiveCartFacade, useValue: mockActiveCartFacade }, ], }).compileComponents(); }); @@ -186,6 +194,10 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { ( checkoutFlowOrchestratorService.getPaymentProvider as jasmine.Spy ).calls.reset(); + mockActiveCartFacade.hasDeliveryItems.calls.reset(); + mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress.calls.reset(); + mockCheckoutDeliveryModesFacade.setDeliveryMode.calls.reset(); + }); it('should create', () => { @@ -226,4 +238,42 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { expect(card.text).toBeDefined(); }); }); + + it('should clear delivery address and set pickup mode when cart has no delivery items', () => { + + mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(false)); + + + component.setPickupDeliveryMode(); + + expect(mockActiveCartFacade.hasDeliveryItems).toHaveBeenCalled(); + expect(mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).toHaveBeenCalled(); + expect(mockCheckoutDeliveryModesFacade.setDeliveryMode).toHaveBeenCalledWith('pickup'); + }); + it('should not modify delivery settings when cart has delivery items', () => { + mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(true)); + + component.setPickupDeliveryMode(); + + expect(mockActiveCartFacade.hasDeliveryItems).toHaveBeenCalled(); + expect(mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).not.toHaveBeenCalled(); + expect(mockCheckoutDeliveryModesFacade.setDeliveryMode).not.toHaveBeenCalled(); + }); + + it('should handle Observable completion correctly', () => { + const completionSpy = jasmine.createSpy('completion'); + + mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(false).pipe( + finalize(() => { + completionSpy(); + }) + )); + + component.setPickupDeliveryMode(); + + expect(completionSpy).toHaveBeenCalled(); + expect(mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).toHaveBeenCalled(); + expect(mockCheckoutDeliveryModesFacade.setDeliveryMode).toHaveBeenCalledWith('pickup'); + }); + }); diff --git a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts index b40eabbf02c..db6d5cb35c6 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts @@ -15,8 +15,10 @@ import { UntypedFormGroup, Validators, } from '@angular/forms'; +import { ActiveCartFacade } from '@spartacus/cart/base/root'; import { CheckoutPaymentTypeFacade } from '@spartacus/checkout/b2b/root'; import { CheckoutReviewSubmitComponent } from '@spartacus/checkout/base/components'; +import { CheckoutDeliveryModesFacade } from '@spartacus/checkout/base/root'; import { CmsService, Page } from '@spartacus/core'; import { OpfBaseFacade, @@ -40,6 +42,8 @@ export class OpfCheckoutPaymentAndReviewComponent protected cmsService = inject(CmsService); protected checkoutPaymentTypeFacade = inject(CheckoutPaymentTypeFacade); protected opfBaseFacade = inject(OpfBaseFacade); + protected checkoutDeliveryModesFacade = inject(CheckoutDeliveryModesFacade); + protected activeCartFacade = inject(ActiveCartFacade); protected defaultTermsAndConditionsFieldValue = false; @@ -100,7 +104,17 @@ export class OpfCheckoutPaymentAndReviewComponent this.selectedPaymentProviderName$.next(providerName); } + setPickupDeliveryMode(): void { + this.activeCartFacade.hasDeliveryItems().pipe(take(1)).subscribe((hasDeliveryItems) => { + if (!hasDeliveryItems) { + this.checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress(); + this.checkoutDeliveryModesFacade.setDeliveryMode('pickup'); + } + }); + } + ngOnInit() { this.updateTermsAndConditionsState(); + this.setPickupDeliveryMode(); } } From 800e497297e09d7b33c911b12b313830e851cd88 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Tue, 16 Sep 2025 18:26:45 +0530 Subject: [PATCH 21/49] fixed prettier formatting error --- ...checkout-billing-address-form.component.ts | 18 +++-- ...ckout-payment-and-review.component.spec.ts | 78 +++++++++++-------- ...f-checkout-payment-and-review.component.ts | 17 ++-- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 028b3759dcf..edd33b15b8f 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -22,7 +22,9 @@ import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, }) -export class OpfCheckoutBillingAddressFormComponent implements OnInit, OnDestroy { +export class OpfCheckoutBillingAddressFormComponent + implements OnInit, OnDestroy +{ protected service = inject(OpfCheckoutBillingAddressFormService); protected userAddressService = inject(UserAddressService); protected activeCartFacade = inject(ActiveCartFacade); @@ -42,17 +44,19 @@ export class OpfCheckoutBillingAddressFormComponent implements OnInit, OnDestroy countries$: Observable; ngOnInit() { - this.subscription.add(this.activeCartFacade.getActive().subscribe((cart) => (this.cart = cart))); + this.subscription.add( + this.activeCartFacade.getActive().subscribe((cart) => (this.cart = cart)) + ); this.countries$ = this.service.getCountries(); this.userAddressService.loadAddresses(); this.service.setDefaultBillingAddress(); this.service.getAddresses(); this.subscription.add( - this.service.pickupNoDefaultAddress$.subscribe(() => { - this.isEditBillingAddress = true; - this.isAddingBillingAddressInProgress = true; - }) - ); + this.service.pickupNoDefaultAddress$.subscribe(() => { + this.isEditBillingAddress = true; + this.isAddingBillingAddressInProgress = true; + }) + ); } cancelAndHideForm(): void { diff --git a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts index a1806e3f7e0..241a80b48af 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.spec.ts @@ -124,7 +124,9 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { getDeliveryAddressState: jasmine .createSpy('getDeliveryAddressState') .and.returnValue(of({})), - clearCheckoutDeliveryAddress: jasmine.createSpy('clearCheckoutDeliveryAddress'), + clearCheckoutDeliveryAddress: jasmine.createSpy( + 'clearCheckoutDeliveryAddress' + ), }; const mockCheckoutPaymentFacade = { @@ -194,10 +196,9 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { ( checkoutFlowOrchestratorService.getPaymentProvider as jasmine.Spy ).calls.reset(); - mockActiveCartFacade.hasDeliveryItems.calls.reset(); - mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress.calls.reset(); - mockCheckoutDeliveryModesFacade.setDeliveryMode.calls.reset(); - + mockActiveCartFacade.hasDeliveryItems.calls.reset(); + mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress.calls.reset(); + mockCheckoutDeliveryModesFacade.setDeliveryMode.calls.reset(); }); it('should create', () => { @@ -239,41 +240,52 @@ describe('OpfCheckoutPaymentAndReviewComponent', () => { }); }); - it('should clear delivery address and set pickup mode when cart has no delivery items', () => { - - mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(false)); + it('should clear delivery address and set pickup mode when cart has no delivery items', () => { + mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(false)); + component.setPickupDeliveryMode(); - component.setPickupDeliveryMode(); - - expect(mockActiveCartFacade.hasDeliveryItems).toHaveBeenCalled(); - expect(mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).toHaveBeenCalled(); - expect(mockCheckoutDeliveryModesFacade.setDeliveryMode).toHaveBeenCalledWith('pickup'); - }); - it('should not modify delivery settings when cart has delivery items', () => { - mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(true)); - - component.setPickupDeliveryMode(); - - expect(mockActiveCartFacade.hasDeliveryItems).toHaveBeenCalled(); - expect(mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).not.toHaveBeenCalled(); - expect(mockCheckoutDeliveryModesFacade.setDeliveryMode).not.toHaveBeenCalled(); - }); + expect(mockActiveCartFacade.hasDeliveryItems).toHaveBeenCalled(); + expect( + mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress + ).toHaveBeenCalled(); + expect( + mockCheckoutDeliveryModesFacade.setDeliveryMode + ).toHaveBeenCalledWith('pickup'); + }); + it('should not modify delivery settings when cart has delivery items', () => { + mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(true)); + + component.setPickupDeliveryMode(); + + expect(mockActiveCartFacade.hasDeliveryItems).toHaveBeenCalled(); + expect( + mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress + ).not.toHaveBeenCalled(); + expect( + mockCheckoutDeliveryModesFacade.setDeliveryMode + ).not.toHaveBeenCalled(); + }); - it('should handle Observable completion correctly', () => { - const completionSpy = jasmine.createSpy('completion'); + it('should handle Observable completion correctly', () => { + const completionSpy = jasmine.createSpy('completion'); - mockActiveCartFacade.hasDeliveryItems.and.returnValue(of(false).pipe( + mockActiveCartFacade.hasDeliveryItems.and.returnValue( + of(false).pipe( finalize(() => { completionSpy(); }) - )); - - component.setPickupDeliveryMode(); + ) + ); - expect(completionSpy).toHaveBeenCalled(); - expect(mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress).toHaveBeenCalled(); - expect(mockCheckoutDeliveryModesFacade.setDeliveryMode).toHaveBeenCalledWith('pickup'); - }); + component.setPickupDeliveryMode(); + expect(completionSpy).toHaveBeenCalled(); + expect( + mockCheckoutDeliveryAddressFacade.clearCheckoutDeliveryAddress + ).toHaveBeenCalled(); + expect( + mockCheckoutDeliveryModesFacade.setDeliveryMode + ).toHaveBeenCalledWith('pickup'); + }); }); diff --git a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts index db6d5cb35c6..7bd6b257da1 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payment-and-review/opf-checkout-payment-and-review.component.ts @@ -104,13 +104,16 @@ export class OpfCheckoutPaymentAndReviewComponent this.selectedPaymentProviderName$.next(providerName); } - setPickupDeliveryMode(): void { - this.activeCartFacade.hasDeliveryItems().pipe(take(1)).subscribe((hasDeliveryItems) => { - if (!hasDeliveryItems) { - this.checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress(); - this.checkoutDeliveryModesFacade.setDeliveryMode('pickup'); - } - }); + setPickupDeliveryMode(): void { + this.activeCartFacade + .hasDeliveryItems() + .pipe(take(1)) + .subscribe((hasDeliveryItems) => { + if (!hasDeliveryItems) { + this.checkoutDeliveryAddressFacade.clearCheckoutDeliveryAddress(); + this.checkoutDeliveryModesFacade.setDeliveryMode('pickup'); + } + }); } ngOnInit() { From 7c15215fc031720e6b27eb3f63d1a6241336b583 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Thu, 18 Sep 2025 14:43:03 +0530 Subject: [PATCH 22/49] variable rename --- .../opf-checkout-billing-address-form.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index e0f5eba11b0..db224e7c9df 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -57,7 +57,7 @@ export class OpfCheckoutBillingAddressFormService { OpfCheckoutPaymentWrapperService ); protected userAddressService = inject(UserAddressService); - protected _pickupNoDefaultAddress$ = new Subject(); + protected _noDefaultAddressFoundForPickupMode$ = new Subject(); protected pickupOptionFacade = inject(PickupOptionFacade); protected readonly _$billingAddressSub = new BehaviorSubject< @@ -72,11 +72,11 @@ export class OpfCheckoutBillingAddressFormService { isSameAsDelivery$ = this._$isSameAsDelivery.asObservable(); get pickupNoDefaultAddress$(): Observable { - return this._pickupNoDefaultAddress$.asObservable(); + return this._noDefaultAddressFoundForPickupMode$.asObservable(); } protected handleNoDefaultAddress(): void { this.setIsSameAsDeliveryValue(false); - this._pickupNoDefaultAddress$.next(); + this._noDefaultAddressFoundForPickupMode$.next(); } getCountries(): Observable { From ddd293c2881f8500d07f0a8be289c044e3bbc999 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Thu, 18 Sep 2025 14:48:18 +0530 Subject: [PATCH 23/49] fixed testcases --- .../opf-checkout-billing-address-form.service.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index 070d1b23872..91692463686 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -97,7 +97,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { { provide: Store, useValue: { pipe: () => of(undefined) } }, { provide: UserAddressAdapter, useValue: {} }, { - provide: '_pickupNoDefaultAddress$', + provide: '_noDefaultAddressFoundForPickupMode$', useValue: mockPickupNoDefaultAddress$, }, { provide: UserAddressService, useValue: mockUserAddressService }, @@ -273,7 +273,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { it('should return an observable from pickupNoDefaultAddress$', () => { spyOn(mockPickupNoDefaultAddress$, 'asObservable').and.callThrough(); - (service as any)._pickupNoDefaultAddress$ = mockPickupNoDefaultAddress$; + (service as any)._noDefaultAddressFoundForPickupMode$ = mockPickupNoDefaultAddress$; const result: Observable = service.pickupNoDefaultAddress$; From 3821d25b58718f1bde45d28475421cc9551224e1 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Thu, 18 Sep 2025 15:34:07 +0530 Subject: [PATCH 24/49] fixed formatting issue --- .../opf-checkout-billing-address-form.service.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index 91692463686..6a406d43c0b 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -273,7 +273,8 @@ describe('OpfCheckoutBillingAddressFormService', () => { it('should return an observable from pickupNoDefaultAddress$', () => { spyOn(mockPickupNoDefaultAddress$, 'asObservable').and.callThrough(); - (service as any)._noDefaultAddressFoundForPickupMode$ = mockPickupNoDefaultAddress$; + (service as any)._noDefaultAddressFoundForPickupMode$ = + mockPickupNoDefaultAddress$; const result: Observable = service.pickupNoDefaultAddress$; From 42d6df66ff8afa7dae50500e3e9830aaa1e76171 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Fri, 19 Sep 2025 11:45:42 +0530 Subject: [PATCH 25/49] changes reverted --- .../base/components/guards/checkout-steps-set.guard.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts index 9f1c99e087c..001d45193cd 100644 --- a/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts +++ b/feature-libs/checkout/base/components/guards/checkout-steps-set.guard.ts @@ -4,12 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { inject, Injectable, isDevMode, OnDestroy } from '@angular/core'; import { ActivatedRouteSnapshot, GuardResult, Router, UrlTree, } from '@angular/router'; +import { ActiveCartFacade } from '@spartacus/cart/base/root'; import { CheckoutDeliveryAddressFacade, CheckoutDeliveryModesFacade, @@ -17,9 +19,8 @@ import { CheckoutStep, CheckoutStepType, } from '@spartacus/checkout/base/root'; -import { Injectable, OnDestroy, inject, isDevMode } from '@angular/core'; import { LoggerService, RoutingConfigService } from '@spartacus/core'; -import { Observable, Subscription, of } from 'rxjs'; +import { Observable, of, Subscription } from 'rxjs'; import { distinctUntilChanged, filter, @@ -27,8 +28,6 @@ import { switchMap, take, } from 'rxjs/operators'; - -import { ActiveCartFacade } from '@spartacus/cart/base/root'; import { CheckoutStepService } from '../services/checkout-step.service'; @Injectable({ @@ -37,7 +36,7 @@ import { CheckoutStepService } from '../services/checkout-step.service'; export class CheckoutStepsSetGuard implements OnDestroy { protected subscription: Subscription; protected logger = inject(LoggerService); - protected hasDeliveryItemsInCart: boolean; + constructor( protected checkoutStepService: CheckoutStepService, protected routingConfigService: RoutingConfigService, @@ -51,7 +50,6 @@ export class CheckoutStepsSetGuard implements OnDestroy { .hasDeliveryItems() .pipe(distinctUntilChanged()) .subscribe((hasDeliveryItems) => { - this.hasDeliveryItemsInCart = hasDeliveryItems; this.checkoutStepService.disableEnableStep( CheckoutStepType.DELIVERY_ADDRESS, !hasDeliveryItems From 2b06d521bcf613af2bcd19dab97abecb416d88b0 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 24 Sep 2025 16:52:27 +0530 Subject: [PATCH 26/49] fix: no billing address disables payment options --- ...opf-checkout-billing-address-form.component.html | 2 +- .../opf-checkout-billing-address-form.component.ts | 9 ++++++++- .../opf-checkout-billing-address-form.service.ts | 12 +++++++++++- .../opf-checkout-payments.component.html | 13 ++++++------- .../opf-checkout-payments.component.spec.ts | 12 ++++++++++++ .../opf-checkout-payments.component.ts | 3 +++ .../opf-checkout-review-cart-details.component.html | 2 +- .../opf-checkout-review-cart-details.component.ts | 4 +++- ...eckout-terms-and-conditions-alert.component.html | 2 +- ...out-terms-and-conditions-alert.component.spec.ts | 13 +++++++++++++ ...checkout-terms-and-conditions-alert.component.ts | 3 +++ .../_opf-checkout-payment-and-review.scss | 2 +- 12 files changed, 63 insertions(+), 14 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html index 0df8acf7c3d..23247052169 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html @@ -48,7 +48,7 @@

{{ 'opfCheckout.billingAddress' | cxTranslate }}

[addressData]="getAddressData(addressData.billingAddress)" class="cx-form" [showTitleCode]="true" - [showCancelBtn]="true" + [showCancelBtn]="!(service.paymentOptionsDisabled$ | async)" actionBtnLabel="{{ 'common.save' | cxTranslate }}" cancelBtnLabel="{{ 'common.cancel' | cxTranslate }}" (submitAddress)="onSubmitAddress($event)" diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index edd33b15b8f..a782de6e40f 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -97,7 +97,14 @@ export class OpfCheckoutBillingAddressFormComponent return; } - this.service.setBillingAddress(address).subscribe(); + this.service.setBillingAddress(address).subscribe({ + next: () => { + this.service.setPaymentOptionsDisabled(false); + }, + error: () => { + this.service.setPaymentOptionsDisabled(true); + } + }); } ngOnDestroy(): void { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index db224e7c9df..4bc10e1ddf8 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -70,13 +70,20 @@ export class OpfCheckoutBillingAddressFormService { billingAddress$ = this._$billingAddressSub.asObservable(); isLoadingAddress$ = this._$isLoadingAddress.asObservable(); isSameAsDelivery$ = this._$isSameAsDelivery.asObservable(); + protected readonly _$paymentOptionsDisabled = new BehaviorSubject(false); + paymentOptionsDisabled$ = this._$paymentOptionsDisabled.asObservable(); get pickupNoDefaultAddress$(): Observable { return this._noDefaultAddressFoundForPickupMode$.asObservable(); } + + setPaymentOptionsDisabled(value: boolean): void { + this._$paymentOptionsDisabled.next(value); + } protected handleNoDefaultAddress(): void { this.setIsSameAsDeliveryValue(false); this._noDefaultAddressFoundForPickupMode$.next(); + this.setPaymentOptionsDisabled(true); } getCountries(): Observable { @@ -104,7 +111,10 @@ export class OpfCheckoutBillingAddressFormService { } }), filter((addr): addr is Address => !!addr), - switchMap((defaultAddress) => this.setBillingAddress(defaultAddress)), + switchMap((defaultAddress) => { + this.setPaymentOptionsDisabled(false); + return this.setBillingAddress(defaultAddress); + }), catchError(() => { this.globalMessageService.add( { key: 'opfCheckout.errors.loadDefaultAddress' }, diff --git a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.html b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.html index 98ecba3e0a5..354e1fb3f66 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.html @@ -31,13 +31,12 @@

class="form-check-input" role="radio" type="radio" - [attr.aria-checked]="configuration.id === selectedPaymentId" + [attr.aria-checked]="(paymentDisabled$ | async) && configuration.id === selectedPaymentId" (change)="changePayment(configuration)" [value]="configuration.id" - [checked]="configuration.id === selectedPaymentId" + [checked]="!(paymentDisabled$ | async) && configuration.id === selectedPaymentId" formControlName="paymentId" - [disabled]="disabled && explicitTermsAndConditions" - /> + [disabled]="(paymentDisabled$ | async) || (disabled && explicitTermsAndConditions)" />

- +
- + - + \ No newline at end of file diff --git a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts index 9a641eb0c2a..b8f79c4eba9 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts @@ -28,6 +28,7 @@ import { By } from '@angular/platform-browser'; import { BehaviorSubject, Observable, of } from 'rxjs'; import { OpfCheckoutTermsAndConditionsAlertModule } from '../opf-checkout-terms-and-conditions-alert'; import { OpfCheckoutPaymentsComponent } from './opf-checkout-payments.component'; +import { OpfCheckoutBillingAddressFormService } from '../opf-checkout-billing-address-form'; @Component({ template: '', @@ -105,6 +106,8 @@ describe('OpfCheckoutPaymentsComponent', () => { let globalMessageService: GlobalMessageService; let opfMetadataStoreServiceMock: jasmine.SpyObj; let el: DebugElement; + let mockBillingAddressFormService: Partial; + beforeEach(async () => { opfMetadataStoreServiceMock = jasmine.createSpyObj( @@ -115,6 +118,10 @@ describe('OpfCheckoutPaymentsComponent', () => { opfMetadataStoreServiceMock.getOpfMetadataState.and.returnValue( of(mockOpfMetadata) ); + mockBillingAddressFormService = { + paymentOptionsDisabled$: of(false), // Mock the observable + }; + await TestBed.configureTestingModule({ imports: [I18nTestingModule, OpfCheckoutTermsAndConditionsAlertModule], declarations: [ @@ -132,6 +139,11 @@ describe('OpfCheckoutPaymentsComponent', () => { provide: OpfMetadataStoreService, useValue: opfMetadataStoreServiceMock, }, + { + provide: OpfCheckoutBillingAddressFormService, + useValue: mockBillingAddressFormService, + + } ], }).compileComponents(); diff --git a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts index be51a9dc148..3479fec73fa 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts @@ -34,6 +34,7 @@ import { import { ICON_TYPE } from '@spartacus/storefront'; import { Observable, Subscription } from 'rxjs'; import { tap } from 'rxjs/operators'; +import { OpfCheckoutBillingAddressFormService } from '../opf-checkout-billing-address-form'; @Component({ selector: 'cx-opf-checkout-payments', @@ -47,6 +48,7 @@ export class OpfCheckoutPaymentsComponent implements OnInit, OnDestroy { protected translation = inject(TranslationService); protected opfMetadataStoreService = inject(OpfMetadataStoreService); protected globalMessageService = inject(GlobalMessageService); + protected opfCheckoutBillingAddressFormService = inject(OpfCheckoutBillingAddressFormService); protected subscription = new Subscription(); @@ -109,6 +111,7 @@ export class OpfCheckoutPaymentsComponent implements OnInit, OnDestroy { @Output() selectedPaymentProviderName = new EventEmitter(); protected paginationModel: PaginationModel | undefined; + protected paymentDisabled$ = this.opfCheckoutBillingAddressFormService.paymentOptionsDisabled$; protected isStateEmpty( state: QueryState diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html index 272cead5606..5e00b658db0 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.html @@ -23,7 +23,7 @@
{{ 'opfCheckout.itemsToBeShipped' | cxTranslate }}
-
+
+
- +
- + - \ No newline at end of file + diff --git a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts index b8f79c4eba9..8514bd7c299 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts @@ -108,7 +108,6 @@ describe('OpfCheckoutPaymentsComponent', () => { let el: DebugElement; let mockBillingAddressFormService: Partial; - beforeEach(async () => { opfMetadataStoreServiceMock = jasmine.createSpyObj( 'OpfMetadataStoreService', @@ -118,7 +117,7 @@ describe('OpfCheckoutPaymentsComponent', () => { opfMetadataStoreServiceMock.getOpfMetadataState.and.returnValue( of(mockOpfMetadata) ); - mockBillingAddressFormService = { + mockBillingAddressFormService = { paymentOptionsDisabled$: of(false), // Mock the observable }; @@ -142,8 +141,7 @@ describe('OpfCheckoutPaymentsComponent', () => { { provide: OpfCheckoutBillingAddressFormService, useValue: mockBillingAddressFormService, - - } + }, ], }).compileComponents(); diff --git a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts index 3479fec73fa..4321c961e09 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.ts @@ -48,7 +48,9 @@ export class OpfCheckoutPaymentsComponent implements OnInit, OnDestroy { protected translation = inject(TranslationService); protected opfMetadataStoreService = inject(OpfMetadataStoreService); protected globalMessageService = inject(GlobalMessageService); - protected opfCheckoutBillingAddressFormService = inject(OpfCheckoutBillingAddressFormService); + protected opfCheckoutBillingAddressFormService = inject( + OpfCheckoutBillingAddressFormService + ); protected subscription = new Subscription(); @@ -111,7 +113,8 @@ export class OpfCheckoutPaymentsComponent implements OnInit, OnDestroy { @Output() selectedPaymentProviderName = new EventEmitter(); protected paginationModel: PaginationModel | undefined; - protected paymentDisabled$ = this.opfCheckoutBillingAddressFormService.paymentOptionsDisabled$; + protected paymentDisabled$ = + this.opfCheckoutBillingAddressFormService.paymentOptionsDisabled$; protected isStateEmpty( state: QueryState diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts index 3d598aa6f79..880545d986e 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts @@ -23,7 +23,7 @@ export class OpfCheckoutReviewCartDetailsComponent extends CheckoutReviewSubmitC @Input() cart: Cart | null; @Input() entries: any[] | null; - @Input() isAddressCardVisible=false; + @Input() isAddressCardVisible = false; readonly promotionLocation: PromotionLocation = PromotionLocation.Checkout; cartOutlets = CartOutlets; } diff --git a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html index 45f9a6150fa..c498b835992 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html @@ -23,7 +23,7 @@ }}

- -
\ No newline at end of file +
diff --git a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.spec.ts index ac71c37f383..6802beec1fa 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.spec.ts @@ -40,11 +40,11 @@ describe('OpfCheckoutTermsAndConditionsAlertComponent', () => { MockTranslatePipe, ], providers: [ - { + { provide: OpfCheckoutBillingAddressFormService, useValue: mockBillingAddressFormService, }, - ] + ], }).compileComponents(); fixture = TestBed.createComponent( diff --git a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.ts b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.ts index cf2bfa46c1d..29103a74b2a 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.ts @@ -24,10 +24,13 @@ import { OpfCheckoutBillingAddressFormService } from '../opf-checkout-billing-ad }) export class OpfCheckoutTermsAndConditionsAlertComponent implements OnInit { protected opfMetadataStoreService = inject(OpfMetadataStoreService); - protected opfCheckoutBillingAddressFormService=inject(OpfCheckoutBillingAddressFormService); + protected opfCheckoutBillingAddressFormService = inject( + OpfCheckoutBillingAddressFormService + ); iconTypes = ICON_TYPE; - protected paymentDisabled$ = this.opfCheckoutBillingAddressFormService.paymentOptionsDisabled$; + protected paymentDisabled$ = + this.opfCheckoutBillingAddressFormService.paymentOptionsDisabled$; /** * Defines if alert could be dismissed or not From f139519148b6329bb994b9a450b4db78ac044560 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 1 Oct 2025 11:15:10 +0530 Subject: [PATCH 33/49] fix: noBillingAddress error message --- .../checkout/base/assets/translations/en/checkout.json | 3 ++- .../opf/checkout/assets/translations/en/opfCheckout.json | 2 +- .../opf-checkout-billing-address-form.component.html | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/feature-libs/checkout/base/assets/translations/en/checkout.json b/feature-libs/checkout/base/assets/translations/en/checkout.json index 412fc7a8ad7..040ff9dcb39 100644 --- a/feature-libs/checkout/base/assets/translations/en/checkout.json +++ b/feature-libs/checkout/base/assets/translations/en/checkout.json @@ -1,6 +1,7 @@ { "checkout": { - "backToCart": "Back to cart" + "backToCart": "Back to cart", + "back": "Back" }, "checkoutProgress": { "label": "Checkout Progress", diff --git a/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json b/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json index 336a3cab0fb..ed73541883c 100644 --- a/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json +++ b/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json @@ -33,7 +33,7 @@ "loadActiveConfigurations": "We are unable to load payment options at this time. Please try again later.", "noActiveConfigurations": "There are no payment options available at this time. Please try again later or contact support.", "updateBillingAddress": "The address could not be updated. Please check that the address information is correct and that your device is connected to the internet. If the problem persists, you may need to clear your cart and start the checkout again.", - "noBillingAddress": "A billing address is required to proceed with the payment" + "noBillingAddress": "Billing address is required" } } } diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html index 104f719e71d..f562c4e35f5 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html @@ -52,7 +52,7 @@

{{ 'opfCheckout.billingAddress' | cxTranslate }}

actionBtnLabel="{{ 'common.save' | cxTranslate }}" [cancelBtnLabel]=" (service.paymentOptionsDisabled$ | async) - ? ('checkout.backToCart' | cxTranslate) + ? ('checkout.back' | cxTranslate) : ('common.cancel' | cxTranslate) " (submitAddress)="onSubmitAddress($event)" From 6432ccc56e9bba77608a6ad1da216b546ebdef76 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 1 Oct 2025 11:55:41 +0530 Subject: [PATCH 34/49] unit testcases fixed --- .../opf-checkout-billing-address-form.component.spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts index c3c2559a69e..d6c881aa4de 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts @@ -8,7 +8,10 @@ import { BehaviorSubject, EMPTY, Observable, Subject, of } from 'rxjs'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Pipe, PipeTransform } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { ActiveCartFacade } from '@spartacus/cart/base/root'; +import { BaseSiteService } from '@spartacus/core'; +import { CheckoutStepService } from '@spartacus/checkout/base/components'; import { OpfCheckoutBillingAddressFormComponent } from './opf-checkout-billing-address-form.component'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { Store } from '@ngrx/store'; @@ -74,6 +77,9 @@ describe('OpfCheckoutBillingAddressFormComponent', () => { }, { provide: Store, useValue: {} }, { provide: UserAddressAdapter, useValue: {} }, + { provide: CheckoutStepService, useValue: {} }, + { provide: BaseSiteService, useValue: {} }, + { provide: ActivatedRoute, useValue: { params: of({}) } }, ], }).compileComponents(); From a35853c75fa8f1f064d366d8de0e28491866d405 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 1 Oct 2025 13:18:31 +0530 Subject: [PATCH 35/49] fixed formatting --- ...f-checkout-billing-address-form.service.ts | 15 +++++++------ ...opf-checkout-review-cart-details.module.ts | 9 ++++---- .../user/facade/user-address.service.spec.ts | 21 ++++++++----------- .../src/user/facade/user-address.service.ts | 15 +++++++------ 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index 226551ee943..1e960419bd6 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -4,14 +4,19 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { Injectable, inject } from '@angular/core'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; +import { + CheckoutBillingAddressFacade, + CheckoutDeliveryAddressFacade, + CheckoutPaymentFacade, +} from '@spartacus/checkout/base/root'; import { Address, Country, GlobalMessageService, GlobalMessageType, HttpErrorModel, - UserAddressService, UserPaymentService, } from '@spartacus/core'; import { @@ -23,12 +28,6 @@ import { of, throwError, } from 'rxjs'; -import { - CheckoutBillingAddressFacade, - CheckoutDeliveryAddressFacade, - CheckoutPaymentFacade, -} from '@spartacus/checkout/base/root'; -import { Injectable, inject } from '@angular/core'; import { catchError, filter, @@ -39,9 +38,9 @@ import { take, tap, } from 'rxjs/operators'; - import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; import { PickupOptionFacade } from '@spartacus/pickup-in-store/root'; +import { UserAddressService } from '@spartacus/core'; @Injectable() export class OpfCheckoutBillingAddressFormService { diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.module.ts b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.module.ts index 30a0262e753..422a162d3a2 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.module.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.module.ts @@ -4,14 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { I18nModule, UrlModule } from '@spartacus/core'; -import { OutletModule, PromotionsModule } from '@spartacus/storefront'; - -import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { OpfCheckoutReviewCardModule } from '../opf-checkout-review-card'; +import { CommonModule } from '@angular/common'; +import { I18nModule, UrlModule } from '@spartacus/core'; +import { PromotionsModule, OutletModule } from '@spartacus/storefront'; import { OpfCheckoutReviewCartDetailsComponent } from './opf-checkout-review-cart-details.component'; import { PickUpItemsDetailsModule } from '@spartacus/pickup-in-store/components'; +import { OpfCheckoutReviewCardModule } from '../opf-checkout-review-card'; @NgModule({ imports: [ diff --git a/projects/core/src/user/facade/user-address.service.spec.ts b/projects/core/src/user/facade/user-address.service.spec.ts index e48cf4cdf44..223e32e9c47 100644 --- a/projects/core/src/user/facade/user-address.service.spec.ts +++ b/projects/core/src/user/facade/user-address.service.spec.ts @@ -1,25 +1,22 @@ -import * as fromProcessReducers from '../../process/store/reducers'; -import * as fromStoreReducers from '../store/reducers/index'; - +import { inject, TestBed } from '@angular/core/testing'; +import { Store, StoreModule } from '@ngrx/store'; +import { Observable, of } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; import { Address, AddressValidation, Country, Region, } from '../../model/address.model'; -import { Observable, of } from 'rxjs'; -import { StateWithUser, USER_FEATURE } from '../store/user-state'; -import { Store, StoreModule } from '@ngrx/store'; -import { TestBed, inject } from '@angular/core/testing'; - import { OCC_USER_ID_CURRENT } from '../../occ/utils/occ-constants'; import { PROCESS_FEATURE } from '../../process/store/process-state'; -import { UserActions } from '../store/actions/index'; +import * as fromProcessReducers from '../../process/store/reducers'; import { UserAddressConnector } from '../connectors/address/user-address.connector'; +import { UserActions } from '../store/actions/index'; +import * as fromStoreReducers from '../store/reducers/index'; +import { StateWithUser, USER_FEATURE } from '../store/user-state'; import { UserAddressService } from './user-address.service'; -import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; -import { take } from 'rxjs/operators'; - import createSpy = jasmine.createSpy; class MockUserIdService implements Partial { diff --git a/projects/core/src/user/facade/user-address.service.ts b/projects/core/src/user/facade/user-address.service.ts index 590c9baa53c..e4461f4f1aa 100644 --- a/projects/core/src/user/facade/user-address.service.ts +++ b/projects/core/src/user/facade/user-address.service.ts @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { Injectable } from '@angular/core'; +import { select, Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; +import { map, switchMap } from 'rxjs/operators'; +import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; import { Address, AddressValidation, @@ -14,16 +19,10 @@ import { Command, CommandService, } from '../../util/command-query/command.service'; -import { Store, select } from '@ngrx/store'; -import { map, switchMap } from 'rxjs/operators'; - -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { StateWithUser } from '../store/user-state'; -import { UserActions } from '../store/actions/index'; import { UserAddressConnector } from '../connectors/address/user-address.connector'; -import { UserIdService } from '../../auth/user-auth/facade/user-id.service'; +import { UserActions } from '../store/actions/index'; import { UsersSelectors } from '../store/selectors/index'; +import { StateWithUser } from '../store/user-state'; @Injectable({ providedIn: 'root', From feab14be6b1ecd16c7a02b0dc5173f539519cdc9 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 1 Oct 2025 13:34:14 +0530 Subject: [PATCH 36/49] fixed sonarqube and formatting --- ...checkout-billing-address-form.component.spec.ts | 14 ++++++-------- .../opf-checkout-billing-address-form.component.ts | 3 ++- ...f-checkout-billing-address-form.service.spec.ts | 13 ++++++------- .../opf-checkout-billing-address-form.service.ts | 2 +- .../opf-checkout-review-cart-details.component.ts | 7 +++---- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts index d6c881aa4de..96b85ab91c1 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts @@ -3,18 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Address, Country, UserAddressAdapter } from '@spartacus/core'; -import { BehaviorSubject, EMPTY, Observable, Subject, of } from 'rxjs'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Pipe, PipeTransform } from '@angular/core'; - -import { ActivatedRoute } from '@angular/router'; -import { ActiveCartFacade } from '@spartacus/cart/base/root'; -import { BaseSiteService } from '@spartacus/core'; -import { CheckoutStepService } from '@spartacus/checkout/base/components'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Address, BaseSiteService, Country, UserAddressAdapter } from '@spartacus/core'; +import { BehaviorSubject, EMPTY, Observable, of,Subject } from 'rxjs'; import { OpfCheckoutBillingAddressFormComponent } from './opf-checkout-billing-address-form.component'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { Store } from '@ngrx/store'; +import { ActiveCartFacade } from '@spartacus/cart/base/root'; +import { CheckoutStepService } from '@spartacus/checkout/base/components'; +import { ActivatedRoute } from '@angular/router'; class Service { billingAddress$ = new BehaviorSubject
(undefined); diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 52dc8711da3..abcc8029c96 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -13,11 +13,12 @@ import { } from '@angular/core'; import { Address, Country, UserAddressService } from '@spartacus/core'; import { ICON_TYPE } from '@spartacus/storefront'; -import { Observable, Subscription } from 'rxjs'; +import { Observable,Subscription } from 'rxjs'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; import { ActivatedRoute } from '@angular/router'; import { CheckoutStepService } from '@spartacus/checkout/base/components'; + @Component({ selector: 'cx-opf-checkout-billing-address-form', templateUrl: './opf-checkout-billing-address-form.component.html', diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index 6a406d43c0b..1763083d5ad 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -3,7 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { fakeAsync, flush, TestBed } from '@angular/core/testing'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; +import { + CheckoutBillingAddressFacade, + CheckoutDeliveryAddressFacade, +} from '@spartacus/checkout/base/root'; import { Address, GlobalMessageService, @@ -13,14 +18,8 @@ import { UserPaymentService, } from '@spartacus/core'; import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; -import { - CheckoutBillingAddressFacade, - CheckoutDeliveryAddressFacade, -} from '@spartacus/checkout/base/root'; -import { TestBed, fakeAsync, flush } from '@angular/core/testing'; - -import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; +import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { Store } from '@ngrx/store'; describe('OpfCheckoutBillingAddressFormService', () => { diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index 1e960419bd6..c4d3f0d686c 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -18,6 +18,7 @@ import { GlobalMessageType, HttpErrorModel, UserPaymentService, + UserAddressService, } from '@spartacus/core'; import { BehaviorSubject, @@ -40,7 +41,6 @@ import { } from 'rxjs/operators'; import { OpfCheckoutPaymentWrapperService } from '../opf-checkout-payment-wrapper'; import { PickupOptionFacade } from '@spartacus/pickup-in-store/root'; -import { UserAddressService } from '@spartacus/core'; @Injectable() export class OpfCheckoutBillingAddressFormService { diff --git a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts index 880545d986e..c65f7eb22da 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-review-cart-details/opf-checkout-review-cart-details.component.ts @@ -4,13 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { - Cart, - CartOutlets, PromotionLocation, + CartOutlets, + Cart, } from '@spartacus/cart/base/root'; -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; - import { CheckoutReviewSubmitComponent } from '@spartacus/checkout/base/components'; @Component({ From 43f28be6851d1ffea473e06871136ce605b7c4ed Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 1 Oct 2025 14:38:26 +0530 Subject: [PATCH 37/49] fixed formatting --- ...out-billing-address-form.component.spec.ts | 9 +++++-- ...checkout-billing-address-form.component.ts | 2 +- ...-terms-and-conditions-alert.component.html | 24 +++++++++---------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts index 96b85ab91c1..95374da4f2e 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.spec.ts @@ -5,8 +5,13 @@ import { Pipe, PipeTransform } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Address, BaseSiteService, Country, UserAddressAdapter } from '@spartacus/core'; -import { BehaviorSubject, EMPTY, Observable, of,Subject } from 'rxjs'; +import { + Address, + Country, + BaseSiteService, + UserAddressAdapter, +} from '@spartacus/core'; +import { BehaviorSubject, EMPTY, Observable, of, Subject } from 'rxjs'; import { OpfCheckoutBillingAddressFormComponent } from './opf-checkout-billing-address-form.component'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { Store } from '@ngrx/store'; diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index abcc8029c96..8a83586f4f3 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -13,7 +13,7 @@ import { } from '@angular/core'; import { Address, Country, UserAddressService } from '@spartacus/core'; import { ICON_TYPE } from '@spartacus/storefront'; -import { Observable,Subscription } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; import { OpfCheckoutBillingAddressFormService } from './opf-checkout-billing-address-form.service'; import { ActiveCartFacade, Cart } from '@spartacus/cart/base/root'; import { ActivatedRoute } from '@angular/router'; diff --git a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html index c498b835992..bfb02d1dce9 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.component.html @@ -22,18 +22,18 @@ ) | cxTranslate }}

+ - From 97b5d395b9555be10ac766b5a037c847e8c66b67 Mon Sep 17 00:00:00 2001 From: Diksha Rahul Bhatkar Date: Fri, 3 Oct 2025 09:55:17 +0530 Subject: [PATCH 38/49] addressing review comments --- .../checkout/base/assets/translations/en/checkout.json | 3 +-- .../opf-checkout-billing-address-form.component.html | 2 +- .../opf-checkout-billing-address-form.component.ts | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/feature-libs/checkout/base/assets/translations/en/checkout.json b/feature-libs/checkout/base/assets/translations/en/checkout.json index 040ff9dcb39..412fc7a8ad7 100644 --- a/feature-libs/checkout/base/assets/translations/en/checkout.json +++ b/feature-libs/checkout/base/assets/translations/en/checkout.json @@ -1,7 +1,6 @@ { "checkout": { - "backToCart": "Back to cart", - "back": "Back" + "backToCart": "Back to cart" }, "checkoutProgress": { "label": "Checkout Progress", diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html index f562c4e35f5..ec641877bf1 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.html @@ -52,7 +52,7 @@

{{ 'opfCheckout.billingAddress' | cxTranslate }}

actionBtnLabel="{{ 'common.save' | cxTranslate }}" [cancelBtnLabel]=" (service.paymentOptionsDisabled$ | async) - ? ('checkout.back' | cxTranslate) + ? ('common.back' | cxTranslate) : ('common.cancel' | cxTranslate) " (submitAddress)="onSubmitAddress($event)" diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 8a83586f4f3..0e2e284e63e 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -80,8 +80,8 @@ export class OpfCheckoutBillingAddressFormComponent onBackToAddress(): void { this.subscription.add( - this.service.paymentOptionsDisabled$.subscribe((disabled) => - disabled ? this.back() : this.cancelAndHideForm() + this.service.paymentOptionsDisabled$.subscribe((isDisabled) => + isDisabled ? this.back() : this.cancelAndHideForm() ) ); } From e06decf79e36865a2b3b96fe66a00d8150ff2aec Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Fri, 3 Oct 2025 10:33:45 +0530 Subject: [PATCH 39/49] addressing review comments --- .../opf-checkout-billing-address-form.component.ts | 7 ++----- .../opf-checkout-billing-address-form.service.ts | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 0e2e284e63e..7e50f5328cf 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -31,6 +31,8 @@ export class OpfCheckoutBillingAddressFormComponent protected service = inject(OpfCheckoutBillingAddressFormService); protected userAddressService = inject(UserAddressService); protected activeCartFacade = inject(ActiveCartFacade); + protected checkoutStepService= inject(CheckoutStepService); + protected activatedRoute= inject(ActivatedRoute); protected cart: Cart | null = null; @@ -46,11 +48,6 @@ export class OpfCheckoutBillingAddressFormComponent countries$: Observable; - constructor( - protected checkoutStepService: CheckoutStepService, - protected activatedRoute: ActivatedRoute - ) {} - ngOnInit() { this.subscription.add( this.activeCartFacade.getActive().subscribe((cart) => (this.cart = cart)) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts index c4d3f0d686c..4aa780ab83f 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.ts @@ -102,7 +102,7 @@ export class OpfCheckoutBillingAddressFormService { .hasDeliveryItems() .pipe( take(1), - filter((hasDeliveryItems) => !hasDeliveryItems), + filter((hasDeliveryItems: boolean) => !hasDeliveryItems), switchMap(() => this.userAddressService.getDefaultAddress()), tap((defaultAddress) => { if (!defaultAddress) { @@ -110,7 +110,7 @@ export class OpfCheckoutBillingAddressFormService { } }), filter((addr): addr is Address => !!addr), - switchMap((defaultAddress) => { + switchMap((defaultAddress: Address) => { this.setPaymentOptionsDisabled(false); return this.setBillingAddress(defaultAddress); }), From f2c9db5b227130833d26d333386aab65547ca87d Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Fri, 3 Oct 2025 10:57:46 +0530 Subject: [PATCH 40/49] fixed formatting --- .../opf-checkout-billing-address-form.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts index 7e50f5328cf..6e37ee4eb9a 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.component.ts @@ -31,8 +31,8 @@ export class OpfCheckoutBillingAddressFormComponent protected service = inject(OpfCheckoutBillingAddressFormService); protected userAddressService = inject(UserAddressService); protected activeCartFacade = inject(ActiveCartFacade); - protected checkoutStepService= inject(CheckoutStepService); - protected activatedRoute= inject(ActivatedRoute); + protected checkoutStepService = inject(CheckoutStepService); + protected activatedRoute = inject(ActivatedRoute); protected cart: Cart | null = null; From 5e1b18012b7a85da7971030a60a03b2b7a928396 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Fri, 3 Oct 2025 13:59:24 +0530 Subject: [PATCH 41/49] fix build error --- feature-libs/estimated-delivery-date/public_api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/feature-libs/estimated-delivery-date/public_api.ts b/feature-libs/estimated-delivery-date/public_api.ts index 857c631da55..d845a5541a6 100644 --- a/feature-libs/estimated-delivery-date/public_api.ts +++ b/feature-libs/estimated-delivery-date/public_api.ts @@ -9,3 +9,4 @@ */ export * from './estimated-delivery-date.module'; export * from './show-estimated-delivery-date/public_api'; +export * from './assets/public_api'; From fa56d6ad94a4464c0c6b1857ceaeaea37a4e9fa4 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Mon, 6 Oct 2025 10:37:40 +0530 Subject: [PATCH 42/49] fixed error 'cxfeature' can't bind --- .../pickup-items-details/pickup-items-details.module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/feature-libs/pickup-in-store/components/container/pickup-items-details/pickup-items-details.module.ts b/feature-libs/pickup-in-store/components/container/pickup-items-details/pickup-items-details.module.ts index 200ae957d1e..dbdfd08a6ad 100644 --- a/feature-libs/pickup-in-store/components/container/pickup-items-details/pickup-items-details.module.ts +++ b/feature-libs/pickup-in-store/components/container/pickup-items-details/pickup-items-details.module.ts @@ -11,6 +11,7 @@ import { RouterModule } from '@angular/router'; import { CmsConfig, ConfigModule, + FeaturesConfigModule, I18nModule, UrlModule, } from '@spartacus/core'; @@ -28,6 +29,7 @@ import { PickUpItemsDetailsComponent } from './pickup-items-details.component'; StoreModule, CardModule, MediaModule, + FeaturesConfigModule, ConfigModule.withConfig({ cmsComponents: { OrderConfirmationPickUpComponent: { From 4a3260097bac3adfc55c76abd6754d6b6a268568 Mon Sep 17 00:00:00 2001 From: Mateusz Kolasa Date: Mon, 6 Oct 2025 10:41:04 +0200 Subject: [PATCH 43/49] chore: add pickup in store lib to be built before OPF --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 61b50baec82..4677fb4eac0 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "build:epd-visualization": "npm --prefix integration-libs/epd-visualization run build:schematics && nx build epd-visualization --configuration production", "build:estimated-delivery-date": "npm --prefix feature-libs/estimated-delivery-date run build:schematics && nx build estimated-delivery-date --configuration production", "build:order": "npm --prefix feature-libs/order run build:schematics && nx build order --configuration production", - "build:libs": "ts-node ./scripts/i18n/validate-translations-json-files.ts && nx build core --configuration production && nx build storefrontlib --configuration production && concurrently --kill-others-on-fail npm:build:schematics npm:build:user && npm run build:cart && npm run build:pdf-invoices && npm run build:order && npm run build:storefinder && concurrently --kill-others-on-fail npm:build:checkout npm:build:asm npm:build:tracking npm:build:customer-ticketing npm:build:subscription-billing && concurrently --kill-others-on-fail npm:build:organization npm:build:product npm:build:product-configurator npm:build:product-multi-dimensional && concurrently --kill-others-on-fail npm:build:requested-delivery-date && concurrently --kill-others-on-fail npm:build:estimated-delivery-date && concurrently --kill-others-on-fail npm:build:smartedit npm:build:qualtrics npm:build:assets npm:build:cds npm:build:cdc npm:build:cdp npm:build:digital-payments npm:build:epd-visualization npm:build:s4om npm:build:omf npm:build:cpq-quote npm:build:segment-refs npm:build:opf npm:build:punchout npm:build:opps npm:build:pickup-in-store npm:build:quote && npm run build:setup && npm run build:s4-service", + "build:libs": "ts-node ./scripts/i18n/validate-translations-json-files.ts && nx build core --configuration production && nx build storefrontlib --configuration production && concurrently --kill-others-on-fail npm:build:schematics npm:build:user && npm run build:cart && npm run build:pdf-invoices && npm run build:order && npm run build:storefinder && concurrently --kill-others-on-fail npm:build:checkout npm:build:asm npm:build:tracking npm:build:customer-ticketing npm:build:subscription-billing && concurrently --kill-others-on-fail npm:build:organization npm:build:product npm:build:product-configurator npm:build:product-multi-dimensional && concurrently --kill-others-on-fail npm:build:requested-delivery-date && concurrently --kill-others-on-fail npm:build:estimated-delivery-date npm:build:pickup-in-store && concurrently --kill-others-on-fail npm:build:smartedit npm:build:qualtrics npm:build:assets npm:build:cds npm:build:cdc npm:build:cdp npm:build:digital-payments npm:build:epd-visualization npm:build:s4om npm:build:omf npm:build:cpq-quote npm:build:segment-refs npm:build:opf npm:build:punchout npm:build:opps npm:build:quote && npm run build:setup && npm run build:s4-service", "build:organization": "npm --prefix feature-libs/organization run build:schematics && nx build organization --configuration production", "build:pdf-invoices": "npm --prefix feature-libs/pdf-invoices run build:schematics && nx build pdf-invoices --configuration production", "build:pickup-in-store": "npm --prefix feature-libs/pickup-in-store run build:schematics && nx build pickup-in-store --configuration production", From b2bb5f60a19d9eb59597e74bf632df4d175e089d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 7 Oct 2025 06:43:36 +0000 Subject: [PATCH 44/49] Add license header --- projects/core/src/util/glob-utils.ts | 2 +- projects/schematics/src/shared/utils/html-utils.ts | 2 +- projects/schematics/src/shared/utils/load-esm-module.ts | 2 +- projects/schematics/src/shared/utils/project-tsconfig-paths.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/core/src/util/glob-utils.ts b/projects/core/src/util/glob-utils.ts index a89c758a553..76d8d026a0f 100644 --- a/projects/core/src/util/glob-utils.ts +++ b/projects/core/src/util/glob-utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2019 Google LLC. http://angular.io/license + * Copyright (C) 2010-2019 Google LLC. http://angular.io/license * SPDX-FileCopyrightText: 2025 SAP Spartacus team * * SPDX-License-Identifier: Apache-2.0 diff --git a/projects/schematics/src/shared/utils/html-utils.ts b/projects/schematics/src/shared/utils/html-utils.ts index 0b994c0f1c6..64793c708da 100644 --- a/projects/schematics/src/shared/utils/html-utils.ts +++ b/projects/schematics/src/shared/utils/html-utils.ts @@ -2,8 +2,8 @@ import { SchematicsException, Tree } from '@angular-devkit/schematics'; import { DefaultTreeAdapterMap, parse as parseHtml } from 'parse5'; /* - * Copyright Google LLC All Rights Reserved. * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * Copyright Google LLC All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/projects/schematics/src/shared/utils/load-esm-module.ts b/projects/schematics/src/shared/utils/load-esm-module.ts index d301ee67f03..74396eb5e9c 100644 --- a/projects/schematics/src/shared/utils/load-esm-module.ts +++ b/projects/schematics/src/shared/utils/load-esm-module.ts @@ -6,8 +6,8 @@ // See the Angular Schematics ticket: https://github.com/angular/angular-cli/issues/22786 /* - * Copyright Google LLC All Rights Reserved. * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * Copyright Google LLC All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/projects/schematics/src/shared/utils/project-tsconfig-paths.ts b/projects/schematics/src/shared/utils/project-tsconfig-paths.ts index 693013d88fe..d371c6bccfa 100644 --- a/projects/schematics/src/shared/utils/project-tsconfig-paths.ts +++ b/projects/schematics/src/shared/utils/project-tsconfig-paths.ts @@ -1,6 +1,6 @@ /* - * Copyright Google LLC All Rights Reserved. * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * Copyright Google LLC All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ From 04d3c28aaecbf2297ce45ed0870f46341fbd46c3 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Tue, 7 Oct 2025 13:40:11 +0530 Subject: [PATCH 45/49] addressing review comments --- feature-libs/estimated-delivery-date/public_api.ts | 1 - .../opf-b2b-checkout-payment-and-review.component.html | 1 - .../opf-b2b-checkout-review.component.html | 1 - .../opf-checkout-billing-address-form.service.spec.ts | 2 ++ projects/core/src/util/glob-utils.ts | 2 +- projects/schematics/src/shared/utils/html-utils.ts | 2 +- projects/schematics/src/shared/utils/load-esm-module.ts | 2 +- projects/schematics/src/shared/utils/project-tsconfig-paths.ts | 2 +- 8 files changed, 6 insertions(+), 7 deletions(-) diff --git a/feature-libs/estimated-delivery-date/public_api.ts b/feature-libs/estimated-delivery-date/public_api.ts index d845a5541a6..857c631da55 100644 --- a/feature-libs/estimated-delivery-date/public_api.ts +++ b/feature-libs/estimated-delivery-date/public_api.ts @@ -9,4 +9,3 @@ */ export * from './estimated-delivery-date.module'; export * from './show-estimated-delivery-date/public_api'; -export * from './assets/public_api'; diff --git a/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-payment-and-review/opf-b2b-checkout-payment-and-review.component.html b/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-payment-and-review/opf-b2b-checkout-payment-and-review.component.html index 2044a6f6770..f0ae8f8d7b9 100644 --- a/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-payment-and-review/opf-b2b-checkout-payment-and-review.component.html +++ b/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-payment-and-review/opf-b2b-checkout-payment-and-review.component.html @@ -110,6 +110,5 @@

{{ 'opfCheckout.termsAndConditions' | cxTranslate }}

diff --git a/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html b/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html index 1bb6a8a4674..d6d5b7211c0 100644 --- a/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html +++ b/integration-libs/opf/b2b-checkout/components/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html @@ -110,7 +110,6 @@

{{ 'opfCheckout.termsAndConditions' | cxTranslate }}

diff --git a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts index 1763083d5ad..9b3f118dfca 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-billing-address-form/opf-checkout-billing-address-form.service.spec.ts @@ -269,6 +269,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { expect(service.setBillingAddress).not.toHaveBeenCalled(); }); + it('should return an observable from pickupNoDefaultAddress$', () => { spyOn(mockPickupNoDefaultAddress$, 'asObservable').and.callThrough(); @@ -289,6 +290,7 @@ describe('OpfCheckoutBillingAddressFormService', () => { }); (service as any).handleNoDefaultAddress(); }); + it('should handle error when setting default billing address fails', fakeAsync(() => { spyOn(mockActiveCartFacade, 'hasDeliveryItems').and.returnValue(of(false)); spyOn(mockUserAddressService, 'getDefaultAddress').and.returnValue( diff --git a/projects/core/src/util/glob-utils.ts b/projects/core/src/util/glob-utils.ts index 76d8d026a0f..a89c758a553 100644 --- a/projects/core/src/util/glob-utils.ts +++ b/projects/core/src/util/glob-utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2019 Google LLC. http://angular.io/license + * Copyright (c) 2010-2019 Google LLC. http://angular.io/license * SPDX-FileCopyrightText: 2025 SAP Spartacus team * * SPDX-License-Identifier: Apache-2.0 diff --git a/projects/schematics/src/shared/utils/html-utils.ts b/projects/schematics/src/shared/utils/html-utils.ts index 64793c708da..0b994c0f1c6 100644 --- a/projects/schematics/src/shared/utils/html-utils.ts +++ b/projects/schematics/src/shared/utils/html-utils.ts @@ -2,8 +2,8 @@ import { SchematicsException, Tree } from '@angular-devkit/schematics'; import { DefaultTreeAdapterMap, parse as parseHtml } from 'parse5'; /* - * SPDX-FileCopyrightText: 2025 SAP Spartacus team * Copyright Google LLC All Rights Reserved. + * SPDX-FileCopyrightText: 2025 SAP Spartacus team * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/projects/schematics/src/shared/utils/load-esm-module.ts b/projects/schematics/src/shared/utils/load-esm-module.ts index 74396eb5e9c..d301ee67f03 100644 --- a/projects/schematics/src/shared/utils/load-esm-module.ts +++ b/projects/schematics/src/shared/utils/load-esm-module.ts @@ -6,8 +6,8 @@ // See the Angular Schematics ticket: https://github.com/angular/angular-cli/issues/22786 /* - * SPDX-FileCopyrightText: 2025 SAP Spartacus team * Copyright Google LLC All Rights Reserved. + * SPDX-FileCopyrightText: 2025 SAP Spartacus team * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/projects/schematics/src/shared/utils/project-tsconfig-paths.ts b/projects/schematics/src/shared/utils/project-tsconfig-paths.ts index d371c6bccfa..693013d88fe 100644 --- a/projects/schematics/src/shared/utils/project-tsconfig-paths.ts +++ b/projects/schematics/src/shared/utils/project-tsconfig-paths.ts @@ -1,6 +1,6 @@ /* - * SPDX-FileCopyrightText: 2025 SAP Spartacus team * Copyright Google LLC All Rights Reserved. + * SPDX-FileCopyrightText: 2025 SAP Spartacus team * * SPDX-License-Identifier: Apache-2.0 */ From ce897a2b5c2633b60f8c59338c3cdc90f08c2269 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 7 Oct 2025 08:10:47 +0000 Subject: [PATCH 46/49] Add license header --- projects/core/src/util/glob-utils.ts | 2 +- projects/schematics/src/shared/utils/html-utils.ts | 2 +- projects/schematics/src/shared/utils/load-esm-module.ts | 2 +- projects/schematics/src/shared/utils/project-tsconfig-paths.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/core/src/util/glob-utils.ts b/projects/core/src/util/glob-utils.ts index a89c758a553..76d8d026a0f 100644 --- a/projects/core/src/util/glob-utils.ts +++ b/projects/core/src/util/glob-utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2019 Google LLC. http://angular.io/license + * Copyright (C) 2010-2019 Google LLC. http://angular.io/license * SPDX-FileCopyrightText: 2025 SAP Spartacus team * * SPDX-License-Identifier: Apache-2.0 diff --git a/projects/schematics/src/shared/utils/html-utils.ts b/projects/schematics/src/shared/utils/html-utils.ts index 0b994c0f1c6..64793c708da 100644 --- a/projects/schematics/src/shared/utils/html-utils.ts +++ b/projects/schematics/src/shared/utils/html-utils.ts @@ -2,8 +2,8 @@ import { SchematicsException, Tree } from '@angular-devkit/schematics'; import { DefaultTreeAdapterMap, parse as parseHtml } from 'parse5'; /* - * Copyright Google LLC All Rights Reserved. * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * Copyright Google LLC All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/projects/schematics/src/shared/utils/load-esm-module.ts b/projects/schematics/src/shared/utils/load-esm-module.ts index d301ee67f03..74396eb5e9c 100644 --- a/projects/schematics/src/shared/utils/load-esm-module.ts +++ b/projects/schematics/src/shared/utils/load-esm-module.ts @@ -6,8 +6,8 @@ // See the Angular Schematics ticket: https://github.com/angular/angular-cli/issues/22786 /* - * Copyright Google LLC All Rights Reserved. * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * Copyright Google LLC All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/projects/schematics/src/shared/utils/project-tsconfig-paths.ts b/projects/schematics/src/shared/utils/project-tsconfig-paths.ts index 693013d88fe..d371c6bccfa 100644 --- a/projects/schematics/src/shared/utils/project-tsconfig-paths.ts +++ b/projects/schematics/src/shared/utils/project-tsconfig-paths.ts @@ -1,6 +1,6 @@ /* - * Copyright Google LLC All Rights Reserved. * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * Copyright Google LLC All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ From 6ea545b1c7d3dca71b473a87a9f586c7810ef673 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Wed, 8 Oct 2025 16:43:47 +0530 Subject: [PATCH 47/49] addressing review comments --- .../opf-checkout-payments.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts index 8514bd7c299..3590f2b8130 100644 --- a/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts +++ b/integration-libs/opf/checkout/components/opf-checkout-payments/opf-checkout-payments.component.spec.ts @@ -118,7 +118,7 @@ describe('OpfCheckoutPaymentsComponent', () => { of(mockOpfMetadata) ); mockBillingAddressFormService = { - paymentOptionsDisabled$: of(false), // Mock the observable + paymentOptionsDisabled$: of(false), }; await TestBed.configureTestingModule({ From c9ac70fe93aa213a575c86255699f6368a27bf8d Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Thu, 9 Oct 2025 11:50:29 +0530 Subject: [PATCH 48/49] fix dependencies error --- integration-libs/opf/package.json | 1 + projects/schematics/src/dependencies.json | 1 + projects/schematics/src/shared/utils/graph-utils_spec.ts | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/integration-libs/opf/package.json b/integration-libs/opf/package.json index e5f9e918e4c..e31a679e146 100644 --- a/integration-libs/opf/package.json +++ b/integration-libs/opf/package.json @@ -36,6 +36,7 @@ "@spartacus/checkout": "221121.2.0", "@spartacus/core": "221121.2.0", "@spartacus/order": "221121.2.0", + "@spartacus/pickup-in-store": "221121.2.0", "@spartacus/schematics": "221121.2.0", "@spartacus/storefront": "221121.2.0", "@spartacus/styles": "221121.2.0", diff --git a/projects/schematics/src/dependencies.json b/projects/schematics/src/dependencies.json index d7e79a6f3fd..453fce4bc1e 100644 --- a/projects/schematics/src/dependencies.json +++ b/projects/schematics/src/dependencies.json @@ -433,6 +433,7 @@ "@spartacus/checkout": "221121.2.0", "@spartacus/core": "221121.2.0", "@spartacus/order": "221121.2.0", + "@spartacus/pickup-in-store": "221121.2.0", "@spartacus/schematics": "221121.2.0", "@spartacus/storefront": "221121.2.0", "@spartacus/styles": "221121.2.0", diff --git a/projects/schematics/src/shared/utils/graph-utils_spec.ts b/projects/schematics/src/shared/utils/graph-utils_spec.ts index 2bceaa951c4..a0294839df9 100644 --- a/projects/schematics/src/shared/utils/graph-utils_spec.ts +++ b/projects/schematics/src/shared/utils/graph-utils_spec.ts @@ -202,6 +202,7 @@ describe('Graph utils', () => { "TMS-GTM", "PDF-Invoices", "Requested-Delivery-Date", + "Pickup-In-Store", "Customer-Ticketing", "Organization-User-Registration", "Administration", @@ -237,7 +238,6 @@ describe('Graph utils', () => { "Product-Variants", "Image-Zoom", "Bulk-Pricing", - "Pickup-In-Store", "Quote", ] `); From 673aebf40f77a262ca958f5063c9e615876e84c9 Mon Sep 17 00:00:00 2001 From: ijitendrasap Date: Thu, 9 Oct 2025 12:28:22 +0530 Subject: [PATCH 49/49] fix dependency order --- projects/schematics/src/shared/utils/graph-utils_spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/schematics/src/shared/utils/graph-utils_spec.ts b/projects/schematics/src/shared/utils/graph-utils_spec.ts index a0294839df9..2bceaa951c4 100644 --- a/projects/schematics/src/shared/utils/graph-utils_spec.ts +++ b/projects/schematics/src/shared/utils/graph-utils_spec.ts @@ -202,7 +202,6 @@ describe('Graph utils', () => { "TMS-GTM", "PDF-Invoices", "Requested-Delivery-Date", - "Pickup-In-Store", "Customer-Ticketing", "Organization-User-Registration", "Administration", @@ -238,6 +237,7 @@ describe('Graph utils', () => { "Product-Variants", "Image-Zoom", "Bulk-Pricing", + "Pickup-In-Store", "Quote", ] `);