#4185 OLA Warenkorb - 500 Fix

This commit is contained in:
Lorenz Hilpert
2023-08-22 13:47:22 +02:00
parent 0626538aea
commit 771816f3af
4 changed files with 62 additions and 46 deletions

View File

@@ -37,7 +37,7 @@ import {
ResponseArgsOfValueTupleOfIEnumerableOfDisplayOrderDTOAndIEnumerableOfKeyValueDTOOfStringAndString,
} from '@swagger/oms';
import { isNullOrUndefined, memorize } from '@utils/common';
import { combineLatest, Observable, of, concat, isObservable, throwError, interval, zip, EMPTY } from 'rxjs';
import { combineLatest, Observable, of, concat, isObservable, throwError, interval, zip, EMPTY, Subscription } from 'rxjs';
import {
bufferCount,
catchError,
@@ -50,6 +50,7 @@ import {
share,
shareReplay,
switchMap,
take,
tap,
withLatestFrom,
} from 'rxjs/operators';
@@ -694,39 +695,56 @@ export class DomainCheckoutService {
return availability;
}
/**
* Check if the availability of all items is valid
* @param param0 Process Id
* @returns true if the availability of all items is valid
*/
validateOlaStatus({ processId }: { processId: number }): Observable<boolean> {
const enity$ = this.store.select(DomainCheckoutSelectors.selectCheckoutEntityByProcessId, { processId });
return combineLatest([enity$, interval(250)]).pipe(
mergeMap(([entity]) => {
if (!entity || !entity.shoppingCart || !entity.shoppingCart.items) {
return EMPTY;
}
return new Observable((observer) => {
const enity$ = this.store.select(DomainCheckoutSelectors.selectCheckoutEntityByProcessId, { processId });
const availabilityHistory = entity.availabilityHistory ?? [];
const shoppingCart = entity.shoppingCart;
const olaExpiration = this.olaExpiration;
const now = Date.now();
const exp = this.olaExpiration;
let timeout: any;
for (const item of shoppingCart.items.map((i) => i.data)) {
const latestAvailability = availabilityHistory
.filter((h) => h.shoppingCartItemId === item.id && h.type === item.features.orderType)
.reduce(
(prev, curr) => {
return prev.timestamp > curr.timestamp ? prev : curr;
},
{ timestamp: 0 }
);
let subscription: Subscription;
if (latestAvailability.timestamp + exp < now) {
return of(false);
function check() {
const exp = Date.now() - olaExpiration;
subscription?.unsubscribe();
subscription = enity$.pipe(take(1)).subscribe((entity) => {
if (!entity || !entity.shoppingCart || !entity.shoppingCart.items) {
return;
}
}
return of(true);
}),
distinctUntilChanged(isEqual)
);
const itemAvailabilityTimestamp = entity.itemAvailabilityTimestamp ?? {};
const shoppingCart = entity.shoppingCart;
const timestamps = shoppingCart.items
?.map((i) => i.data)
?.filter((item) => !!item?.features?.orderType)
?.map((item) => itemAvailabilityTimestamp[`${item.id}_${item.features.orderType}`]);
if (timestamps?.length > 0) {
const oldestTimestamp = Math.min(...timestamps);
observer.next(exp < oldestTimestamp);
}
timeout = setTimeout(() => {
check.call(this);
}, olaExpiration);
});
}
check.call(this);
return () => {
subscription?.unsubscribe();
clearTimeout(timeout);
};
});
}
validateAvailabilities({ processId }: { processId: number }): Observable<boolean> {

View File

@@ -22,5 +22,5 @@ export interface CheckoutEntity {
specialComment: string;
notificationChannels: NotificationChannel;
olaErrorIds: number[];
availabilityHistory: Array<{ shoppingCartItemId: number; availability: AvailabilityDTO; timestamp: number; type: string }>;
itemAvailabilityTimestamp: Record<string, number>;
}

View File

@@ -16,18 +16,14 @@ const _domainCheckoutReducer = createReducer(
entity.shoppingCart = shoppingCart;
for (let shoppingCartItem of addedShoppingCartItems) {
if (!shoppingCartItem.features?.orderType) continue;
entity.itemAvailabilityTimestamp = entity.itemAvailabilityTimestamp ?? {};
entity.availabilityHistory = [
...(entity?.availabilityHistory ?? []),
{
availability: shoppingCartItem.availability,
shoppingCartItemId: shoppingCartItem.id,
timestamp: Date.now(),
type: shoppingCartItem.features.orderType,
},
];
const now = Date.now();
for (let shoppingCartItem of addedShoppingCartItems) {
if (shoppingCartItem.features?.orderType) {
entity.itemAvailabilityTimestamp[`${shoppingCartItem.id}_${shoppingCartItem.features.orderType}`] = now;
}
}
return storeCheckoutAdapter.setOne(entity, s);
@@ -123,15 +119,15 @@ const _domainCheckoutReducer = createReducer(
on(DomainCheckoutActions.addShoppingCartItemAvailabilityToHistory, (s, { processId, shoppingCartItemId, availability }) => {
const entity = getOrCreateCheckoutEntity({ processId, entities: s.entities });
const availabilityHistory = entity?.availabilityHistory ? [...entity?.availabilityHistory] : [];
const itemAvailabilityTimestamp = entity?.itemAvailabilityTimestamp ? { ...entity?.itemAvailabilityTimestamp } : {};
const item = entity?.shoppingCart?.items?.find((i) => i.id === shoppingCartItemId)?.data;
if (!item?.features?.orderType) return s;
availabilityHistory.push({ availability, shoppingCartItemId, timestamp: Date.now(), type: item.features.orderType });
itemAvailabilityTimestamp[`${item.id}_${item?.features?.orderType}`] = Date.now();
entity.availabilityHistory = availabilityHistory;
entity.itemAvailabilityTimestamp = itemAvailabilityTimestamp;
return storeCheckoutAdapter.setOne(entity, s);
}),
@@ -140,15 +136,15 @@ const _domainCheckoutReducer = createReducer(
(s, { shoppingCartId, shoppingCartItemId, availability }) => {
const entity = getCheckoutEntityByShoppingCartId({ shoppingCartId, entities: s.entities });
const availabilityHistory = entity?.availabilityHistory ? [...entity?.availabilityHistory] : [];
const itemAvailabilityTimestamp = entity?.itemAvailabilityTimestamp ? { ...entity?.itemAvailabilityTimestamp } : {};
const item = entity?.shoppingCart?.items?.find((i) => i.id === shoppingCartItemId)?.data;
if (!item?.features?.orderType) return s;
availabilityHistory.push({ availability, shoppingCartItemId, timestamp: Date.now(), type: item.features.orderType });
itemAvailabilityTimestamp[`${item.id}_${item?.features?.orderType}`] = Date.now();
entity.availabilityHistory = availabilityHistory;
entity.itemAvailabilityTimestamp = itemAvailabilityTimestamp;
return storeCheckoutAdapter.setOne(entity, s);
}
@@ -175,7 +171,8 @@ function getOrCreateCheckoutEntity({ entities, processId }: { entities: Dictiona
notificationChannels: 0,
olaErrorIds: [],
customer: undefined,
availabilityHistory: [],
// availabilityHistory: [],
itemAvailabilityTimestamp: {},
};
}

View File

@@ -232,6 +232,7 @@ export class CheckoutReviewComponent implements OnInit, OnDestroy {
this.checkingOla$.next(true);
for (let itemComp of this._shoppingCartItems.toArray()) {
await itemComp.refreshAvailability();
await new Promise((resolve) => setTimeout(resolve, 500));
}
this.checkingOla$.next(false);
}