Merged PR 2003: 🐛 fix(purchase-options): correct popup display for e-books and downloads

🐛 fix(purchase-options): correct popup display for e-books and downloads

- Check item formats (DL/EB) instead of backend availabilities to determine download-only items
- Display 'Derzeit nicht verfügbar' warning when download items lack availability
- Prevent 'Geringer Bestand' message from showing for:
  * Download/e-book items
  * Items with zero stock
  * Items with pending in-store availability requests

Fixes #5410

Related work items: #5410
This commit is contained in:
Lorenz Hilpert
2025-11-04 16:06:05 +00:00
committed by Nino Righi
parent cc62441f58
commit a2833b669d
3 changed files with 67 additions and 15 deletions

View File

@@ -242,6 +242,14 @@
}
}
@if (showNoDownloadAvailability$ | async) {
<span
class="inline-block font-bold text-[#BE8100] mt-[14px] max-w-[19rem]"
>
Derzeit nicht verfügbar
</span>
}
@if (showMaxAvailableQuantity$ | async) {
<span class="font-bold text-[#BE8100] mt-[14px]">
{{ (availability$ | async)?.inStock }} Exemplare sofort lieferbar

View File

@@ -36,6 +36,7 @@ import { GIFT_CARD_MAX_PRICE, PRICE_PATTERN } from '../constants';
import {
Item,
PurchaseOptionsStore,
isDownload,
isItemDTO,
isShoppingCartItemDTO,
} from '../store';
@@ -222,13 +223,23 @@ export class PurchaseOptionsListItemComponent
}),
);
fetchingAvailabilities$ = this.item$
.pipe(
switchMap((item) =>
this._store.getFetchingAvailabilitiesForItem$(item.id),
),
)
.pipe(map((fetchingAvailabilities) => fetchingAvailabilities.length > 0));
fetchingAvailabilitiesArray$ = this.item$.pipe(
switchMap((item) => this._store.getFetchingAvailabilitiesForItem$(item.id)),
);
fetchingAvailabilities$ = this.fetchingAvailabilitiesArray$.pipe(
map((fetchingAvailabilities) => fetchingAvailabilities.length > 0),
);
fetchingInStoreAvailability$ = this.fetchingAvailabilitiesArray$.pipe(
map((fetchingAvailabilities) =>
fetchingAvailabilities.some((fa) => fa.purchaseOption === 'in-store'),
),
);
isFetchingInStore = toSignal(this.fetchingInStoreAvailability$, {
initialValue: false,
});
showNotAvailable$ = combineLatest([
this.availabilities$,
@@ -247,6 +258,35 @@ export class PurchaseOptionsListItemComponent
}),
);
isDownload$ = this.item$.pipe(map((item) => isDownload(item)));
isDownloadItem = toSignal(this.isDownload$, { initialValue: false });
showNoDownloadAvailability$ = combineLatest([
this.isDownload$,
this.availabilities$,
this.fetchingAvailabilities$,
]).pipe(
map(([isDownloadItem, availabilities, fetchingAvailabilities]) => {
// Only check for download items
if (!isDownloadItem) {
return false;
}
// Don't show error while loading
if (fetchingAvailabilities) {
return false;
}
// Check if download availability exists
const hasDownloadAvailability = availabilities.some(
(a) => a.purchaseOption === 'download',
);
return !hasDownloadAvailability;
}),
);
// Ticket #4813 Artikeldetailseite // EVT-Datum bei der Kaufoption Rücklage anzeigen
get isEVT() {
// Einstieg über Kaufoptionen - Hier wird die Katalogavailability verwendet die am ItemDTO hängt
@@ -279,10 +319,16 @@ export class PurchaseOptionsListItemComponent
});
showLowStockMessage = computed(() => {
const availability = this.availability();
const inStock = availability?.inStock ?? 0;
return (
this.useRedemptionPoints() &&
this.isReservePurchaseOption() &&
(!this.availability() || this.availability().inStock < 2)
!this.isDownloadItem() &&
!this.isFetchingInStore() &&
inStock > 0 &&
inStock < 2
);
});

View File

@@ -20,6 +20,7 @@ import {
PickupPurchaseOptionTileComponent,
} from './purchase-options-tile';
import {
isDownload,
isGiftCard,
Item,
PurchaseOption,
@@ -102,19 +103,16 @@ export class PurchaseOptionsModalComponent implements OnInit, OnDestroy {
purchasingOptions$ = this.store.getPurchaseOptionsInAvailabilities$;
isDownloadOnly$ = this.purchasingOptions$.pipe(
map(
(purchasingOptions) =>
purchasingOptions.length === 1 && purchasingOptions[0] === 'download',
),
isDownloadOnly$ = this.store.items$.pipe(
map((items) => items.length > 0 && items.every((item) => isDownload(item))),
);
isGiftCardOnly$ = this.store.items$.pipe(
map((items) => items.every((item) => isGiftCard(item, this.store.type))),
);
hasDownload$ = this.purchasingOptions$.pipe(
map((purchasingOptions) => purchasingOptions.includes('download')),
hasDownload$ = this.store.items$.pipe(
map((items) => items.some((item) => isDownload(item))),
);
canContinue$ = this.store.canContinue$;