Merged PR 1166: #2666 Hotfix Listenbestellung CanAddItems angepasst

#2666 Hotfix Listenbestellung CanAddItems angepasst

Related work items: #2666
This commit is contained in:
Andreas Schickinger
2022-04-05 15:12:34 +00:00
committed by Lorenz Hilpert
parent 698af2ecc3
commit 94753ceac4
10 changed files with 117 additions and 59 deletions

View File

@@ -134,10 +134,8 @@ export class PurchasingOptionsListItemComponent {
this._store.deliveryB2bAvailabilities$
),
map(([[canAdd, items], option, delivery, deliveryDig, deliveryB2b]) => {
// Initial immer alle Selects anzeigen
const selectedItem = items?.find((_) => true);
if (!selectedItem) {
return true;
if (!option) {
return false;
}
// Select immer sichtbar bei ausgewählten Items
@@ -146,27 +144,34 @@ export class PurchasingOptionsListItemComponent {
}
// Select nur anzeigen, wenn ein anderes ausgewähltes Item die gleiche Verfügbarkeit hat (B2B Versand z.B.)
if (selectedItem && option === 'delivery') {
if (delivery[selectedItem.product?.catalogProductNumber] && delivery[this.item.product?.catalogProductNumber]) {
if (items?.length > 0 && option === 'delivery' && canAdd[this.item.product.catalogProductNumber]?.status < 2) {
if (items.every((item) => delivery[item.product?.catalogProductNumber]) && delivery[this.item.product?.catalogProductNumber]) {
return true;
}
if (deliveryDig[selectedItem.product?.catalogProductNumber] && deliveryDig[this.item.product?.catalogProductNumber]) {
if (
items.every((item) => deliveryDig[item.product?.catalogProductNumber]) &&
deliveryDig[this.item.product?.catalogProductNumber]
) {
return true;
}
if (deliveryB2b[selectedItem.product?.catalogProductNumber] && deliveryB2b[this.item.product?.catalogProductNumber]) {
if (
items.every((item) => deliveryB2b[item.product?.catalogProductNumber]) &&
deliveryB2b[this.item.product?.catalogProductNumber]
) {
return true;
}
return false;
}
return canAdd && canAdd[this.item.product.catalogProductNumber] === true;
return canAdd && canAdd[this.item.product.catalogProductNumber]?.status < 2;
})
);
canAdd$ = this._store.canAdd$.pipe(
filter((canAdd) => !!this.item && !!canAdd),
map((canAdd) => canAdd[this.item.product.catalogProductNumber])
map((canAdd) => canAdd[this.item.product.catalogProductNumber]?.message)
);
quantityRange$ = combineLatest([this._store.selectedFilterOption$, this.takeAwayAvailabilities$]).pipe(

View File

@@ -6,7 +6,7 @@
<div class="items" *ngIf="shoppingCartItems$ | async; let shoppingCartItems">
<div class="item-actions">
<ng-container *ngIf="showSelectAll$ | async">
<ng-container>
<button
*ngIf="!(allShoppingCartItemsSelected$ | async); else unselectAll"
class="cta-select-all"

View File

@@ -19,6 +19,7 @@ export class PurchasingOptionsListModalComponent implements OnInit {
private _onDestroy$ = new Subject();
addItemsLoader$ = new BehaviorSubject<boolean>(false);
lastSelectedFilterOption$ = new BehaviorSubject<string>(undefined);
shoppingCartItems$ = combineLatest([
this._store.fetchingAvailabilities$,
@@ -66,14 +67,28 @@ export class PurchasingOptionsListModalComponent implements OnInit {
selectedShoppingCartItems$ = this._store.selectedShoppingCartItems$;
allShoppingCartItemsSelected$ = combineLatest([this.shoppingCartItems$, this.selectedShoppingCartItems$]).pipe(
map(([shoppingCartItems, selectedShoppingCartItems]) =>
shoppingCartItems.every((item) => selectedShoppingCartItems.find((i) => item.id === i.id))
map(
([shoppingCartItems, selectedShoppingCartItems]) =>
shoppingCartItems.every((item) => selectedShoppingCartItems.find((i) => item.id === i.id)) && shoppingCartItems?.length > 0
)
);
selectAllCtaDisabled$ = this._store.selectedFilterOption$.pipe(
canAddItems$ = this._store.canAdd$.pipe(
map((canAdd) => {
for (const key in canAdd) {
if (Object.prototype.hasOwnProperty.call(canAdd, key)) {
if (!!canAdd[key]?.message) {
return false;
}
}
}
return true;
})
);
selectAllCtaDisabled$ = combineLatest([this._store.selectedFilterOption$, this.canAddItems$]).pipe(
withLatestFrom(this.shoppingCartItems$),
map(([selectedFilterOption, items]) => !selectedFilterOption || items?.length === 0)
map(([[selectedFilterOption, canAddItems], items]) => !selectedFilterOption || items?.length === 0 || !canAddItems)
);
applyCtaDisabled$ = combineLatest([this.addItemsLoader$, this._store.selectedFilterOption$, this._store.selectedShoppingCartItems$]).pipe(
@@ -84,19 +99,6 @@ export class PurchasingOptionsListModalComponent implements OnInit {
)
);
showSelectAll$ = this._store.canAdd$.pipe(
map((canAdd) => {
for (const key in canAdd) {
if (Object.prototype.hasOwnProperty.call(canAdd, key)) {
if (canAdd[key] !== true) {
return false;
}
}
}
return true;
})
);
constructor(
private _modalRef: UiModalRef<any, PurchasingOptionsListModalData>,
private _modal: UiModalService,
@@ -120,14 +122,19 @@ export class PurchasingOptionsListModalComponent implements OnInit {
if (!!option && items?.length > 0) {
this._store.checkCanAddItems(items);
} else {
this._store.patchState({ canAdd: {} });
}
});
this.showSelectAll$
this.canAddItems$
.pipe(takeUntil(this._onDestroy$), withLatestFrom(this.shoppingCartItems$, this._store.selectedFilterOption$))
.subscribe(([showSelectAll, items, option]) => {
if (items?.length > 0) {
if (items?.length > 0 && this.lastSelectedFilterOption$.value !== option) {
this.selectAll(items, showSelectAll && !!option);
// Nach dem Übernehmen von Items wird eine neue CanAdd Abfrage ausgeführt, in diesem Fall soll aber nicht alles ausgewählt werden
this.lastSelectedFilterOption$.next(option);
}
});
}
@@ -234,5 +241,10 @@ export class PurchasingOptionsListModalComponent implements OnInit {
} finally {
this.addItemsLoader$.next(false);
}
const shoppingCartItems = await this.shoppingCartItems$.pipe(first()).toPromise();
if (shoppingCartItems?.length > 0) {
this._store.checkCanAddItems(shoppingCartItems);
}
}
}

View File

@@ -16,7 +16,7 @@ interface PurchasingOptionsListModalState {
deliveryB2bAvailabilities: { [key: string]: AvailabilityDTO | true };
deliveryDigAvailabilities: { [key: string]: AvailabilityDTO | true };
customerFeatures: { [key: string]: string };
canAdd: { [key: string]: true | string };
canAdd: { [key: string]: { message: string; status: number } };
selectedShoppingCartItems: ShoppingCartItemDTO[];
branches: BranchDTO[];
currentBranch: BranchDTO;
@@ -57,7 +57,7 @@ export class PurchasingOptionsListModalStore extends ComponentStore<PurchasingOp
selectedFilterOption$ = this.select((s) => s.selectedFilterOption);
set selectedFilterOption(selectedFilterOption: string) {
this.patchState({ selectedFilterOption, canAdd: {} });
this.patchState({ selectedFilterOption });
}
get selectedFilterOption() {
@@ -472,12 +472,23 @@ export class PurchasingOptionsListModalStore extends ComponentStore<PurchasingOp
return this._checkoutService.canAddItems({ processId, payload, orderType }).pipe(
tapResponse(
(result: any) => {
const canAdd = {};
result?.forEach((r) => {
this.setCanAdd({ itemId: r.id, canAddItem: r.ok || r.message });
canAdd[r.id] = { message: r.message, status: r.status };
});
this.patchState({ canAdd });
},
(error: Error) =>
items?.forEach((item) => this.setCanAdd({ itemId: item.product.catalogProductNumber, canAddItem: error?.message }))
(error: Error) => {
const canAdd = {};
items?.forEach((i) => {
canAdd[i.product?.catalogProductNumber] = { message: error?.message };
});
this.patchState({ canAdd });
}
)
);
})
@@ -501,13 +512,6 @@ export class PurchasingOptionsListModalStore extends ComponentStore<PurchasingOp
};
}
readonly setCanAdd = this.updater((state, data: { itemId: number; canAddItem: true | string }) => {
const canAdd = { ...state.canAdd };
canAdd[data.itemId] = data.canAddItem;
return { ...state, canAdd };
});
readonly updateItemQuantity = this.updater((state, value: { itemId: number; quantity: number }) => {
const itemToUpdate = state.shoppingCartItems.find((item) => item.id === value.itemId);
const otherItems = state.shoppingCartItems.filter((item) => item.id !== value.itemId);

View File

@@ -432,19 +432,15 @@ export class PurchasingOptionsModalStore extends ComponentStore<PurchasingOption
withLatestFrom(this.selectOlaAvailability, this.selectProcessId, this.selectOrderType),
switchMap(([_, availability, processId, orderType]) => {
this.patchState({ checkingCanAdd: true });
return this.checkoutService
.canAddItem({
processId,
availability,
orderType,
})
.pipe(
tapResponse(
(canAdd) => this.setCanAdd(canAdd),
(error: Error) => this.setCanAdd(error?.message)
),
tap((_) => this.patchState({ checkingCanAdd: false }))
);
return this.checkoutService.canAddItems({ processId, payload: [{ availabilities: [availability] }], orderType }).pipe(
tapResponse(
(response: any) => {
this.setCanAdd(response?.find((_) => true)?.status === 0 ? true : response?.find((_) => true)?.message);
},
(error: Error) => this.setCanAdd(error?.message)
),
tap((_) => this.patchState({ checkingCanAdd: false }))
);
})
)
);

View File

@@ -15,6 +15,9 @@ export { KeyValueDTOOfStringAndString } from './models/key-value-dtoof-string-an
export { IPublicUserInfo } from './models/ipublic-user-info';
export { ProblemDetails } from './models/problem-details';
export { ItemPayload } from './models/item-payload';
export { ResponseArgsOfItemsResult } from './models/response-args-of-items-result';
export { ItemsResult } from './models/items-result';
export { ItemsResultStatus } from './models/items-result-status';
export { ResponseArgsOfBuyerResult } from './models/response-args-of-buyer-result';
export { BuyerResult } from './models/buyer-result';
export { QueryTokenDTO } from './models/query-token-dto';

View File

@@ -0,0 +1,2 @@
/* tslint:disable */
export type ItemsResultStatus = 0 | 1 | 2 | 4;

View File

@@ -0,0 +1,29 @@
/* tslint:disable */
import { OLAAvailabilityDTO } from './olaavailability-dto';
import { ItemsResultStatus } from './items-result-status';
/**
* Output
*/
export interface ItemsResult {
/**
* Artikelverfügbarkeit
*/
availability?: OLAAvailabilityDTO;
/**
* Id
*/
id?: string;
/**
* Nachricht
*/
message?: string;
/**
* Can Add
*/
status: ItemsResultStatus;
}

View File

@@ -0,0 +1,6 @@
/* tslint:disable */
import { ResponseArgs } from './response-args';
import { ItemsResult } from './items-result';
export interface ResponseArgsOfItemsResult extends ResponseArgs{
result?: ItemsResult;
}

View File

@@ -9,6 +9,7 @@ import { map as __map, filter as __filter } from 'rxjs/operators';
import { ResponseArgsOfItemResult } from '../models/response-args-of-item-result';
import { ItemPayload } from '../models/item-payload';
import { ResponseArgsOfItemsResult } from '../models/response-args-of-items-result';
import { ResponseArgsOfBuyerResult } from '../models/response-args-of-buyer-result';
import { BuyerPayload } from '../models/buyer-payload';
import { ResponseArgsOfDestinationResult } from '../models/response-args-of-destination-result';
@@ -167,7 +168,7 @@ class StoreCheckoutService extends __BaseService {
*
* - `locale`: Lokalisierung
*/
StoreCheckoutCanAddItemsResponse(params: StoreCheckoutService.StoreCheckoutCanAddItemsParams): __Observable<__StrictHttpResponse<ResponseArgsOfItemResult>> {
StoreCheckoutCanAddItemsResponse(params: StoreCheckoutService.StoreCheckoutCanAddItemsParams): __Observable<__StrictHttpResponse<ResponseArgsOfItemsResult>> {
let __params = this.newParams();
let __headers = new HttpHeaders();
let __body: any = null;
@@ -187,7 +188,7 @@ class StoreCheckoutService extends __BaseService {
return this.http.request<any>(req).pipe(
__filter(_r => _r instanceof HttpResponse),
__map((_r) => {
return _r as __StrictHttpResponse<ResponseArgsOfItemResult>;
return _r as __StrictHttpResponse<ResponseArgsOfItemsResult>;
})
);
}
@@ -201,9 +202,9 @@ class StoreCheckoutService extends __BaseService {
*
* - `locale`: Lokalisierung
*/
StoreCheckoutCanAddItems(params: StoreCheckoutService.StoreCheckoutCanAddItemsParams): __Observable<ResponseArgsOfItemResult> {
StoreCheckoutCanAddItems(params: StoreCheckoutService.StoreCheckoutCanAddItemsParams): __Observable<ResponseArgsOfItemsResult> {
return this.StoreCheckoutCanAddItemsResponse(params).pipe(
__map(_r => _r.body as ResponseArgsOfItemResult)
__map(_r => _r.body as ResponseArgsOfItemsResult)
);
}