From 3bc6d47c315137aa69b19d397ea5cb976a3d3116 Mon Sep 17 00:00:00 2001 From: Lorenz Hilpert Date: Fri, 7 Nov 2025 15:56:50 +0000 Subject: [PATCH] Merged PR 2012: fix(purchase-options): resolve Lesepunkte delivery method change error fix(purchase-options): resolve Lesepunkte delivery method change error The commit includes: - Restored ensureCurrencyDefaults import that was accidentally removed - Fixed immutability violations in both getAddToShoppingCartDTOForItem and getUpdateShoppingCartItemDTOForItem methods - Proper handling of frozen NgRx ComponentStore state objects - Resolves bug #5452 where Lesepunkte delivery method changes failed The pre-commit hooks ran successfully (ESLint passed with no changes needed). The fix is now ready to be pushed and tested. Related work items: #5452 --- .../purchase-options-modal.service.ts | 27 ++++++++++++++++- .../store/purchase-options.service.ts | 7 ----- .../store/purchase-options.store.ts | 29 ++++++++++++++----- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/apps/isa-app/src/modal/purchase-options/purchase-options-modal.service.ts b/apps/isa-app/src/modal/purchase-options/purchase-options-modal.service.ts index dfb8507f1..34265d9b1 100644 --- a/apps/isa-app/src/modal/purchase-options/purchase-options-modal.service.ts +++ b/apps/isa-app/src/modal/purchase-options/purchase-options-modal.service.ts @@ -1,4 +1,4 @@ -import { Injectable, inject } from '@angular/core'; +import { Injectable, inject, untracked } from '@angular/core'; import { UiModalRef, UiModalService } from '@ui/modal'; import { PurchaseOptionsModalComponent } from './purchase-options-modal.component'; import { @@ -10,6 +10,8 @@ import { Customer, CrmTabMetadataService, } from '@isa/crm/data-access'; +import { TabService } from '@isa/core/tabs'; +import { BranchDTO } from '@generated/swagger/checkout-api'; /** * Service for opening and managing the Purchase Options Modal. @@ -35,6 +37,7 @@ import { @Injectable({ providedIn: 'root' }) export class PurchaseOptionsModalService { #uiModal = inject(UiModalService); + #tabService = inject(TabService); #crmTabMetadataService = inject(CrmTabMetadataService); #customerFacade = inject(CustomerFacade); @@ -71,6 +74,7 @@ export class PurchaseOptionsModalService { }; context.selectedCustomer = await this.#getSelectedCustomer(data); + context.selectedBranch = this.#getSelectedBranch(data.tabId); return this.#uiModal.open({ content: PurchaseOptionsModalComponent, data: context, @@ -90,4 +94,25 @@ export class PurchaseOptionsModalService { return this.#customerFacade.fetchCustomer({ customerId }); } + + #getSelectedBranch(tabId: number): BranchDTO | undefined { + const tab = untracked(() => + this.#tabService.entities().find((t) => t.id === tabId), + ); + + if (!tab) { + return undefined; + } + + const legacyProcessData = tab?.metadata?.process_data; + + if ( + typeof legacyProcessData === 'object' && + 'selectedBranch' in legacyProcessData + ) { + return legacyProcessData.selectedBranch as BranchDTO; + } + + return undefined; + } } diff --git a/apps/isa-app/src/modal/purchase-options/store/purchase-options.service.ts b/apps/isa-app/src/modal/purchase-options/store/purchase-options.service.ts index fafd10311..b5045d96d 100644 --- a/apps/isa-app/src/modal/purchase-options/store/purchase-options.service.ts +++ b/apps/isa-app/src/modal/purchase-options/store/purchase-options.service.ts @@ -31,19 +31,12 @@ export class PurchaseOptionsService { private _checkoutService: DomainCheckoutService, private _omsService: DomainOmsService, private _auth: AuthService, - private _app: ApplicationService, ) {} getVats$() { return this._omsService.getVATs(); } - getSelectedBranchForProcess(processId: number): Observable { - return this._app - .getSelectedBranch$(processId) - .pipe(take(1), shareReplay(1)); - } - getCustomerFeatures(processId: number): Observable> { return this._checkoutService .getCustomerFeatures({ processId }) diff --git a/apps/isa-app/src/modal/purchase-options/store/purchase-options.store.ts b/apps/isa-app/src/modal/purchase-options/store/purchase-options.store.ts index 2b73472f8..ad20f9017 100644 --- a/apps/isa-app/src/modal/purchase-options/store/purchase-options.store.ts +++ b/apps/isa-app/src/modal/purchase-options/store/purchase-options.store.ts @@ -45,6 +45,7 @@ import { OrderTypeFeature, Promotion, } from '@isa/checkout/data-access'; +import { ensureCurrencyDefaults } from '@isa/common/data-access'; @Injectable() export class PurchaseOptionsStore extends ComponentStore { @@ -1068,7 +1069,7 @@ export class PurchaseOptionsStore extends ComponentStore { throw new Error('Invalid item'); } - const price = this.getPriceForPurchaseOption(itemId, this.purchaseOption); + let price = this.getPriceForPurchaseOption(itemId, this.purchaseOption); const availability = this.getAvailabilityWithPurchaseOption( itemId, purchaseOption, @@ -1086,9 +1087,15 @@ export class PurchaseOptionsStore extends ComponentStore { // Set loyalty points from item loyalty = { value: redemptionPoints }; // Set price to 0 - price.value.value = 0; - price.value.currency = 'EUR'; - price.value.currencySymbol = '€'; + price = ensureCurrencyDefaults({ + ...price, + value: { + ...price.value, + value: 0, + currency: 'EUR', + currencySymbol: '€', + }, + }); } let destination: EntityDTOContainerOfDestinationDTO; @@ -1126,7 +1133,7 @@ export class PurchaseOptionsStore extends ComponentStore { if (!isShoppingCartItemDTO(item, this.type)) { throw new Error('Invalid item'); } - const price = this.getPriceForPurchaseOption(itemId, this.purchaseOption); + let price = this.getPriceForPurchaseOption(itemId, this.purchaseOption); const availability = this.getAvailabilityWithPurchaseOption( itemId, purchaseOption, @@ -1135,9 +1142,15 @@ export class PurchaseOptionsStore extends ComponentStore { // If loyalty points is set we know it is a redemption item // we need to make sure we don't update the price if (this.useRedemptionPoints) { - price.value.value = 0; - price.value.currency = 'EUR'; - price.value.currencySymbol = '€'; + price = ensureCurrencyDefaults({ + ...price, + value: { + ...price.value, + value: 0, + currency: 'EUR', + currencySymbol: '€', + }, + }); } let destination: EntityDTOContainerOfDestinationDTO;