mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
#4269 Preis wird nicht von Shipping AVA übernommen
This commit is contained in:
@@ -155,7 +155,6 @@ export class DomainAvailabilityService {
|
||||
quantity: number;
|
||||
branch?: BranchDTO;
|
||||
}): Observable<AvailabilityDTO> {
|
||||
console.log('getTakeAwayAvailability', item, quantity, branch);
|
||||
const request = !!branch ? this.getStockByBranch(branch.id) : this.getDefaultStock();
|
||||
return request.pipe(
|
||||
switchMap((s) =>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { AfterContentInit, ChangeDetectionStrategy, Component, ElementRef, Renderer2 } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-scale-content, [sharedScaleContent]',
|
||||
template: '<ng-content></ng-content>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
styles: [
|
||||
`
|
||||
:host {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
`,
|
||||
],
|
||||
})
|
||||
export class ScaleContentComponent implements AfterContentInit {
|
||||
// TODO: Bessere Lösung finden? Falls keine bessere Lösung gefunden wird, dann muss die Komponente auslagen
|
||||
|
||||
fontSizeInEm = 1;
|
||||
|
||||
adjustmentSteps = 0.05;
|
||||
|
||||
constructor(private _elementRef: ElementRef<HTMLElement>, private _renderer: Renderer2) {}
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
this.adjustFontSize();
|
||||
}
|
||||
|
||||
adjustFontSize() {
|
||||
const element = this._elementRef.nativeElement;
|
||||
|
||||
const clientRect = element?.getClientRects();
|
||||
const scrollHeight = element?.scrollHeight;
|
||||
|
||||
const domRect = clientRect && clientRect[0];
|
||||
|
||||
if (domRect && Math.ceil(domRect?.height) < scrollHeight) {
|
||||
this.fontSizeInEm -= this.adjustmentSteps;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
this._renderer.setStyle(element, 'font-size', `${this.fontSizeInEm}em`);
|
||||
|
||||
setTimeout(() => this.adjustFontSize(), 1);
|
||||
}
|
||||
}
|
||||
1
apps/shared/components/scale-content/src/public-api.ts
Normal file
1
apps/shared/components/scale-content/src/public-api.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './lib/scale-content.component';
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="shared-purchase-options-list-item__contributors font-bold">
|
||||
{{ product?.contributors }}
|
||||
</div>
|
||||
<div class="shared-purchase-options-list-item__name font-bold h-12" scaleContent>
|
||||
<div class="shared-purchase-options-list-item__name font-bold h-12" sharedScaleContent>
|
||||
{{ product?.name }}
|
||||
</div>
|
||||
<div class="shared-purchase-options-list-item__format flex flex-row items-center">
|
||||
@@ -82,67 +82,40 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="shared-purchase-options-list-item__price text-right ml-4 flex flex-col items-end">
|
||||
<div
|
||||
class="shared-purchase-options-list-item__price-value font-bold text-xl flex flex-row items-center"
|
||||
*ngIf="!(canEditPrice$ | async)"
|
||||
>
|
||||
<div class="shared-purchase-options-list-item__price-value font-bold text-xl flex flex-row items-center">
|
||||
<ui-svg-icon class="mr-3" [uiOverlayTrigger]="tooltip" icon="mat-info" *ngIf="priceMaintained$ | async"></ui-svg-icon>
|
||||
<ui-tooltip #tooltip yPosition="above" xPosition="after" [yOffset]="-8" [xOffset]="5" [closeable]="true">
|
||||
Günstigerer Preis aus Hugendubel Katalog wird übernommen
|
||||
</ui-tooltip>
|
||||
<ng-container *ngIf="!(setManualPrice$ | async); else setManualPrice">
|
||||
{{ priceValue$ | async | currency: 'EUR':'code' }}
|
||||
</ng-container>
|
||||
<ng-template #setManualPrice>
|
||||
<div class="relative flex flex-row items-start manual-price">
|
||||
<ui-select
|
||||
class="w-[6.5rem] min-h-[3.4375rem] p-4 rounded-card border border-solid border-[#AEB7C1] mr-4"
|
||||
tabindex="-1"
|
||||
[formControl]="manualVatFormControl"
|
||||
[defaultLabel]="'MwSt'"
|
||||
>
|
||||
<ui-select-option *ngFor="let vat of vats$ | async" [label]="vat.name + '%'" [value]="vat.vatType"></ui-select-option>
|
||||
</ui-select>
|
||||
|
||||
<shared-input-control [class.ml-8]="manualPriceFormControl?.invalid && manualPriceFormControl?.dirty">
|
||||
<shared-input-control-indicator>
|
||||
<ui-svg-icon *ngIf="manualPriceFormControl?.invalid && manualPriceFormControl?.dirty" icon="mat-info"></ui-svg-icon>
|
||||
</shared-input-control-indicator>
|
||||
<input
|
||||
triggerOn="init"
|
||||
#quantityInput
|
||||
sharedInputControlInput
|
||||
type="string"
|
||||
class="w-24"
|
||||
[formControl]="manualPriceFormControl"
|
||||
placeholder="00,00"
|
||||
(sharedOnInit)="quantityInput.focus()"
|
||||
sharedNumberValue
|
||||
/>
|
||||
<shared-input-control-suffix>EUR</shared-input-control-suffix>
|
||||
<shared-input-control-error error="required">Preis ist ungültig</shared-input-control-error>
|
||||
<shared-input-control-error error="pattern">Preis ist ungültig</shared-input-control-error>
|
||||
<shared-input-control-error error="max">Preis ist ungültig</shared-input-control-error>
|
||||
</shared-input-control>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="shared-purchase-options-list-item__price-value font-bold text-xl" *ngIf="canEditPrice$ | async">
|
||||
<div class="relative flex flex-col">
|
||||
<shared-input-control>
|
||||
<div class="relative flex flex-row justify-end items-start">
|
||||
<ui-select
|
||||
*ngIf="canEditVat$ | async"
|
||||
class="w-[6.5rem] min-h-[3.4375rem] p-4 rounded-card border border-solid border-[#AEB7C1] mr-4"
|
||||
tabindex="-1"
|
||||
[formControl]="manualVatFormControl"
|
||||
[defaultLabel]="'MwSt'"
|
||||
>
|
||||
<ui-select-option *ngFor="let vat of vats$ | async" [label]="vat.name + '%'" [value]="vat.vatType"></ui-select-option>
|
||||
</ui-select>
|
||||
<shared-input-control
|
||||
[class.ml-6]="priceFormControl?.invalid && priceFormControl?.dirty"
|
||||
*ngIf="canEditPrice$ | async; else priceTmpl"
|
||||
>
|
||||
<shared-input-control-indicator>
|
||||
<ui-svg-icon *ngIf="priceFormControl?.invalid && priceFormControl?.dirty" icon="mat-info"></ui-svg-icon>
|
||||
</shared-input-control-indicator>
|
||||
<input
|
||||
[uiOverlayTrigger]="tooltip"
|
||||
triggerOn="init"
|
||||
[uiOverlayTrigger]="giftCardTooltip"
|
||||
triggerOn="none"
|
||||
#quantityInput
|
||||
#priceOverlayTrigger="uiOverlayTrigger"
|
||||
sharedInputControlInput
|
||||
type="string"
|
||||
class="w-24"
|
||||
[formControl]="priceFormControl"
|
||||
placeholder="00,00"
|
||||
(sharedOnInit)="quantityInput.focus()"
|
||||
(sharedOnInit)="onPriceInputInit(quantityInput, priceOverlayTrigger)"
|
||||
sharedNumberValue
|
||||
/>
|
||||
<shared-input-control-suffix>EUR</shared-input-control-suffix>
|
||||
@@ -152,11 +125,14 @@
|
||||
<shared-input-control-error error="max">Preis ist ungültig</shared-input-control-error>
|
||||
</shared-input-control>
|
||||
|
||||
<ui-tooltip [warning]="true" xPosition="after" yPosition="below" [xOffset]="-55" [yOffset]="18" [closeable]="true" #tooltip>
|
||||
<ui-tooltip [warning]="true" xPosition="after" yPosition="below" [xOffset]="-55" [yOffset]="18" [closeable]="true" #giftCardTooltip>
|
||||
Tragen Sie hier den <br />
|
||||
Gutscheinbetrag ein.
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
<ng-template #priceTmpl>
|
||||
{{ priceValue$ | async | currency: 'EUR':'code' }}
|
||||
</ng-template>
|
||||
</div>
|
||||
<ui-quantity-dropdown class="mt-2" [formControl]="quantityFormControl" [range]="maxSelectableQuantity$ | async"> </ui-quantity-dropdown>
|
||||
<div class="pt-7">
|
||||
|
||||
@@ -1,78 +1,22 @@
|
||||
import { CommonModule, NgIf } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
ChangeDetectionStrategy,
|
||||
Input,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
OnChanges,
|
||||
SimpleChanges,
|
||||
AfterContentInit,
|
||||
ElementRef,
|
||||
Renderer2,
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, ChangeDetectionStrategy, Input, OnInit, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { ProductImageModule } from '@cdn/product-image';
|
||||
import { InputControlModule } from '@shared/components/input-control';
|
||||
import { ElementLifecycleModule } from '@shared/directives/element-lifecycle';
|
||||
import { UiCommonModule } from '@ui/common';
|
||||
import { UiCommonModule, UiOverlayTriggerDirective } from '@ui/common';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { UiQuantityDropdownModule } from '@ui/quantity-dropdown';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { UiTooltipModule } from '@ui/tooltip';
|
||||
import { combineLatest, ReplaySubject, Subscription } from 'rxjs';
|
||||
import { map, take, shareReplay, startWith, switchMap, withLatestFrom, last } from 'rxjs/operators';
|
||||
import { map, take, shareReplay, startWith, switchMap, withLatestFrom, last, tap } from 'rxjs/operators';
|
||||
import { GIFT_CARD_MAX_PRICE, PRICE_PATTERN } from '../constants';
|
||||
import { Item, PurchaseOptionsStore } from '../store';
|
||||
import { OrderDeadlinePipeModule } from '@shared/pipes/order-deadline';
|
||||
import { UiSelectModule } from '@ui/select';
|
||||
import { KeyValueDTOOfStringAndString } from '@swagger/cat';
|
||||
|
||||
@Component({
|
||||
selector: 'scale-content, [scaleContent]',
|
||||
template: '<ng-content></ng-content>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
styles: [
|
||||
`
|
||||
:host {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
`,
|
||||
],
|
||||
})
|
||||
export class ScaleContentComponent implements AfterContentInit {
|
||||
// TODO: Bessere Lösung finden? Falls keine bessere Lösung gefunden wird, dann muss die Komponente auslagen
|
||||
|
||||
fontSizeInEm = 1;
|
||||
|
||||
adjustmentSteps = 0.05;
|
||||
|
||||
constructor(private _elementRef: ElementRef<HTMLElement>, private _renderer: Renderer2) {}
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
this.adjustFontSize();
|
||||
}
|
||||
|
||||
adjustFontSize() {
|
||||
const element = this._elementRef.nativeElement;
|
||||
|
||||
const clientRect = element?.getClientRects();
|
||||
const scrollHeight = element?.scrollHeight;
|
||||
|
||||
const domRect = clientRect && clientRect[0];
|
||||
|
||||
if (domRect && Math.ceil(domRect?.height) < scrollHeight) {
|
||||
this.fontSizeInEm -= this.adjustmentSteps;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
this._renderer.setStyle(element, 'font-size', `${this.fontSizeInEm}em`);
|
||||
|
||||
setTimeout(() => this.adjustFontSize(), 1);
|
||||
}
|
||||
}
|
||||
import { ScaleContentComponent } from '@shared/components/scale-content';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-purchase-options-list-item',
|
||||
@@ -115,14 +59,22 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
|
||||
quantityFormControl = new FormControl<number>(null);
|
||||
|
||||
priceFormControl = new FormControl<string>(null, [
|
||||
private readonly _giftCardValidators = [
|
||||
Validators.required,
|
||||
Validators.min(1),
|
||||
Validators.max(GIFT_CARD_MAX_PRICE),
|
||||
Validators.pattern(PRICE_PATTERN),
|
||||
]);
|
||||
];
|
||||
|
||||
private readonly _defaultValidators = [
|
||||
Validators.required,
|
||||
Validators.min(0.01),
|
||||
Validators.max(999.99),
|
||||
Validators.pattern(PRICE_PATTERN),
|
||||
];
|
||||
|
||||
priceFormControl = new FormControl<string>(null);
|
||||
|
||||
manualPriceFormControl = new FormControl<string>(null, [Validators.required, Validators.max(999.99), Validators.pattern(PRICE_PATTERN)]);
|
||||
manualVatFormControl = new FormControl<string>('', [Validators.required]);
|
||||
|
||||
selectedFormControl = new FormControl<boolean>(false);
|
||||
@@ -158,10 +110,20 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
})
|
||||
);
|
||||
|
||||
canEditPrice$ = this.item$.pipe(switchMap((item) => this._store.getCanEditPrice$(item.id)));
|
||||
|
||||
canAddResult$ = this.item$.pipe(switchMap((item) => this._store.getCanAddResultForItemAndCurrentPurchaseOption$(item.id)));
|
||||
|
||||
canEditPrice$ = this.item$.pipe(
|
||||
switchMap((item) => combineLatest([this.canAddResult$, this._store.getCanEditPrice$(item.id)])),
|
||||
map(([canAddResult, canEditPrice]) => canAddResult?.canAdd && canEditPrice)
|
||||
);
|
||||
|
||||
canEditVat$ = this.item$.pipe(
|
||||
switchMap((item) => combineLatest([this.canAddResult$, this._store.getCanEditVat$(item.id)])),
|
||||
map(([canAddResult, canEditVat]) => canAddResult?.canAdd && canEditVat)
|
||||
);
|
||||
|
||||
isGiftCard$ = this.item$.pipe(switchMap((item) => this._store.getIsGiftCard$(item.id)));
|
||||
|
||||
maxSelectableQuantity$ = combineLatest([this._store.purchaseOption$, this.availability$]).pipe(
|
||||
map(([purchaseOption, availability]) => {
|
||||
if (purchaseOption === 'in-store') {
|
||||
@@ -203,6 +165,14 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
|
||||
constructor(private _store: PurchaseOptionsStore) {}
|
||||
|
||||
onPriceInputInit(target: HTMLElement, overlayTrigger: UiOverlayTriggerDirective) {
|
||||
if (this._store.getIsGiftCard(this.item.id)) {
|
||||
overlayTrigger.open();
|
||||
}
|
||||
|
||||
target?.focus();
|
||||
}
|
||||
|
||||
// Wichtig für das korrekte Setzen des Preises an das Item für den Endpoint request
|
||||
parsePrice(value: string) {
|
||||
if (PRICE_PATTERN.test(value)) {
|
||||
@@ -223,10 +193,11 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.initPriceValidatorSubscription();
|
||||
this.initQuantitySubscription();
|
||||
this.initPriceSubscription();
|
||||
this.initVatSubscription();
|
||||
this.initSelectedSubscription();
|
||||
this.initManualPriceSubscriptions();
|
||||
}
|
||||
|
||||
ngOnChanges({ item }: SimpleChanges) {
|
||||
@@ -240,14 +211,16 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
this._subscriptions.unsubscribe();
|
||||
}
|
||||
|
||||
// Ticket #4074 analog zu Ticket #2244
|
||||
// Logik gilt ausschließlich für Archivartikel und über die Kaufoptionen. Nicht über den Warenkorb
|
||||
async initManualPriceSubscriptions() {
|
||||
const isManualPrice = await this.setManualPrice$.pipe(last()).toPromise();
|
||||
if (!!isManualPrice) {
|
||||
this.initManualPriceSubscription();
|
||||
this.initManualVatSubscription();
|
||||
}
|
||||
initPriceValidatorSubscription() {
|
||||
const sub = this.item$.pipe(switchMap((item) => this._store.getIsGiftCard$(item.id))).subscribe((isGiftCard) => {
|
||||
if (isGiftCard) {
|
||||
this.priceFormControl.setValidators(this._giftCardValidators);
|
||||
} else {
|
||||
this.priceFormControl.setValidators(this._defaultValidators);
|
||||
}
|
||||
});
|
||||
|
||||
this._subscriptions.add(sub);
|
||||
}
|
||||
|
||||
initQuantitySubscription() {
|
||||
@@ -277,7 +250,6 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
if (priceStr === '') return;
|
||||
|
||||
if (this.parsePrice(this.priceFormControl.value) !== price?.value?.value) {
|
||||
debugger;
|
||||
this.priceFormControl.setValue(priceStr);
|
||||
}
|
||||
});
|
||||
@@ -303,34 +275,7 @@ export class PurchaseOptionsListItemComponent implements OnInit, OnDestroy, OnCh
|
||||
this._subscriptions.add(valueChangesSub);
|
||||
}
|
||||
|
||||
initManualPriceSubscription() {
|
||||
const sub = this.price$.subscribe((price) => {
|
||||
const priceStr = this.stringifyPrice(price?.value?.value);
|
||||
if (priceStr === '') return;
|
||||
|
||||
if (this.parsePrice(this.manualPriceFormControl.value) !== price?.value?.value) {
|
||||
this.manualPriceFormControl.setValue(priceStr);
|
||||
}
|
||||
});
|
||||
|
||||
const valueChangesSub = this.manualPriceFormControl.valueChanges.subscribe((value) => {
|
||||
const price = this._store.getPrice(this.item.id);
|
||||
const parsedPrice = this.parsePrice(value);
|
||||
|
||||
if (!parsedPrice) {
|
||||
this._store.setPrice(this.item.id, null, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (price?.value?.value !== parsedPrice) {
|
||||
this._store.setPrice(this.item.id, this.parsePrice(value), true);
|
||||
}
|
||||
});
|
||||
this._subscriptions.add(sub);
|
||||
this._subscriptions.add(valueChangesSub);
|
||||
}
|
||||
|
||||
initManualVatSubscription() {
|
||||
initVatSubscription() {
|
||||
const valueChangesSub = this.manualVatFormControl.valueChanges.pipe(withLatestFrom(this.vats$)).subscribe(([formVatType, vats]) => {
|
||||
const price = this._store.getPrice(this.item.id);
|
||||
|
||||
|
||||
@@ -25,18 +25,13 @@
|
||||
</div>
|
||||
<div class="text-center -mx-4 border-t border-gray-200 p-4 border-solid">
|
||||
<ng-container *ngIf="type === 'add'">
|
||||
<button
|
||||
type="button"
|
||||
class="isa-cta-button"
|
||||
[disabled]="!(canContinue$ | async) || saving || !(hasPrice$ | async)"
|
||||
(click)="save('continue-shopping')"
|
||||
>
|
||||
<button type="button" class="isa-cta-button" [disabled]="!(canContinue$ | async) || saving" (click)="save('continue-shopping')">
|
||||
Weiter einkaufen
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-4 isa-cta-button isa-button-primary"
|
||||
[disabled]="!(canContinue$ | async) || saving || !(hasPrice$ | async)"
|
||||
[disabled]="!(canContinue$ | async) || saving"
|
||||
(click)="save('continue')"
|
||||
>
|
||||
Fortfahren
|
||||
@@ -46,7 +41,7 @@
|
||||
<button
|
||||
type="button"
|
||||
class="ml-4 isa-cta-button isa-button-primary"
|
||||
[disabled]="!(canContinue$ | async) || saving || !(hasPrice$ | async)"
|
||||
[disabled]="!(canContinue$ | async) || saving"
|
||||
(click)="save('continue')"
|
||||
>
|
||||
Fortfahren
|
||||
|
||||
@@ -83,7 +83,7 @@ export class PurchaseOptionsModalComponent implements OnInit, OnDestroy {
|
||||
|
||||
hasDownload$ = this.purchasingOptions$.pipe(map((purchasingOptions) => purchasingOptions.includes('download')));
|
||||
|
||||
canContinue$ = this.store.canContinue$.pipe(tap((canContinue) => console.log('canContinue', canContinue)));
|
||||
canContinue$ = this.store.canContinue$;
|
||||
|
||||
private _onDestroy$ = new Subject<void>();
|
||||
|
||||
|
||||
@@ -60,6 +60,14 @@ export function isGiftCard(item: Item, type: ActionType): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export function isArchive(item: Item, type: ActionType): boolean {
|
||||
if (isItemDTO(item, type)) {
|
||||
return item?.features?.some((f) => f.key === 'ARC');
|
||||
} else {
|
||||
return !!item?.features?.['ARC'];
|
||||
}
|
||||
}
|
||||
|
||||
export function mapToItemPayload({
|
||||
item,
|
||||
quantity,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PriceDTO, PriceValueDTO } from '@swagger/checkout';
|
||||
import { DEFAULT_PRICE_DTO, DEFAULT_PRICE_VALUE, GIFT_CARD_MAX_PRICE, GIFT_CARD_TYPE, PURCHASE_OPTIONS } from '../constants';
|
||||
import { isGiftCard, isItemDTO } from './purchase-options.helpers';
|
||||
import { isArchive, isGiftCard, isItemDTO } from './purchase-options.helpers';
|
||||
import { PurchaseOptionsState } from './purchase-options.state';
|
||||
import { ActionType, Availability, Branch, CanAdd, FetchingAvailability, Item, PurchaseOption } from './purchase-options.types';
|
||||
|
||||
@@ -198,43 +198,51 @@ export function getAvailabilitiesForItem(
|
||||
};
|
||||
}
|
||||
|
||||
export function isArchive(item: Item, type: ActionType): boolean {
|
||||
if (isItemDTO(item, type)) {
|
||||
return item?.features?.some((f) => f.key === 'ARC');
|
||||
} else {
|
||||
return !!item?.features?.['ARC'];
|
||||
}
|
||||
export function getCanEditPrice(itemId: number): (state: PurchaseOptionsState) => boolean {
|
||||
return (state) => {
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
|
||||
if (isGiftCard(item, getType(state))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const purchaseOption = getPurchaseOption(state);
|
||||
|
||||
if (isArchive(item, getType(state)) && !getAvailabilityPriceForPurchaseOption(itemId, purchaseOption)(state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
export function getCanEditPrice(itemId: number): (state: PurchaseOptionsState) => boolean {
|
||||
export function getCanEditVat(itemId: number): (state: PurchaseOptionsState) => boolean {
|
||||
return (state) => {
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
const purchaseOption = getPurchaseOption(state);
|
||||
|
||||
if (isArchive(item, getType(state)) && !getAvailabilityPriceForPurchaseOption(itemId, purchaseOption)(state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
export function getIsGiftCard(itemId: number): (state: PurchaseOptionsState) => boolean {
|
||||
return (state) => {
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
return isGiftCard(item, getType(state));
|
||||
};
|
||||
}
|
||||
|
||||
export function getPriceForPurchaseOption(
|
||||
export function getAvailabilityPriceForPurchaseOption(
|
||||
itemId: number,
|
||||
purchaseOption: PurchaseOption
|
||||
): (state: PurchaseOptionsState) => PriceDTO & { fromCatalogue?: boolean } {
|
||||
): (state: PurchaseOptionsState) => (PriceDTO & { fromCatalogue?: boolean }) | undefined {
|
||||
return (state) => {
|
||||
if (
|
||||
getCanEditPrice(itemId)(state) ||
|
||||
isArchive(
|
||||
getItems(state).find((item) => item.id === itemId),
|
||||
getType(state)
|
||||
)
|
||||
) {
|
||||
const price = getPrices(state)[itemId];
|
||||
if (price) {
|
||||
return price;
|
||||
}
|
||||
}
|
||||
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
|
||||
const type = getType(state);
|
||||
|
||||
let availabilities = getAvailabilitiesForItem(itemId)(state);
|
||||
|
||||
let availability = availabilities.find((availability) => availability.purchaseOption === purchaseOption);
|
||||
@@ -271,13 +279,29 @@ export function getPriceForPurchaseOption(
|
||||
}
|
||||
|
||||
if (isItemDTO(item, type)) {
|
||||
return item?.catalogAvailability?.price ?? DEFAULT_PRICE_DTO;
|
||||
return item?.catalogAvailability?.price;
|
||||
} else {
|
||||
return item?.unitPrice ?? DEFAULT_PRICE_DTO;
|
||||
return item?.unitPrice;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getPriceForPurchaseOption(
|
||||
itemId: number,
|
||||
purchaseOption: PurchaseOption
|
||||
): (state: PurchaseOptionsState) => PriceDTO & { fromCatalogue?: boolean } {
|
||||
return (state) => {
|
||||
if (getCanEditPrice(itemId)(state)) {
|
||||
const price = getPrices(state)[itemId];
|
||||
if (price) {
|
||||
return price;
|
||||
}
|
||||
}
|
||||
|
||||
return getAvailabilityPriceForPurchaseOption(itemId, purchaseOption)(state) ?? DEFAULT_PRICE_DTO;
|
||||
};
|
||||
}
|
||||
|
||||
export function getQuantityForItem(itemId: number): (state: PurchaseOptionsState) => number {
|
||||
return (state) => {
|
||||
const item = getItems(state).find((item) => item.id === itemId);
|
||||
@@ -357,12 +381,21 @@ export function canContinue(state: PurchaseOptionsState): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
const actionType = getType(state);
|
||||
|
||||
for (let item of items) {
|
||||
if (isGiftCard(item, getType(state))) {
|
||||
if (isGiftCard(item, actionType)) {
|
||||
const price = getPriceForPurchaseOption(item.id, purchaseOption)(state);
|
||||
if (!(price?.value?.value > 0 && price?.value?.value <= GIFT_CARD_MAX_PRICE)) {
|
||||
return false;
|
||||
}
|
||||
} else if (isArchive(item, actionType) && !getAvailabilityPriceForPurchaseOption(item.id, purchaseOption)(state)) {
|
||||
const price = getPriceForPurchaseOption(item.id, purchaseOption)(state);
|
||||
const hasPrice = price?.value?.value > 0;
|
||||
const hasVat = price?.vat?.vatType > 0;
|
||||
if (!(hasPrice && hasVat)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -612,8 +612,8 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
});
|
||||
}
|
||||
|
||||
isGiftcard(itemId: number) {
|
||||
return this._service;
|
||||
getIsGiftCard(itemId: number) {
|
||||
return this.get(Selectors.getIsGiftCard(itemId));
|
||||
}
|
||||
|
||||
getPrice(itemId: number) {
|
||||
@@ -640,6 +640,18 @@ export class PurchaseOptionsStore extends ComponentStore<PurchaseOptionsState> {
|
||||
return this.select(Selectors.getCanEditPrice(itemId));
|
||||
}
|
||||
|
||||
getCanEditVat(itemId: number) {
|
||||
return this.get(Selectors.getCanEditVat(itemId));
|
||||
}
|
||||
|
||||
getCanEditVat$(itemId: number) {
|
||||
return this.select(Selectors.getCanEditVat(itemId));
|
||||
}
|
||||
|
||||
getIsGiftCard$(itemId: number) {
|
||||
return this.select(Selectors.getIsGiftCard(itemId));
|
||||
}
|
||||
|
||||
setPrice(itemId: number, value: number, manually: boolean = false) {
|
||||
const prices = this.prices;
|
||||
let price = prices[itemId];
|
||||
|
||||
@@ -24,7 +24,7 @@ export class UiOverlayTriggerDirective implements OnInit, OnDestroy, OnChanges {
|
||||
component: UiOverlayTrigger;
|
||||
|
||||
@Input()
|
||||
triggerOn: 'click' | 'hover' | 'init' = 'click';
|
||||
triggerOn: 'click' | 'hover' | 'init' | 'none' = 'click';
|
||||
|
||||
@Input()
|
||||
overlayTriggerDisabled: boolean;
|
||||
|
||||
Reference in New Issue
Block a user