mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
hotfix(customer-card-deactivate): Hotfix due to Keycard ISA Login Error
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<ng-container *ifRole="'Store'">
|
||||
<!-- <ng-container *ifRole="'Store'">
|
||||
@if (customerType !== 'b2b') {
|
||||
<shared-checkbox
|
||||
[ngModel]="p4mUser"
|
||||
@@ -8,15 +8,17 @@
|
||||
Kundenkarte
|
||||
</shared-checkbox>
|
||||
}
|
||||
</ng-container>
|
||||
</ng-container> -->
|
||||
@for (option of filteredOptions$ | async; track option) {
|
||||
@if (option?.enabled !== false) {
|
||||
<shared-checkbox
|
||||
[ngModel]="option.value === customerType"
|
||||
(ngModelChange)="setValue({ customerType: $event ? option.value : undefined })"
|
||||
(ngModelChange)="
|
||||
setValue({ customerType: $event ? option.value : undefined })
|
||||
"
|
||||
[disabled]="isOptionDisabled(option)"
|
||||
[name]="option.value"
|
||||
>
|
||||
>
|
||||
{{ option.label }}
|
||||
</shared-checkbox>
|
||||
}
|
||||
|
||||
@@ -21,7 +21,13 @@ import { OptionDTO } from '@generated/swagger/checkout-api';
|
||||
import { UiCheckboxComponent } from '@ui/checkbox';
|
||||
import { first, isBoolean, isString } from 'lodash';
|
||||
import { combineLatest, Observable, Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
map,
|
||||
shareReplay,
|
||||
switchMap,
|
||||
} from 'rxjs/operators';
|
||||
|
||||
export interface CustomerTypeSelectorState {
|
||||
processId: number;
|
||||
@@ -58,18 +64,18 @@ export class CustomerTypeSelectorComponent
|
||||
|
||||
@Input()
|
||||
get value() {
|
||||
if (this.p4mUser) {
|
||||
return `${this.customerType}-p4m`;
|
||||
}
|
||||
// if (this.p4mUser) {
|
||||
// return `${this.customerType}-p4m`;
|
||||
// }
|
||||
return this.customerType;
|
||||
}
|
||||
set value(value: string) {
|
||||
if (value.includes('-p4m')) {
|
||||
this.p4mUser = true;
|
||||
this.customerType = value.replace('-p4m', '');
|
||||
} else {
|
||||
this.customerType = value;
|
||||
}
|
||||
// if (value.includes('-p4m')) {
|
||||
// this.p4mUser = true;
|
||||
// this.customerType = value.replace('-p4m', '');
|
||||
// } else {
|
||||
this.customerType = value;
|
||||
// }
|
||||
}
|
||||
|
||||
@Output()
|
||||
@@ -111,30 +117,35 @@ export class CustomerTypeSelectorComponent
|
||||
get filteredOptions$() {
|
||||
const options$ = this.select((s) => s.options).pipe(distinctUntilChanged());
|
||||
const p4mUser$ = this.select((s) => s.p4mUser).pipe(distinctUntilChanged());
|
||||
const customerType$ = this.select((s) => s.customerType).pipe(distinctUntilChanged());
|
||||
const customerType$ = this.select((s) => s.customerType).pipe(
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
return combineLatest([options$, p4mUser$, customerType$]).pipe(
|
||||
filter(([options]) => options?.length > 0),
|
||||
map(([options, p4mUser, customerType]) => {
|
||||
const initial = { p4mUser: this.p4mUser, customerType: this.customerType };
|
||||
const initial = {
|
||||
p4mUser: this.p4mUser,
|
||||
customerType: this.customerType,
|
||||
};
|
||||
let result: OptionDTO[] = options;
|
||||
if (p4mUser) {
|
||||
result = result.filter((o) => o.value === 'store' || (o.value === 'webshop' && o.enabled !== false));
|
||||
// if (p4mUser) {
|
||||
// result = result.filter((o) => o.value === 'store' || (o.value === 'webshop' && o.enabled !== false));
|
||||
|
||||
result = result.map((o) => {
|
||||
if (o.value === 'store') {
|
||||
return { ...o, enabled: false };
|
||||
}
|
||||
return o;
|
||||
});
|
||||
}
|
||||
// result = result.map((o) => {
|
||||
// if (o.value === 'store') {
|
||||
// return { ...o, enabled: false };
|
||||
// }
|
||||
// return o;
|
||||
// });
|
||||
// }
|
||||
|
||||
if (customerType === 'b2b' && this.p4mUser) {
|
||||
this.p4mUser = false;
|
||||
}
|
||||
|
||||
if (initial.p4mUser !== this.p4mUser || initial.customerType !== this.customerType) {
|
||||
this.setValue({ customerType: this.customerType, p4mUser: this.p4mUser });
|
||||
}
|
||||
// if (initial.p4mUser !== this.p4mUser || initial.customerType !== this.customerType) {
|
||||
// this.setValue({ customerType: this.customerType, p4mUser: this.p4mUser });
|
||||
// }
|
||||
|
||||
return result;
|
||||
}),
|
||||
@@ -224,42 +235,53 @@ export class CustomerTypeSelectorComponent
|
||||
if (typeof value === 'string') {
|
||||
this.value = value;
|
||||
} else {
|
||||
if (isBoolean(value.p4mUser)) {
|
||||
this.p4mUser = value.p4mUser;
|
||||
}
|
||||
// if (isBoolean(value.p4mUser)) {
|
||||
// this.p4mUser = value.p4mUser;
|
||||
// }
|
||||
if (isString(value.customerType)) {
|
||||
this.customerType = value.customerType;
|
||||
} else if (this.p4mUser) {
|
||||
// Implementierung wie im PBI #3467 beschrieben
|
||||
// wenn customerType nicht gesetzt wird und p4mUser true ist,
|
||||
// dann customerType auf store setzen.
|
||||
// wenn dies nicht möglich ist da der Warenkob keinen store Kunden zulässt,
|
||||
// dann customerType auf webshop setzen.
|
||||
// wenn dies nicht möglich ist da der Warenkob keinen webshop Kunden zulässt,
|
||||
// dann customerType auf den ersten verfügbaren setzen und p4mUser auf false setzen.
|
||||
if (this.enabledOptions.some((o) => o.value === 'store')) {
|
||||
this.customerType = 'store';
|
||||
} else if (this.enabledOptions.some((o) => o.value === 'webshop')) {
|
||||
this.customerType = 'webshop';
|
||||
} else {
|
||||
this.p4mUser = false;
|
||||
const includesGuest = this.enabledOptions.some((o) => o.value === 'guest');
|
||||
this.customerType = includesGuest ? 'guest' : first(this.enabledOptions)?.value;
|
||||
}
|
||||
// } else if (this.p4mUser) {
|
||||
// // Implementierung wie im PBI #3467 beschrieben
|
||||
// // wenn customerType nicht gesetzt wird und p4mUser true ist,
|
||||
// // dann customerType auf store setzen.
|
||||
// // wenn dies nicht möglich ist da der Warenkob keinen store Kunden zulässt,
|
||||
// // dann customerType auf webshop setzen.
|
||||
// // wenn dies nicht möglich ist da der Warenkob keinen webshop Kunden zulässt,
|
||||
// // dann customerType auf den ersten verfügbaren setzen und p4mUser auf false setzen.
|
||||
// if (this.enabledOptions.some((o) => o.value === 'store')) {
|
||||
// this.customerType = 'store';
|
||||
// } else if (this.enabledOptions.some((o) => o.value === 'webshop')) {
|
||||
// this.customerType = 'webshop';
|
||||
// } else {
|
||||
// this.p4mUser = false;
|
||||
// const includesGuest = this.enabledOptions.some(
|
||||
// (o) => o.value === 'guest',
|
||||
// );
|
||||
// this.customerType = includesGuest
|
||||
// ? 'guest'
|
||||
// : first(this.enabledOptions)?.value;
|
||||
// }
|
||||
} else {
|
||||
// wenn customerType nicht gesetzt wird und p4mUser false ist,
|
||||
// dann customerType auf den ersten verfügbaren setzen der nicht mit dem aktuellen customerType übereinstimmt.
|
||||
this.customerType =
|
||||
first(this.enabledOptions.filter((o) => o.value === this.customerType))?.value ?? this.customerType;
|
||||
first(
|
||||
this.enabledOptions.filter((o) => o.value === this.customerType),
|
||||
)?.value ?? this.customerType;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.customerType !== initial.customerType || this.p4mUser !== initial.p4mUser) {
|
||||
if (
|
||||
this.customerType !== initial.customerType ||
|
||||
this.p4mUser !== initial.p4mUser
|
||||
) {
|
||||
this.onChange(this.value);
|
||||
this.onTouched();
|
||||
this.valueChanges.emit(this.value);
|
||||
}
|
||||
|
||||
this.checkboxes?.find((c) => c.name === this.customerType)?.writeValue(true);
|
||||
this.checkboxes
|
||||
?.find((c) => c.name === this.customerType)
|
||||
?.writeValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ export * from './interests';
|
||||
export * from './name';
|
||||
export * from './newsletter';
|
||||
export * from './organisation';
|
||||
export * from './p4m-number';
|
||||
// export * from './p4m-number';
|
||||
export * from './phone-numbers';
|
||||
export * from './form-block';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// start:ng42.barrel
|
||||
export * from './p4m-number-form-block.component';
|
||||
export * from './p4m-number-form-block.module';
|
||||
// end:ng42.barrel
|
||||
// // start:ng42.barrel
|
||||
// export * from './p4m-number-form-block.component';
|
||||
// export * from './p4m-number-form-block.module';
|
||||
// // end:ng42.barrel
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<shared-form-control label="Kundenkartencode" class="flex-grow">
|
||||
<!-- <shared-form-control label="Kundenkartencode" class="flex-grow">
|
||||
<input
|
||||
placeholder="Kundenkartencode"
|
||||
class="input-control"
|
||||
@@ -13,4 +13,4 @@
|
||||
<button type="button" (click)="scan()">
|
||||
<shared-icon icon="barcode-scan" [size]="32"></shared-icon>
|
||||
</button>
|
||||
}
|
||||
} -->
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
import { UntypedFormControl, Validators } from '@angular/forms';
|
||||
import { FormBlockControl } from '../form-block';
|
||||
import { ScanAdapterService } from '@adapter/scan';
|
||||
// import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
// import { UntypedFormControl, Validators } from '@angular/forms';
|
||||
// import { FormBlockControl } from '../form-block';
|
||||
// import { ScanAdapterService } from '@adapter/scan';
|
||||
|
||||
@Component({
|
||||
selector: 'app-p4m-number-form-block',
|
||||
templateUrl: 'p4m-number-form-block.component.html',
|
||||
styleUrls: ['p4m-number-form-block.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
export class P4mNumberFormBlockComponent extends FormBlockControl<string> {
|
||||
get tabIndexEnd() {
|
||||
return this.tabIndexStart;
|
||||
}
|
||||
// @Component({
|
||||
// selector: 'app-p4m-number-form-block',
|
||||
// templateUrl: 'p4m-number-form-block.component.html',
|
||||
// styleUrls: ['p4m-number-form-block.component.scss'],
|
||||
// changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
// standalone: false,
|
||||
// })
|
||||
// export class P4mNumberFormBlockComponent extends FormBlockControl<string> {
|
||||
// get tabIndexEnd() {
|
||||
// return this.tabIndexStart;
|
||||
// }
|
||||
|
||||
constructor(
|
||||
private scanAdapter: ScanAdapterService,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
// constructor(
|
||||
// private scanAdapter: ScanAdapterService,
|
||||
// private changeDetectorRef: ChangeDetectorRef,
|
||||
// ) {
|
||||
// super();
|
||||
// }
|
||||
|
||||
updateValidators(): void {
|
||||
this.control.setValidators([...this.getValidatorFn()]);
|
||||
this.control.setAsyncValidators(this.getAsyncValidatorFn());
|
||||
this.control.updateValueAndValidity();
|
||||
}
|
||||
// updateValidators(): void {
|
||||
// this.control.setValidators([...this.getValidatorFn()]);
|
||||
// this.control.setAsyncValidators(this.getAsyncValidatorFn());
|
||||
// this.control.updateValueAndValidity();
|
||||
// }
|
||||
|
||||
initializeControl(data?: string): void {
|
||||
this.control = new UntypedFormControl(data ?? '', [Validators.required], this.getAsyncValidatorFn());
|
||||
}
|
||||
// initializeControl(data?: string): void {
|
||||
// this.control = new UntypedFormControl(data ?? '', [Validators.required], this.getAsyncValidatorFn());
|
||||
// }
|
||||
|
||||
_patchValue(update: { previous: string; current: string }): void {
|
||||
this.control.patchValue(update.current);
|
||||
}
|
||||
// _patchValue(update: { previous: string; current: string }): void {
|
||||
// this.control.patchValue(update.current);
|
||||
// }
|
||||
|
||||
scan() {
|
||||
this.scanAdapter.scan().subscribe((result) => {
|
||||
this.control.patchValue(result);
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
}
|
||||
// scan() {
|
||||
// this.scanAdapter.scan().subscribe((result) => {
|
||||
// this.control.patchValue(result);
|
||||
// this.changeDetectorRef.markForCheck();
|
||||
// });
|
||||
// }
|
||||
|
||||
canScan() {
|
||||
return this.scanAdapter.isReady();
|
||||
}
|
||||
}
|
||||
// canScan() {
|
||||
// return this.scanAdapter.isReady();
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
// import { NgModule } from '@angular/core';
|
||||
// import { CommonModule } from '@angular/common';
|
||||
|
||||
import { P4mNumberFormBlockComponent } from './p4m-number-form-block.component';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { IconComponent } from '@shared/components/icon';
|
||||
import { FormControlComponent } from '@shared/components/form-control';
|
||||
// import { P4mNumberFormBlockComponent } from './p4m-number-form-block.component';
|
||||
// import { ReactiveFormsModule } from '@angular/forms';
|
||||
// import { IconComponent } from '@shared/components/icon';
|
||||
// import { FormControlComponent } from '@shared/components/form-control';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, ReactiveFormsModule, FormControlComponent, IconComponent],
|
||||
exports: [P4mNumberFormBlockComponent],
|
||||
declarations: [P4mNumberFormBlockComponent],
|
||||
})
|
||||
export class P4mNumberFormBlockModule {}
|
||||
// @NgModule({
|
||||
// imports: [CommonModule, ReactiveFormsModule, FormControlComponent, IconComponent],
|
||||
// exports: [P4mNumberFormBlockComponent],
|
||||
// declarations: [P4mNumberFormBlockComponent],
|
||||
// })
|
||||
// export class P4mNumberFormBlockModule {}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { ChangeDetectorRef, Directive, OnDestroy, OnInit, ViewChild, inject } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Directive,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
AbstractControl,
|
||||
AsyncValidatorFn,
|
||||
@@ -11,7 +18,12 @@ import {
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BreadcrumbService } from '@core/breadcrumb';
|
||||
import { CrmCustomerService } from '@domain/crm';
|
||||
import { AddressDTO, CustomerDTO, PayerDTO, ShippingAddressDTO } from '@generated/swagger/crm-api';
|
||||
import {
|
||||
AddressDTO,
|
||||
CustomerDTO,
|
||||
PayerDTO,
|
||||
ShippingAddressDTO,
|
||||
} from '@generated/swagger/crm-api';
|
||||
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
|
||||
import { UiValidators } from '@ui/validators';
|
||||
import { isNull } from 'lodash';
|
||||
@@ -42,7 +54,10 @@ import {
|
||||
mapCustomerInfoDtoToCustomerCreateFormData,
|
||||
} from './customer-create-form-data';
|
||||
import { AddressSelectionModalService } from '../modals';
|
||||
import { CustomerCreateNavigation, CustomerSearchNavigation } from '@shared/services/navigation';
|
||||
import {
|
||||
CustomerCreateNavigation,
|
||||
CustomerSearchNavigation,
|
||||
} from '@shared/services/navigation';
|
||||
|
||||
@Directive()
|
||||
export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
@@ -104,7 +119,12 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
);
|
||||
|
||||
this.processId$
|
||||
.pipe(startWith(undefined), bufferCount(2, 1), takeUntil(this.onDestroy$), delay(100))
|
||||
.pipe(
|
||||
startWith(undefined),
|
||||
bufferCount(2, 1),
|
||||
takeUntil(this.onDestroy$),
|
||||
delay(100),
|
||||
)
|
||||
.subscribe(async ([previous, current]) => {
|
||||
if (previous === undefined) {
|
||||
await this._initFormData();
|
||||
@@ -155,7 +175,10 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
async addOrUpdateBreadcrumb(processId: number, formData: CustomerCreateFormData) {
|
||||
async addOrUpdateBreadcrumb(
|
||||
processId: number,
|
||||
formData: CustomerCreateFormData,
|
||||
) {
|
||||
await this.breadcrumb.addOrUpdateBreadcrumbIfNotExists({
|
||||
key: processId,
|
||||
name: 'Kundendaten erfassen',
|
||||
@@ -195,7 +218,10 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
console.log('customerTypeChanged', customerType);
|
||||
}
|
||||
|
||||
addFormBlock(key: keyof CustomerCreateFormData, block: FormBlock<any, AbstractControl>) {
|
||||
addFormBlock(
|
||||
key: keyof CustomerCreateFormData,
|
||||
block: FormBlock<any, AbstractControl>,
|
||||
) {
|
||||
this.form.addControl(key, block.control);
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
@@ -232,7 +258,10 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
return true;
|
||||
}
|
||||
// Check Year + Month
|
||||
else if (inputDate.getFullYear() === minBirthDate.getFullYear() && inputDate.getMonth() < minBirthDate.getMonth()) {
|
||||
else if (
|
||||
inputDate.getFullYear() === minBirthDate.getFullYear() &&
|
||||
inputDate.getMonth() < minBirthDate.getMonth()
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// Check Year + Month + Day
|
||||
@@ -279,70 +308,80 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
);
|
||||
};
|
||||
|
||||
checkLoyalityCardValidator: AsyncValidatorFn = (control) => {
|
||||
return of(control.value).pipe(
|
||||
delay(500),
|
||||
mergeMap((value) => {
|
||||
const customerId = this.formData?._meta?.customerDto?.id ?? this.formData?._meta?.customerInfoDto?.id;
|
||||
return this.customerService.checkLoyaltyCard({ loyaltyCardNumber: value, customerId }).pipe(
|
||||
map((response) => {
|
||||
if (response.error) {
|
||||
throw response.message;
|
||||
}
|
||||
// checkLoyalityCardValidator: AsyncValidatorFn = (control) => {
|
||||
// return of(control.value).pipe(
|
||||
// delay(500),
|
||||
// mergeMap((value) => {
|
||||
// const customerId = this.formData?._meta?.customerDto?.id ?? this.formData?._meta?.customerInfoDto?.id;
|
||||
// return this.customerService.checkLoyaltyCard({ loyaltyCardNumber: value, customerId }).pipe(
|
||||
// map((response) => {
|
||||
// if (response.error) {
|
||||
// throw response.message;
|
||||
// }
|
||||
|
||||
/**
|
||||
* #4485 Kubi // Verhalten mit angelegte aber nicht verknüpfte Kundenkartencode in Kundensuche und Kundendaten erfassen ist nicht gleich
|
||||
* Fall1: Kundenkarte hat Daten in point4more:
|
||||
* Sobald Kundenkartencode in Feld "Kundenkartencode" reingegeben wird- werden die Daten von point4more in Formular "Kundendaten Erfassen" eingefügt und ersetzen (im Ganzen, nicht inkremental) die Daten in Felder, falls welche schon reingetippt werden.
|
||||
* Fall2: Kundenkarte hat keine Daten in point4more:
|
||||
* Sobald Kundenkartencode in Feld "Kundenkartencode" reingegeben wird- bleiben die Daten in Formular "Kundendaten Erfassen" in Felder, falls welche schon reingetippt werden.
|
||||
*/
|
||||
if (response.result && response.result.customer) {
|
||||
const customer = response.result.customer;
|
||||
const data = mapCustomerInfoDtoToCustomerCreateFormData(customer);
|
||||
// /**
|
||||
// * #4485 Kubi // Verhalten mit angelegte aber nicht verknüpfte Kundenkartencode in Kundensuche und Kundendaten erfassen ist nicht gleich
|
||||
// * Fall1: Kundenkarte hat Daten in point4more:
|
||||
// * Sobald Kundenkartencode in Feld "Kundenkartencode" reingegeben wird- werden die Daten von point4more in Formular "Kundendaten Erfassen" eingefügt und ersetzen (im Ganzen, nicht inkremental) die Daten in Felder, falls welche schon reingetippt werden.
|
||||
// * Fall2: Kundenkarte hat keine Daten in point4more:
|
||||
// * Sobald Kundenkartencode in Feld "Kundenkartencode" reingegeben wird- bleiben die Daten in Formular "Kundendaten Erfassen" in Felder, falls welche schon reingetippt werden.
|
||||
// */
|
||||
// if (response.result && response.result.customer) {
|
||||
// const customer = response.result.customer;
|
||||
// const data = mapCustomerInfoDtoToCustomerCreateFormData(customer);
|
||||
|
||||
if (data.name.firstName && data.name.lastName) {
|
||||
// Fall1
|
||||
this._formData.next(data);
|
||||
} else {
|
||||
// Fall2 Hier müssen die Metadaten gesetzt werden um eine verknüfung zur kundenkarte zu ermöglichen.
|
||||
const current = this.formData;
|
||||
current._meta = data._meta;
|
||||
current.p4m = data.p4m;
|
||||
}
|
||||
}
|
||||
// if (data.name.firstName && data.name.lastName) {
|
||||
// // Fall1
|
||||
// this._formData.next(data);
|
||||
// } else {
|
||||
// // Fall2 Hier müssen die Metadaten gesetzt werden um eine verknüfung zur kundenkarte zu ermöglichen.
|
||||
// const current = this.formData;
|
||||
// current._meta = data._meta;
|
||||
// current.p4m = data.p4m;
|
||||
// }
|
||||
// }
|
||||
|
||||
return null;
|
||||
}),
|
||||
catchError((error) => {
|
||||
if (error instanceof HttpErrorResponse) {
|
||||
if (error?.error?.invalidProperties?.loyaltyCardNumber) {
|
||||
return of({ invalid: error.error.invalidProperties.loyaltyCardNumber });
|
||||
} else {
|
||||
return of({ invalid: 'Kundenkartencode ist ungültig' });
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
}),
|
||||
tap(() => {
|
||||
control.markAsTouched();
|
||||
this.cdr.markForCheck();
|
||||
}),
|
||||
);
|
||||
};
|
||||
// return null;
|
||||
// }),
|
||||
// catchError((error) => {
|
||||
// if (error instanceof HttpErrorResponse) {
|
||||
// if (error?.error?.invalidProperties?.loyaltyCardNumber) {
|
||||
// return of({ invalid: error.error.invalidProperties.loyaltyCardNumber });
|
||||
// } else {
|
||||
// return of({ invalid: 'Kundenkartencode ist ungültig' });
|
||||
// }
|
||||
// }
|
||||
// }),
|
||||
// );
|
||||
// }),
|
||||
// tap(() => {
|
||||
// control.markAsTouched();
|
||||
// this.cdr.markForCheck();
|
||||
// }),
|
||||
// );
|
||||
// };
|
||||
|
||||
async navigateToCustomerDetails(customer: CustomerDTO) {
|
||||
const processId = await this.processId$.pipe(first()).toPromise();
|
||||
const route = this.customerSearchNavigation.detailsRoute({ processId, customerId: customer.id, customer });
|
||||
const route = this.customerSearchNavigation.detailsRoute({
|
||||
processId,
|
||||
customerId: customer.id,
|
||||
customer,
|
||||
});
|
||||
|
||||
return this.router.navigate(route.path, { queryParams: route.urlTree.queryParams });
|
||||
return this.router.navigate(route.path, {
|
||||
queryParams: route.urlTree.queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
async validateAddressData(address: AddressDTO): Promise<AddressDTO> {
|
||||
const addressValidationResult = await this.addressVlidationModal.validateAddress(address);
|
||||
const addressValidationResult =
|
||||
await this.addressVlidationModal.validateAddress(address);
|
||||
|
||||
if (addressValidationResult !== undefined && (addressValidationResult as any) !== 'continue') {
|
||||
if (
|
||||
addressValidationResult !== undefined &&
|
||||
(addressValidationResult as any) !== 'continue'
|
||||
) {
|
||||
address = addressValidationResult;
|
||||
}
|
||||
|
||||
@@ -389,7 +428,9 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
} catch (error) {
|
||||
this.form.enable();
|
||||
setTimeout(() => {
|
||||
this.addressFormBlock.setAddressValidationError(error.error.invalidProperties);
|
||||
this.addressFormBlock.setAddressValidationError(
|
||||
error.error.invalidProperties,
|
||||
);
|
||||
}, 10);
|
||||
|
||||
return;
|
||||
@@ -397,7 +438,10 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
if (data.birthDate && isNull(UiValidators.date(new UntypedFormControl(data.birthDate)))) {
|
||||
if (
|
||||
data.birthDate &&
|
||||
isNull(UiValidators.date(new UntypedFormControl(data.birthDate)))
|
||||
) {
|
||||
customer.dateOfBirth = data.birthDate;
|
||||
}
|
||||
|
||||
@@ -406,11 +450,15 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
|
||||
if (this.validateShippingAddress) {
|
||||
try {
|
||||
billingAddress.address = await this.validateAddressData(billingAddress.address);
|
||||
billingAddress.address = await this.validateAddressData(
|
||||
billingAddress.address,
|
||||
);
|
||||
} catch (error) {
|
||||
this.form.enable();
|
||||
setTimeout(() => {
|
||||
this.addressFormBlock.setAddressValidationError(error.error.invalidProperties);
|
||||
this.addressFormBlock.setAddressValidationError(
|
||||
error.error.invalidProperties,
|
||||
);
|
||||
}, 10);
|
||||
|
||||
return;
|
||||
@@ -426,15 +474,21 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
if (data.deviatingDeliveryAddress?.deviatingAddress) {
|
||||
const shippingAddress = this.mapToShippingAddress(data.deviatingDeliveryAddress);
|
||||
const shippingAddress = this.mapToShippingAddress(
|
||||
data.deviatingDeliveryAddress,
|
||||
);
|
||||
|
||||
if (this.validateShippingAddress) {
|
||||
try {
|
||||
shippingAddress.address = await this.validateAddressData(shippingAddress.address);
|
||||
shippingAddress.address = await this.validateAddressData(
|
||||
shippingAddress.address,
|
||||
);
|
||||
} catch (error) {
|
||||
this.form.enable();
|
||||
setTimeout(() => {
|
||||
this.deviatingDeliveryAddressFormBlock.setAddressValidationError(error.error.invalidProperties);
|
||||
this.deviatingDeliveryAddressFormBlock.setAddressValidationError(
|
||||
error.error.invalidProperties,
|
||||
);
|
||||
}, 10);
|
||||
|
||||
return;
|
||||
@@ -474,7 +528,13 @@ export abstract class AbstractCreateCustomer implements OnInit, OnDestroy {
|
||||
};
|
||||
}
|
||||
|
||||
mapToBillingAddress({ name, address, email, organisation, phoneNumbers }: DeviatingAddressFormBlockData): PayerDTO {
|
||||
mapToBillingAddress({
|
||||
name,
|
||||
address,
|
||||
email,
|
||||
organisation,
|
||||
phoneNumbers,
|
||||
}: DeviatingAddressFormBlockData): PayerDTO {
|
||||
return {
|
||||
gender: name?.gender,
|
||||
title: name?.title,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CreateB2BCustomerModule } from './create-b2b-customer/create-b2b-customer.module';
|
||||
import { CreateGuestCustomerModule } from './create-guest-customer';
|
||||
import { CreateP4MCustomerModule } from './create-p4m-customer';
|
||||
// import { CreateP4MCustomerModule } from './create-p4m-customer';
|
||||
import { CreateStoreCustomerModule } from './create-store-customer/create-store-customer.module';
|
||||
import { CreateWebshopCustomerModule } from './create-webshop-customer/create-webshop-customer.module';
|
||||
import { UpdateP4MWebshopCustomerModule } from './update-p4m-webshop-customer';
|
||||
// import { UpdateP4MWebshopCustomerModule } from './update-p4m-webshop-customer';
|
||||
import { CreateCustomerComponent } from './create-customer.component';
|
||||
|
||||
@NgModule({
|
||||
@@ -13,8 +13,8 @@ import { CreateCustomerComponent } from './create-customer.component';
|
||||
CreateGuestCustomerModule,
|
||||
CreateStoreCustomerModule,
|
||||
CreateWebshopCustomerModule,
|
||||
CreateP4MCustomerModule,
|
||||
UpdateP4MWebshopCustomerModule,
|
||||
// CreateP4MCustomerModule,
|
||||
// UpdateP4MWebshopCustomerModule,
|
||||
CreateCustomerComponent,
|
||||
],
|
||||
exports: [
|
||||
@@ -22,8 +22,8 @@ import { CreateCustomerComponent } from './create-customer.component';
|
||||
CreateGuestCustomerModule,
|
||||
CreateStoreCustomerModule,
|
||||
CreateWebshopCustomerModule,
|
||||
CreateP4MCustomerModule,
|
||||
UpdateP4MWebshopCustomerModule,
|
||||
// CreateP4MCustomerModule,
|
||||
// UpdateP4MWebshopCustomerModule,
|
||||
CreateCustomerComponent,
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@if (formData$ | async; as data) {
|
||||
<!-- @if (formData$ | async; as data) {
|
||||
<form (keydown.enter)="$event.preventDefault()">
|
||||
<h1 class="title flex flex-row items-center justify-center">
|
||||
Kundendaten erfassen
|
||||
<!-- <span
|
||||
class="rounded-full ml-4 h-8 w-8 text-xl text-center border-2 border-solid border-brand text-brand">i</span> -->
|
||||
<span
|
||||
class="rounded-full ml-4 h-8 w-8 text-xl text-center border-2 border-solid border-brand text-brand">i</span>
|
||||
</h1>
|
||||
<p class="description">
|
||||
Um Sie als Kunde beim nächsten
|
||||
@@ -135,4 +135,4 @@
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
} -->
|
||||
|
||||
@@ -1,292 +1,292 @@
|
||||
import { Component, ChangeDetectionStrategy, ViewChild, OnInit } from '@angular/core';
|
||||
import { AsyncValidatorFn, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { Result } from '@domain/defs';
|
||||
import { CustomerDTO, CustomerInfoDTO, KeyValueDTOOfStringAndString } from '@generated/swagger/crm-api';
|
||||
import { UiErrorModalComponent, UiModalResult } from '@ui/modal';
|
||||
import { NEVER, Observable, of } from 'rxjs';
|
||||
import { catchError, distinctUntilChanged, first, map, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
|
||||
import {
|
||||
AddressFormBlockComponent,
|
||||
AddressFormBlockData,
|
||||
DeviatingAddressFormBlockComponent,
|
||||
} from '../../components/form-blocks';
|
||||
import { NameFormBlockData } from '../../components/form-blocks/name/name-form-block-data';
|
||||
import { WebshopCustomnerAlreadyExistsModalComponent, WebshopCustomnerAlreadyExistsModalData } from '../../modals';
|
||||
import { validateEmail } from '../../validators/email-validator';
|
||||
import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
import { encodeFormData, mapCustomerDtoToCustomerCreateFormData } from '../customer-create-form-data';
|
||||
import { zipCodeValidator } from '../../validators/zip-code-validator';
|
||||
// import { Component, ChangeDetectionStrategy, ViewChild, OnInit } from '@angular/core';
|
||||
// import { AsyncValidatorFn, ValidatorFn, Validators } from '@angular/forms';
|
||||
// import { Result } from '@domain/defs';
|
||||
// import { CustomerDTO, CustomerInfoDTO, KeyValueDTOOfStringAndString } from '@generated/swagger/crm-api';
|
||||
// import { UiErrorModalComponent, UiModalResult } from '@ui/modal';
|
||||
// import { NEVER, Observable, of } from 'rxjs';
|
||||
// import { catchError, distinctUntilChanged, first, map, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
|
||||
// import {
|
||||
// AddressFormBlockComponent,
|
||||
// AddressFormBlockData,
|
||||
// DeviatingAddressFormBlockComponent,
|
||||
// } from '../../components/form-blocks';
|
||||
// import { NameFormBlockData } from '../../components/form-blocks/name/name-form-block-data';
|
||||
// import { WebshopCustomnerAlreadyExistsModalComponent, WebshopCustomnerAlreadyExistsModalData } from '../../modals';
|
||||
// import { validateEmail } from '../../validators/email-validator';
|
||||
// import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
// import { encodeFormData, mapCustomerDtoToCustomerCreateFormData } from '../customer-create-form-data';
|
||||
// import { zipCodeValidator } from '../../validators/zip-code-validator';
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-p4m-customer',
|
||||
templateUrl: 'create-p4m-customer.component.html',
|
||||
styleUrls: ['../create-customer.scss', 'create-p4m-customer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
export class CreateP4MCustomerComponent extends AbstractCreateCustomer implements OnInit {
|
||||
validateAddress = true;
|
||||
// @Component({
|
||||
// selector: 'app-create-p4m-customer',
|
||||
// templateUrl: 'create-p4m-customer.component.html',
|
||||
// styleUrls: ['../create-customer.scss', 'create-p4m-customer.component.scss'],
|
||||
// changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
// standalone: false,
|
||||
// })
|
||||
// export class CreateP4MCustomerComponent extends AbstractCreateCustomer implements OnInit {
|
||||
// validateAddress = true;
|
||||
|
||||
validateShippingAddress = true;
|
||||
// validateShippingAddress = true;
|
||||
|
||||
get _customerType() {
|
||||
return this.activatedRoute.snapshot.data.customerType;
|
||||
}
|
||||
// get _customerType() {
|
||||
// return this.activatedRoute.snapshot.data.customerType;
|
||||
// }
|
||||
|
||||
get customerType() {
|
||||
return `${this._customerType}-p4m`;
|
||||
}
|
||||
// get customerType() {
|
||||
// return `${this._customerType}-p4m`;
|
||||
// }
|
||||
|
||||
nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
// nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
title: [],
|
||||
};
|
||||
// nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
// firstName: [Validators.required],
|
||||
// lastName: [Validators.required],
|
||||
// gender: [Validators.required],
|
||||
// title: [],
|
||||
// };
|
||||
|
||||
emailRequiredMark: boolean;
|
||||
// emailRequiredMark: boolean;
|
||||
|
||||
emailValidatorFn: ValidatorFn[];
|
||||
// emailValidatorFn: ValidatorFn[];
|
||||
|
||||
asyncEmailVlaidtorFn: AsyncValidatorFn[];
|
||||
// asyncEmailVlaidtorFn: AsyncValidatorFn[];
|
||||
|
||||
asyncLoyaltyCardValidatorFn: AsyncValidatorFn[];
|
||||
// asyncLoyaltyCardValidatorFn: AsyncValidatorFn[];
|
||||
|
||||
shippingAddressRequiredMarks: (keyof AddressFormBlockData)[] = [
|
||||
'street',
|
||||
'streetNumber',
|
||||
'zipCode',
|
||||
'city',
|
||||
'country',
|
||||
];
|
||||
// shippingAddressRequiredMarks: (keyof AddressFormBlockData)[] = [
|
||||
// 'street',
|
||||
// 'streetNumber',
|
||||
// 'zipCode',
|
||||
// 'city',
|
||||
// 'country',
|
||||
// ];
|
||||
|
||||
shippingAddressValidators: Record<string, ValidatorFn[]> = {
|
||||
street: [Validators.required],
|
||||
streetNumber: [Validators.required],
|
||||
zipCode: [Validators.required, zipCodeValidator()],
|
||||
city: [Validators.required],
|
||||
country: [Validators.required],
|
||||
};
|
||||
// shippingAddressValidators: Record<string, ValidatorFn[]> = {
|
||||
// street: [Validators.required],
|
||||
// streetNumber: [Validators.required],
|
||||
// zipCode: [Validators.required, zipCodeValidator()],
|
||||
// city: [Validators.required],
|
||||
// country: [Validators.required],
|
||||
// };
|
||||
|
||||
addressRequiredMarks: (keyof AddressFormBlockData)[];
|
||||
// addressRequiredMarks: (keyof AddressFormBlockData)[];
|
||||
|
||||
addressValidatorFns: Record<string, ValidatorFn[]>;
|
||||
// addressValidatorFns: Record<string, ValidatorFn[]>;
|
||||
|
||||
@ViewChild(AddressFormBlockComponent, { static: false })
|
||||
addressFormBlock: AddressFormBlockComponent;
|
||||
// @ViewChild(AddressFormBlockComponent, { static: false })
|
||||
// addressFormBlock: AddressFormBlockComponent;
|
||||
|
||||
@ViewChild(DeviatingAddressFormBlockComponent, { static: false })
|
||||
deviatingDeliveryAddressFormBlock: DeviatingAddressFormBlockComponent;
|
||||
// @ViewChild(DeviatingAddressFormBlockComponent, { static: false })
|
||||
// deviatingDeliveryAddressFormBlock: DeviatingAddressFormBlockComponent;
|
||||
|
||||
agbValidatorFns = [Validators.requiredTrue];
|
||||
// agbValidatorFns = [Validators.requiredTrue];
|
||||
|
||||
birthDateValidatorFns = [];
|
||||
// birthDateValidatorFns = [];
|
||||
|
||||
existingCustomer$: Observable<CustomerInfoDTO | CustomerDTO | null>;
|
||||
// existingCustomer$: Observable<CustomerInfoDTO | CustomerDTO | null>;
|
||||
|
||||
ngOnInit(): void {
|
||||
super.ngOnInit();
|
||||
this.initMarksAndValidators();
|
||||
this.existingCustomer$ = this.customerExists$.pipe(
|
||||
distinctUntilChanged(),
|
||||
switchMap((exists) => {
|
||||
if (exists) {
|
||||
return this.fetchCustomerInfo();
|
||||
}
|
||||
return of(null);
|
||||
}),
|
||||
);
|
||||
// ngOnInit(): void {
|
||||
// super.ngOnInit();
|
||||
// this.initMarksAndValidators();
|
||||
// this.existingCustomer$ = this.customerExists$.pipe(
|
||||
// distinctUntilChanged(),
|
||||
// switchMap((exists) => {
|
||||
// if (exists) {
|
||||
// return this.fetchCustomerInfo();
|
||||
// }
|
||||
// return of(null);
|
||||
// }),
|
||||
// );
|
||||
|
||||
this.existingCustomer$
|
||||
.pipe(
|
||||
takeUntil(this.onDestroy$),
|
||||
switchMap((info) => {
|
||||
if (info) {
|
||||
return this.customerService.getCustomer(info.id, 2).pipe(
|
||||
map((res) => res.result),
|
||||
catchError((err) => NEVER),
|
||||
);
|
||||
}
|
||||
return NEVER;
|
||||
}),
|
||||
withLatestFrom(this.processId$),
|
||||
)
|
||||
.subscribe(([customer, processId]) => {
|
||||
if (customer) {
|
||||
this.modal
|
||||
.open({
|
||||
content: WebshopCustomnerAlreadyExistsModalComponent,
|
||||
data: {
|
||||
customer,
|
||||
processId,
|
||||
} as WebshopCustomnerAlreadyExistsModalData,
|
||||
title: 'Es existiert bereits ein Onlinekonto mit dieser E-Mail-Adresse',
|
||||
})
|
||||
.afterClosed$.subscribe(async (result: UiModalResult<boolean>) => {
|
||||
if (result.data) {
|
||||
this.navigateToUpdatePage(customer);
|
||||
} else {
|
||||
this.formData.email = '';
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// this.existingCustomer$
|
||||
// .pipe(
|
||||
// takeUntil(this.onDestroy$),
|
||||
// switchMap((info) => {
|
||||
// if (info) {
|
||||
// return this.customerService.getCustomer(info.id, 2).pipe(
|
||||
// map((res) => res.result),
|
||||
// catchError((err) => NEVER),
|
||||
// );
|
||||
// }
|
||||
// return NEVER;
|
||||
// }),
|
||||
// withLatestFrom(this.processId$),
|
||||
// )
|
||||
// .subscribe(([customer, processId]) => {
|
||||
// if (customer) {
|
||||
// this.modal
|
||||
// .open({
|
||||
// content: WebshopCustomnerAlreadyExistsModalComponent,
|
||||
// data: {
|
||||
// customer,
|
||||
// processId,
|
||||
// } as WebshopCustomnerAlreadyExistsModalData,
|
||||
// title: 'Es existiert bereits ein Onlinekonto mit dieser E-Mail-Adresse',
|
||||
// })
|
||||
// .afterClosed$.subscribe(async (result: UiModalResult<boolean>) => {
|
||||
// if (result.data) {
|
||||
// this.navigateToUpdatePage(customer);
|
||||
// } else {
|
||||
// this.formData.email = '';
|
||||
// this.cdr.markForCheck();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
async navigateToUpdatePage(customer: CustomerDTO) {
|
||||
const processId = await this.processId$.pipe(first()).toPromise();
|
||||
this.router.navigate(['/kunde', processId, 'customer', 'create', 'webshop-p4m', 'update'], {
|
||||
queryParams: {
|
||||
formData: encodeFormData({
|
||||
...mapCustomerDtoToCustomerCreateFormData(customer),
|
||||
p4m: this.formData.p4m,
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
// async navigateToUpdatePage(customer: CustomerDTO) {
|
||||
// const processId = await this.processId$.pipe(first()).toPromise();
|
||||
// this.router.navigate(['/kunde', processId, 'customer', 'create', 'webshop-p4m', 'update'], {
|
||||
// queryParams: {
|
||||
// formData: encodeFormData({
|
||||
// ...mapCustomerDtoToCustomerCreateFormData(customer),
|
||||
// p4m: this.formData.p4m,
|
||||
// }),
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
initMarksAndValidators() {
|
||||
this.asyncLoyaltyCardValidatorFn = [this.checkLoyalityCardValidator];
|
||||
this.birthDateValidatorFns = [Validators.required, this.minBirthDateValidator()];
|
||||
if (this._customerType === 'webshop') {
|
||||
this.emailRequiredMark = true;
|
||||
this.emailValidatorFn = [Validators.required, Validators.email, validateEmail];
|
||||
this.asyncEmailVlaidtorFn = [this.emailExistsValidator];
|
||||
this.addressRequiredMarks = this.shippingAddressRequiredMarks;
|
||||
this.addressValidatorFns = this.shippingAddressValidators;
|
||||
} else {
|
||||
this.emailRequiredMark = false;
|
||||
this.emailValidatorFn = [Validators.email, validateEmail];
|
||||
}
|
||||
}
|
||||
// initMarksAndValidators() {
|
||||
// this.asyncLoyaltyCardValidatorFn = [this.checkLoyalityCardValidator];
|
||||
// this.birthDateValidatorFns = [Validators.required, this.minBirthDateValidator()];
|
||||
// if (this._customerType === 'webshop') {
|
||||
// this.emailRequiredMark = true;
|
||||
// this.emailValidatorFn = [Validators.required, Validators.email, validateEmail];
|
||||
// this.asyncEmailVlaidtorFn = [this.emailExistsValidator];
|
||||
// this.addressRequiredMarks = this.shippingAddressRequiredMarks;
|
||||
// this.addressValidatorFns = this.shippingAddressValidators;
|
||||
// } else {
|
||||
// this.emailRequiredMark = false;
|
||||
// this.emailValidatorFn = [Validators.email, validateEmail];
|
||||
// }
|
||||
// }
|
||||
|
||||
fetchCustomerInfo(): Observable<CustomerDTO | null> {
|
||||
const email = this.formData.email;
|
||||
return this.customerService.getOnlineCustomerByEmail(email).pipe(
|
||||
map((result) => {
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
catchError((err) => {
|
||||
this.modal.open({
|
||||
content: UiErrorModalComponent,
|
||||
data: err,
|
||||
});
|
||||
return [null];
|
||||
}),
|
||||
);
|
||||
}
|
||||
// fetchCustomerInfo(): Observable<CustomerDTO | null> {
|
||||
// const email = this.formData.email;
|
||||
// return this.customerService.getOnlineCustomerByEmail(email).pipe(
|
||||
// map((result) => {
|
||||
// if (result) {
|
||||
// return result;
|
||||
// }
|
||||
// return null;
|
||||
// }),
|
||||
// catchError((err) => {
|
||||
// this.modal.open({
|
||||
// content: UiErrorModalComponent,
|
||||
// data: err,
|
||||
// });
|
||||
// return [null];
|
||||
// }),
|
||||
// );
|
||||
// }
|
||||
|
||||
getInterests(): KeyValueDTOOfStringAndString[] {
|
||||
const interests: KeyValueDTOOfStringAndString[] = [];
|
||||
// getInterests(): KeyValueDTOOfStringAndString[] {
|
||||
// const interests: KeyValueDTOOfStringAndString[] = [];
|
||||
|
||||
for (const key in this.formData.interests) {
|
||||
if (this.formData.interests[key]) {
|
||||
interests.push({ key, group: 'KUBI_INTERESSEN' });
|
||||
}
|
||||
}
|
||||
// for (const key in this.formData.interests) {
|
||||
// if (this.formData.interests[key]) {
|
||||
// interests.push({ key, group: 'KUBI_INTERESSEN' });
|
||||
// }
|
||||
// }
|
||||
|
||||
return interests;
|
||||
}
|
||||
// return interests;
|
||||
// }
|
||||
|
||||
getNewsletter(): KeyValueDTOOfStringAndString | undefined {
|
||||
if (this.formData.newsletter) {
|
||||
return { key: 'kubi_newsletter', group: 'KUBI_NEWSLETTER' };
|
||||
}
|
||||
}
|
||||
// getNewsletter(): KeyValueDTOOfStringAndString | undefined {
|
||||
// if (this.formData.newsletter) {
|
||||
// return { key: 'kubi_newsletter', group: 'KUBI_NEWSLETTER' };
|
||||
// }
|
||||
// }
|
||||
|
||||
static MapCustomerInfoDtoToCustomerDto(customerInfoDto: CustomerInfoDTO): CustomerDTO {
|
||||
return {
|
||||
address: customerInfoDto.address,
|
||||
agentComment: customerInfoDto.agentComment,
|
||||
bonusCard: customerInfoDto.bonusCard,
|
||||
campaignCode: customerInfoDto.campaignCode,
|
||||
communicationDetails: customerInfoDto.communicationDetails,
|
||||
createdInBranch: customerInfoDto.createdInBranch,
|
||||
customerGroup: customerInfoDto.customerGroup,
|
||||
customerNumber: customerInfoDto.customerNumber,
|
||||
customerStatus: customerInfoDto.customerStatus,
|
||||
customerType: customerInfoDto.customerType,
|
||||
dateOfBirth: customerInfoDto.dateOfBirth,
|
||||
features: customerInfoDto.features,
|
||||
firstName: customerInfoDto.firstName,
|
||||
lastName: customerInfoDto.lastName,
|
||||
gender: customerInfoDto.gender,
|
||||
hasOnlineAccount: customerInfoDto.hasOnlineAccount,
|
||||
isGuestAccount: customerInfoDto.isGuestAccount,
|
||||
label: customerInfoDto.label,
|
||||
notificationChannels: customerInfoDto.notificationChannels,
|
||||
organisation: customerInfoDto.organisation,
|
||||
title: customerInfoDto.title,
|
||||
id: customerInfoDto.id,
|
||||
pId: customerInfoDto.pId,
|
||||
};
|
||||
}
|
||||
// static MapCustomerInfoDtoToCustomerDto(customerInfoDto: CustomerInfoDTO): CustomerDTO {
|
||||
// return {
|
||||
// address: customerInfoDto.address,
|
||||
// agentComment: customerInfoDto.agentComment,
|
||||
// bonusCard: customerInfoDto.bonusCard,
|
||||
// campaignCode: customerInfoDto.campaignCode,
|
||||
// communicationDetails: customerInfoDto.communicationDetails,
|
||||
// createdInBranch: customerInfoDto.createdInBranch,
|
||||
// customerGroup: customerInfoDto.customerGroup,
|
||||
// customerNumber: customerInfoDto.customerNumber,
|
||||
// customerStatus: customerInfoDto.customerStatus,
|
||||
// customerType: customerInfoDto.customerType,
|
||||
// dateOfBirth: customerInfoDto.dateOfBirth,
|
||||
// features: customerInfoDto.features,
|
||||
// firstName: customerInfoDto.firstName,
|
||||
// lastName: customerInfoDto.lastName,
|
||||
// gender: customerInfoDto.gender,
|
||||
// hasOnlineAccount: customerInfoDto.hasOnlineAccount,
|
||||
// isGuestAccount: customerInfoDto.isGuestAccount,
|
||||
// label: customerInfoDto.label,
|
||||
// notificationChannels: customerInfoDto.notificationChannels,
|
||||
// organisation: customerInfoDto.organisation,
|
||||
// title: customerInfoDto.title,
|
||||
// id: customerInfoDto.id,
|
||||
// pId: customerInfoDto.pId,
|
||||
// };
|
||||
// }
|
||||
|
||||
async saveCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
|
||||
const isWebshop = this._customerType === 'webshop';
|
||||
let res: Result<CustomerDTO>;
|
||||
// async saveCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
|
||||
// const isWebshop = this._customerType === 'webshop';
|
||||
// let res: Result<CustomerDTO>;
|
||||
|
||||
const { customerDto, customerInfoDto } = this.formData?._meta ?? {};
|
||||
// const { customerDto, customerInfoDto } = this.formData?._meta ?? {};
|
||||
|
||||
if (customerDto) {
|
||||
customer = { ...customerDto, ...customer };
|
||||
} else if (customerInfoDto) {
|
||||
customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
}
|
||||
// if (customerDto) {
|
||||
// customer = { ...customerDto, ...customer };
|
||||
// } else if (customerInfoDto) {
|
||||
// customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
// }
|
||||
|
||||
const p4mFeature = customer.features?.find((attr) => attr.key === 'p4mUser');
|
||||
if (p4mFeature) {
|
||||
p4mFeature.value = this.formData.p4m;
|
||||
} else {
|
||||
customer.features.push({
|
||||
key: 'p4mUser',
|
||||
value: this.formData.p4m,
|
||||
});
|
||||
}
|
||||
// const p4mFeature = customer.features?.find((attr) => attr.key === 'p4mUser');
|
||||
// if (p4mFeature) {
|
||||
// p4mFeature.value = this.formData.p4m;
|
||||
// } else {
|
||||
// customer.features.push({
|
||||
// key: 'p4mUser',
|
||||
// value: this.formData.p4m,
|
||||
// });
|
||||
// }
|
||||
|
||||
const interests = this.getInterests();
|
||||
// const interests = this.getInterests();
|
||||
|
||||
if (interests.length > 0) {
|
||||
customer.features?.push(...interests);
|
||||
// TODO: Klärung wie Interessen zukünftig gespeichert werden
|
||||
// await this._loyaltyCardService
|
||||
// .LoyaltyCardSaveInteressen({
|
||||
// customerId: res.result.id,
|
||||
// interessen: this.getInterests(),
|
||||
// })
|
||||
// .toPromise();
|
||||
}
|
||||
// if (interests.length > 0) {
|
||||
// customer.features?.push(...interests);
|
||||
// // TODO: Klärung wie Interessen zukünftig gespeichert werden
|
||||
// // await this._loyaltyCardService
|
||||
// // .LoyaltyCardSaveInteressen({
|
||||
// // customerId: res.result.id,
|
||||
// // interessen: this.getInterests(),
|
||||
// // })
|
||||
// // .toPromise();
|
||||
// }
|
||||
|
||||
const newsletter = this.getNewsletter();
|
||||
// const newsletter = this.getNewsletter();
|
||||
|
||||
if (newsletter) {
|
||||
customer.features.push(newsletter);
|
||||
} else {
|
||||
customer.features = customer.features.filter(
|
||||
(feature) => feature.key !== 'kubi_newsletter' && feature.group !== 'KUBI_NEWSLETTER',
|
||||
);
|
||||
}
|
||||
// if (newsletter) {
|
||||
// customer.features.push(newsletter);
|
||||
// } else {
|
||||
// customer.features = customer.features.filter(
|
||||
// (feature) => feature.key !== 'kubi_newsletter' && feature.group !== 'KUBI_NEWSLETTER',
|
||||
// );
|
||||
// }
|
||||
|
||||
if (isWebshop) {
|
||||
if (customer.id > 0) {
|
||||
if (this.formData?._meta?.hasLocalityCard) {
|
||||
res = await this.customerService.updateStoreP4MToWebshopP4M(customer);
|
||||
} else {
|
||||
res = await this.customerService.updateToP4MOnlineCustomer(customer);
|
||||
}
|
||||
} else {
|
||||
res = await this.customerService.createOnlineCustomer(customer).toPromise();
|
||||
}
|
||||
} else {
|
||||
res = await this.customerService.createStoreCustomer(customer).toPromise();
|
||||
}
|
||||
// if (isWebshop) {
|
||||
// if (customer.id > 0) {
|
||||
// if (this.formData?._meta?.hasLocalityCard) {
|
||||
// res = await this.customerService.updateStoreP4MToWebshopP4M(customer);
|
||||
// } else {
|
||||
// res = await this.customerService.updateToP4MOnlineCustomer(customer);
|
||||
// }
|
||||
// } else {
|
||||
// res = await this.customerService.createOnlineCustomer(customer).toPromise();
|
||||
// }
|
||||
// } else {
|
||||
// res = await this.customerService.createStoreCustomer(customer).toPromise();
|
||||
// }
|
||||
|
||||
return res.result;
|
||||
}
|
||||
}
|
||||
// return res.result;
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
// import { NgModule } from '@angular/core';
|
||||
// import { CommonModule } from '@angular/common';
|
||||
|
||||
import { CreateP4MCustomerComponent } from './create-p4m-customer.component';
|
||||
import {
|
||||
AddressFormBlockModule,
|
||||
BirthDateFormBlockModule,
|
||||
InterestsFormBlockModule,
|
||||
NameFormBlockModule,
|
||||
OrganisationFormBlockModule,
|
||||
P4mNumberFormBlockModule,
|
||||
NewsletterFormBlockModule,
|
||||
DeviatingAddressFormBlockComponentModule,
|
||||
AcceptAGBFormBlockModule,
|
||||
EmailFormBlockModule,
|
||||
PhoneNumbersFormBlockModule,
|
||||
} from '../../components/form-blocks';
|
||||
import { CustomerTypeSelectorModule } from '../../components/customer-type-selector';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
import { UiIconModule } from '@ui/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
// import { CreateP4MCustomerComponent } from './create-p4m-customer.component';
|
||||
// import {
|
||||
// AddressFormBlockModule,
|
||||
// BirthDateFormBlockModule,
|
||||
// InterestsFormBlockModule,
|
||||
// NameFormBlockModule,
|
||||
// OrganisationFormBlockModule,
|
||||
// P4mNumberFormBlockModule,
|
||||
// NewsletterFormBlockModule,
|
||||
// DeviatingAddressFormBlockComponentModule,
|
||||
// AcceptAGBFormBlockModule,
|
||||
// EmailFormBlockModule,
|
||||
// PhoneNumbersFormBlockModule,
|
||||
// } from '../../components/form-blocks';
|
||||
// import { CustomerTypeSelectorModule } from '../../components/customer-type-selector';
|
||||
// import { UiSpinnerModule } from '@ui/spinner';
|
||||
// import { UiIconModule } from '@ui/icon';
|
||||
// import { RouterModule } from '@angular/router';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
CustomerTypeSelectorModule,
|
||||
AddressFormBlockModule,
|
||||
BirthDateFormBlockModule,
|
||||
InterestsFormBlockModule,
|
||||
NameFormBlockModule,
|
||||
OrganisationFormBlockModule,
|
||||
P4mNumberFormBlockModule,
|
||||
NewsletterFormBlockModule,
|
||||
DeviatingAddressFormBlockComponentModule,
|
||||
AcceptAGBFormBlockModule,
|
||||
EmailFormBlockModule,
|
||||
PhoneNumbersFormBlockModule,
|
||||
UiSpinnerModule,
|
||||
UiIconModule,
|
||||
RouterModule,
|
||||
],
|
||||
exports: [CreateP4MCustomerComponent],
|
||||
declarations: [CreateP4MCustomerComponent],
|
||||
})
|
||||
export class CreateP4MCustomerModule {}
|
||||
// @NgModule({
|
||||
// imports: [
|
||||
// CommonModule,
|
||||
// CustomerTypeSelectorModule,
|
||||
// AddressFormBlockModule,
|
||||
// BirthDateFormBlockModule,
|
||||
// InterestsFormBlockModule,
|
||||
// NameFormBlockModule,
|
||||
// OrganisationFormBlockModule,
|
||||
// P4mNumberFormBlockModule,
|
||||
// NewsletterFormBlockModule,
|
||||
// DeviatingAddressFormBlockComponentModule,
|
||||
// AcceptAGBFormBlockModule,
|
||||
// EmailFormBlockModule,
|
||||
// PhoneNumbersFormBlockModule,
|
||||
// UiSpinnerModule,
|
||||
// UiIconModule,
|
||||
// RouterModule,
|
||||
// ],
|
||||
// exports: [CreateP4MCustomerComponent],
|
||||
// declarations: [CreateP4MCustomerComponent],
|
||||
// })
|
||||
// export class CreateP4MCustomerModule {}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './create-p4m-customer.component';
|
||||
export * from './create-p4m-customer.module';
|
||||
// export * from './create-p4m-customer.component';
|
||||
// export * from './create-p4m-customer.module';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, ChangeDetectionStrategy, ViewChild } from '@angular/core';
|
||||
import { ValidatorFn, Validators } from '@angular/forms';
|
||||
import { CustomerDTO } from '@generated/swagger/crm-api';
|
||||
import { CustomerDTO, CustomerInfoDTO } from '@generated/swagger/crm-api';
|
||||
import { map } from 'rxjs/operators';
|
||||
import {
|
||||
AddressFormBlockComponent,
|
||||
@@ -10,13 +10,16 @@ import {
|
||||
import { NameFormBlockData } from '../../components/form-blocks/name/name-form-block-data';
|
||||
import { validateEmail } from '../../validators/email-validator';
|
||||
import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
import { CreateP4MCustomerComponent } from '../create-p4m-customer';
|
||||
// import { CreateP4MCustomerComponent } from '../create-p4m-customer';
|
||||
import { zipCodeValidator } from '../../validators/zip-code-validator';
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-webshop-customer',
|
||||
templateUrl: 'create-webshop-customer.component.html',
|
||||
styleUrls: ['../create-customer.scss', 'create-webshop-customer.component.scss'],
|
||||
styleUrls: [
|
||||
'../create-customer.scss',
|
||||
'create-webshop-customer.component.scss',
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
@@ -26,7 +29,11 @@ export class CreateWebshopCustomerComponent extends AbstractCreateCustomer {
|
||||
validateAddress = true;
|
||||
validateShippingAddress = true;
|
||||
|
||||
nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
nameRequiredMarks: (keyof NameFormBlockData)[] = [
|
||||
'gender',
|
||||
'firstName',
|
||||
'lastName',
|
||||
];
|
||||
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
@@ -35,7 +42,13 @@ export class CreateWebshopCustomerComponent extends AbstractCreateCustomer {
|
||||
title: [],
|
||||
};
|
||||
|
||||
addressRequiredMarks: (keyof AddressFormBlockData)[] = ['street', 'streetNumber', 'zipCode', 'city', 'country'];
|
||||
addressRequiredMarks: (keyof AddressFormBlockData)[] = [
|
||||
'street',
|
||||
'streetNumber',
|
||||
'zipCode',
|
||||
'city',
|
||||
'country',
|
||||
];
|
||||
|
||||
addressValidators: Record<string, ValidatorFn[]> = {
|
||||
street: [Validators.required],
|
||||
@@ -68,7 +81,11 @@ export class CreateWebshopCustomerComponent extends AbstractCreateCustomer {
|
||||
if (customerDto) {
|
||||
customer = { ...customerDto, ...customer };
|
||||
} else if (customerInfoDto) {
|
||||
customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
customer = {
|
||||
// ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto),
|
||||
...this.mapCustomerInfoDtoToCustomerDto(customerInfoDto),
|
||||
...customer,
|
||||
};
|
||||
}
|
||||
|
||||
const res = await this.customerService.updateToOnlineCustomer(customer);
|
||||
@@ -80,4 +97,34 @@ export class CreateWebshopCustomerComponent extends AbstractCreateCustomer {
|
||||
.toPromise();
|
||||
}
|
||||
}
|
||||
|
||||
mapCustomerInfoDtoToCustomerDto(
|
||||
customerInfoDto: CustomerInfoDTO,
|
||||
): CustomerDTO {
|
||||
return {
|
||||
address: customerInfoDto.address,
|
||||
agentComment: customerInfoDto.agentComment,
|
||||
bonusCard: customerInfoDto.bonusCard,
|
||||
campaignCode: customerInfoDto.campaignCode,
|
||||
communicationDetails: customerInfoDto.communicationDetails,
|
||||
createdInBranch: customerInfoDto.createdInBranch,
|
||||
customerGroup: customerInfoDto.customerGroup,
|
||||
customerNumber: customerInfoDto.customerNumber,
|
||||
customerStatus: customerInfoDto.customerStatus,
|
||||
customerType: customerInfoDto.customerType,
|
||||
dateOfBirth: customerInfoDto.dateOfBirth,
|
||||
features: customerInfoDto.features,
|
||||
firstName: customerInfoDto.firstName,
|
||||
lastName: customerInfoDto.lastName,
|
||||
gender: customerInfoDto.gender,
|
||||
hasOnlineAccount: customerInfoDto.hasOnlineAccount,
|
||||
isGuestAccount: customerInfoDto.isGuestAccount,
|
||||
label: customerInfoDto.label,
|
||||
notificationChannels: customerInfoDto.notificationChannels,
|
||||
organisation: customerInfoDto.organisation,
|
||||
title: customerInfoDto.title,
|
||||
id: customerInfoDto.id,
|
||||
pId: customerInfoDto.pId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CustomerDTO, Gender } from '@generated/swagger/crm-api';
|
||||
|
||||
export interface CreateCustomerQueryParams {
|
||||
p4mNumber?: string;
|
||||
// p4mNumber?: string;
|
||||
customerId?: number;
|
||||
gender?: Gender;
|
||||
title?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export * from './create-b2b-customer';
|
||||
export * from './create-guest-customer';
|
||||
export * from './create-p4m-customer';
|
||||
// export * from './create-p4m-customer';
|
||||
export * from './create-store-customer';
|
||||
export * from './create-webshop-customer';
|
||||
export * from './defs';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@if (formData$ | async; as data) {
|
||||
<!-- @if (formData$ | async; as data) {
|
||||
<form (keydown.enter)="$event.preventDefault()">
|
||||
<h1 class="title flex flex-row items-center justify-center">Kundenkartendaten erfasen</h1>
|
||||
<p class="description">Bitte erfassen Sie die Kundenkarte</p>
|
||||
@@ -106,4 +106,4 @@
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
} -->
|
||||
|
||||
@@ -1,156 +1,156 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
import { AsyncValidatorFn, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { Result } from '@domain/defs';
|
||||
import { CustomerDTO, KeyValueDTOOfStringAndString, PayerDTO } from '@generated/swagger/crm-api';
|
||||
import { AddressFormBlockData } from '../../components/form-blocks';
|
||||
import { NameFormBlockData } from '../../components/form-blocks/name/name-form-block-data';
|
||||
import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
import { CreateP4MCustomerComponent } from '../create-p4m-customer';
|
||||
// import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||
// import { AsyncValidatorFn, ValidatorFn, Validators } from '@angular/forms';
|
||||
// import { Result } from '@domain/defs';
|
||||
// import { CustomerDTO, KeyValueDTOOfStringAndString, PayerDTO } from '@generated/swagger/crm-api';
|
||||
// import { AddressFormBlockData } from '../../components/form-blocks';
|
||||
// import { NameFormBlockData } from '../../components/form-blocks/name/name-form-block-data';
|
||||
// import { AbstractCreateCustomer } from '../abstract-create-customer';
|
||||
// import { CreateP4MCustomerComponent } from '../create-p4m-customer';
|
||||
|
||||
@Component({
|
||||
selector: 'page-update-p4m-webshop-customer',
|
||||
templateUrl: 'update-p4m-webshop-customer.component.html',
|
||||
styleUrls: ['../create-customer.scss', 'update-p4m-webshop-customer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
export class UpdateP4MWebshopCustomerComponent extends AbstractCreateCustomer implements OnInit {
|
||||
customerType = 'webshop-p4m/update';
|
||||
// @Component({
|
||||
// selector: 'page-update-p4m-webshop-customer',
|
||||
// templateUrl: 'update-p4m-webshop-customer.component.html',
|
||||
// styleUrls: ['../create-customer.scss', 'update-p4m-webshop-customer.component.scss'],
|
||||
// changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
// standalone: false,
|
||||
// })
|
||||
// export class UpdateP4MWebshopCustomerComponent extends AbstractCreateCustomer implements OnInit {
|
||||
// customerType = 'webshop-p4m/update';
|
||||
|
||||
validateAddress = true;
|
||||
// validateAddress = true;
|
||||
|
||||
validateShippingAddress = true;
|
||||
// validateShippingAddress = true;
|
||||
|
||||
agbValidatorFns = [Validators.requiredTrue];
|
||||
// agbValidatorFns = [Validators.requiredTrue];
|
||||
|
||||
birthDateValidatorFns = [Validators.required, this.minBirthDateValidator()];
|
||||
// birthDateValidatorFns = [Validators.required, this.minBirthDateValidator()];
|
||||
|
||||
nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
// nameRequiredMarks: (keyof NameFormBlockData)[] = ['gender', 'firstName', 'lastName'];
|
||||
|
||||
nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
firstName: [Validators.required],
|
||||
lastName: [Validators.required],
|
||||
gender: [Validators.required],
|
||||
title: [],
|
||||
};
|
||||
// nameValidationFns: Record<keyof NameFormBlockData, ValidatorFn[]> = {
|
||||
// firstName: [Validators.required],
|
||||
// lastName: [Validators.required],
|
||||
// gender: [Validators.required],
|
||||
// title: [],
|
||||
// };
|
||||
|
||||
addressRequiredMarks: (keyof AddressFormBlockData)[] = ['street', 'streetNumber', 'zipCode', 'city', 'country'];
|
||||
// addressRequiredMarks: (keyof AddressFormBlockData)[] = ['street', 'streetNumber', 'zipCode', 'city', 'country'];
|
||||
|
||||
addressValidatorFns: Record<string, ValidatorFn[]> = {
|
||||
street: [Validators.required],
|
||||
streetNumber: [Validators.required],
|
||||
zipCode: [Validators.required],
|
||||
city: [Validators.required],
|
||||
country: [Validators.required],
|
||||
};
|
||||
// addressValidatorFns: Record<string, ValidatorFn[]> = {
|
||||
// street: [Validators.required],
|
||||
// streetNumber: [Validators.required],
|
||||
// zipCode: [Validators.required],
|
||||
// city: [Validators.required],
|
||||
// country: [Validators.required],
|
||||
// };
|
||||
|
||||
asyncLoyaltyCardValidatorFn: AsyncValidatorFn[] = [this.checkLoyalityCardValidator];
|
||||
// asyncLoyaltyCardValidatorFn: AsyncValidatorFn[] = [this.checkLoyalityCardValidator];
|
||||
|
||||
get billingAddress(): PayerDTO | undefined {
|
||||
const payers = this.formData?._meta?.customerDto?.payers;
|
||||
// get billingAddress(): PayerDTO | undefined {
|
||||
// const payers = this.formData?._meta?.customerDto?.payers;
|
||||
|
||||
if (!payers || payers.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
// if (!payers || payers.length === 0) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
// the default payer is the payer with the latest isDefault(Date) value
|
||||
const defaultPayer = payers.reduce((prev, curr) =>
|
||||
new Date(prev.isDefault) > new Date(curr.isDefault) ? prev : curr,
|
||||
);
|
||||
// // the default payer is the payer with the latest isDefault(Date) value
|
||||
// const defaultPayer = payers.reduce((prev, curr) =>
|
||||
// new Date(prev.isDefault) > new Date(curr.isDefault) ? prev : curr,
|
||||
// );
|
||||
|
||||
return defaultPayer.payer.data;
|
||||
}
|
||||
// return defaultPayer.payer.data;
|
||||
// }
|
||||
|
||||
get shippingAddress() {
|
||||
const shippingAddresses = this.formData?._meta?.customerDto?.shippingAddresses;
|
||||
// get shippingAddress() {
|
||||
// const shippingAddresses = this.formData?._meta?.customerDto?.shippingAddresses;
|
||||
|
||||
if (!shippingAddresses || shippingAddresses.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
// if (!shippingAddresses || shippingAddresses.length === 0) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
// the default shipping address is the shipping address with the latest isDefault(Date) value
|
||||
const defaultShippingAddress = shippingAddresses.reduce((prev, curr) =>
|
||||
new Date(prev.data.isDefault) > new Date(curr.data.isDefault) ? prev : curr,
|
||||
);
|
||||
// // the default shipping address is the shipping address with the latest isDefault(Date) value
|
||||
// const defaultShippingAddress = shippingAddresses.reduce((prev, curr) =>
|
||||
// new Date(prev.data.isDefault) > new Date(curr.data.isDefault) ? prev : curr,
|
||||
// );
|
||||
|
||||
return defaultShippingAddress.data;
|
||||
}
|
||||
// return defaultShippingAddress.data;
|
||||
// }
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
}
|
||||
// ngOnInit() {
|
||||
// super.ngOnInit();
|
||||
// }
|
||||
|
||||
getInterests(): KeyValueDTOOfStringAndString[] {
|
||||
const interests: KeyValueDTOOfStringAndString[] = [];
|
||||
// getInterests(): KeyValueDTOOfStringAndString[] {
|
||||
// const interests: KeyValueDTOOfStringAndString[] = [];
|
||||
|
||||
for (const key in this.formData.interests) {
|
||||
if (this.formData.interests[key]) {
|
||||
interests.push({ key, group: 'KUBI_INTERESSEN' });
|
||||
}
|
||||
}
|
||||
// for (const key in this.formData.interests) {
|
||||
// if (this.formData.interests[key]) {
|
||||
// interests.push({ key, group: 'KUBI_INTERESSEN' });
|
||||
// }
|
||||
// }
|
||||
|
||||
return interests;
|
||||
}
|
||||
// return interests;
|
||||
// }
|
||||
|
||||
getNewsletter(): KeyValueDTOOfStringAndString | undefined {
|
||||
if (this.formData.newsletter) {
|
||||
return { key: 'kubi_newsletter', group: 'KUBI_NEWSLETTER' };
|
||||
}
|
||||
}
|
||||
// getNewsletter(): KeyValueDTOOfStringAndString | undefined {
|
||||
// if (this.formData.newsletter) {
|
||||
// return { key: 'kubi_newsletter', group: 'KUBI_NEWSLETTER' };
|
||||
// }
|
||||
// }
|
||||
|
||||
async saveCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
|
||||
let res: Result<CustomerDTO>;
|
||||
// async saveCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
|
||||
// let res: Result<CustomerDTO>;
|
||||
|
||||
const { customerDto, customerInfoDto } = this.formData?._meta ?? {};
|
||||
// const { customerDto, customerInfoDto } = this.formData?._meta ?? {};
|
||||
|
||||
if (customerDto) {
|
||||
customer = { ...customerDto, shippingAddresses: [], payers: [], ...customer };
|
||||
// if (customerDto) {
|
||||
// customer = { ...customerDto, shippingAddresses: [], payers: [], ...customer };
|
||||
|
||||
if (customerDto.shippingAddresses?.length) {
|
||||
customer.shippingAddresses.unshift(...customerDto.shippingAddresses);
|
||||
}
|
||||
if (customerDto.payers?.length) {
|
||||
customer.payers.unshift(...customerDto.payers);
|
||||
}
|
||||
} else if (customerInfoDto) {
|
||||
customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
}
|
||||
// if (customerDto.shippingAddresses?.length) {
|
||||
// customer.shippingAddresses.unshift(...customerDto.shippingAddresses);
|
||||
// }
|
||||
// if (customerDto.payers?.length) {
|
||||
// customer.payers.unshift(...customerDto.payers);
|
||||
// }
|
||||
// } else if (customerInfoDto) {
|
||||
// customer = { ...CreateP4MCustomerComponent.MapCustomerInfoDtoToCustomerDto(customerInfoDto), ...customer };
|
||||
// }
|
||||
|
||||
const p4mFeature = customer.features?.find((attr) => attr.key === 'p4mUser');
|
||||
if (p4mFeature) {
|
||||
p4mFeature.value = this.formData.p4m;
|
||||
} else {
|
||||
customer.features.push({
|
||||
key: 'p4mUser',
|
||||
value: this.formData.p4m,
|
||||
});
|
||||
}
|
||||
// const p4mFeature = customer.features?.find((attr) => attr.key === 'p4mUser');
|
||||
// if (p4mFeature) {
|
||||
// p4mFeature.value = this.formData.p4m;
|
||||
// } else {
|
||||
// customer.features.push({
|
||||
// key: 'p4mUser',
|
||||
// value: this.formData.p4m,
|
||||
// });
|
||||
// }
|
||||
|
||||
const interests = this.getInterests();
|
||||
// const interests = this.getInterests();
|
||||
|
||||
if (interests.length > 0) {
|
||||
customer.features?.push(...interests);
|
||||
// TODO: Klärung wie Interessen zukünftig gespeichert werden
|
||||
// await this._loyaltyCardService
|
||||
// .LoyaltyCardSaveInteressen({
|
||||
// customerId: res.result.id,
|
||||
// interessen: this.getInterests(),
|
||||
// })
|
||||
// .toPromise();
|
||||
}
|
||||
// if (interests.length > 0) {
|
||||
// customer.features?.push(...interests);
|
||||
// // TODO: Klärung wie Interessen zukünftig gespeichert werden
|
||||
// // await this._loyaltyCardService
|
||||
// // .LoyaltyCardSaveInteressen({
|
||||
// // customerId: res.result.id,
|
||||
// // interessen: this.getInterests(),
|
||||
// // })
|
||||
// // .toPromise();
|
||||
// }
|
||||
|
||||
const newsletter = this.getNewsletter();
|
||||
// const newsletter = this.getNewsletter();
|
||||
|
||||
if (newsletter) {
|
||||
customer.features.push(newsletter);
|
||||
} else {
|
||||
customer.features = customer.features.filter(
|
||||
(feature) => feature.key !== 'kubi_newsletter' && feature.group !== 'KUBI_NEWSLETTER',
|
||||
);
|
||||
}
|
||||
// if (newsletter) {
|
||||
// customer.features.push(newsletter);
|
||||
// } else {
|
||||
// customer.features = customer.features.filter(
|
||||
// (feature) => feature.key !== 'kubi_newsletter' && feature.group !== 'KUBI_NEWSLETTER',
|
||||
// );
|
||||
// }
|
||||
|
||||
res = await this.customerService.updateToP4MOnlineCustomer(customer);
|
||||
// res = await this.customerService.updateToP4MOnlineCustomer(customer);
|
||||
|
||||
return res.result;
|
||||
}
|
||||
}
|
||||
// return res.result;
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
// import { NgModule } from '@angular/core';
|
||||
// import { CommonModule } from '@angular/common';
|
||||
|
||||
import { UpdateP4MWebshopCustomerComponent } from './update-p4m-webshop-customer.component';
|
||||
// import { UpdateP4MWebshopCustomerComponent } from './update-p4m-webshop-customer.component';
|
||||
|
||||
import {
|
||||
AddressFormBlockModule,
|
||||
BirthDateFormBlockModule,
|
||||
InterestsFormBlockModule,
|
||||
NameFormBlockModule,
|
||||
OrganisationFormBlockModule,
|
||||
P4mNumberFormBlockModule,
|
||||
NewsletterFormBlockModule,
|
||||
DeviatingAddressFormBlockComponentModule,
|
||||
AcceptAGBFormBlockModule,
|
||||
EmailFormBlockModule,
|
||||
PhoneNumbersFormBlockModule,
|
||||
} from '../../components/form-blocks';
|
||||
import { UiFormControlModule } from '@ui/form-control';
|
||||
import { UiInputModule } from '@ui/input';
|
||||
import { CustomerPipesModule } from '@shared/pipes/customer';
|
||||
import { CustomerTypeSelectorModule } from '../../components/customer-type-selector';
|
||||
import { UiSpinnerModule } from '@ui/spinner';
|
||||
// import {
|
||||
// AddressFormBlockModule,
|
||||
// BirthDateFormBlockModule,
|
||||
// InterestsFormBlockModule,
|
||||
// NameFormBlockModule,
|
||||
// OrganisationFormBlockModule,
|
||||
// P4mNumberFormBlockModule,
|
||||
// NewsletterFormBlockModule,
|
||||
// DeviatingAddressFormBlockComponentModule,
|
||||
// AcceptAGBFormBlockModule,
|
||||
// EmailFormBlockModule,
|
||||
// PhoneNumbersFormBlockModule,
|
||||
// } from '../../components/form-blocks';
|
||||
// import { UiFormControlModule } from '@ui/form-control';
|
||||
// import { UiInputModule } from '@ui/input';
|
||||
// import { CustomerPipesModule } from '@shared/pipes/customer';
|
||||
// import { CustomerTypeSelectorModule } from '../../components/customer-type-selector';
|
||||
// import { UiSpinnerModule } from '@ui/spinner';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
CustomerTypeSelectorModule,
|
||||
AddressFormBlockModule,
|
||||
BirthDateFormBlockModule,
|
||||
InterestsFormBlockModule,
|
||||
NameFormBlockModule,
|
||||
OrganisationFormBlockModule,
|
||||
P4mNumberFormBlockModule,
|
||||
NewsletterFormBlockModule,
|
||||
DeviatingAddressFormBlockComponentModule,
|
||||
AcceptAGBFormBlockModule,
|
||||
EmailFormBlockModule,
|
||||
PhoneNumbersFormBlockModule,
|
||||
UiFormControlModule,
|
||||
UiInputModule,
|
||||
CustomerPipesModule,
|
||||
UiSpinnerModule,
|
||||
],
|
||||
exports: [UpdateP4MWebshopCustomerComponent],
|
||||
declarations: [UpdateP4MWebshopCustomerComponent],
|
||||
})
|
||||
export class UpdateP4MWebshopCustomerModule {}
|
||||
// @NgModule({
|
||||
// imports: [
|
||||
// CommonModule,
|
||||
// CustomerTypeSelectorModule,
|
||||
// AddressFormBlockModule,
|
||||
// BirthDateFormBlockModule,
|
||||
// InterestsFormBlockModule,
|
||||
// NameFormBlockModule,
|
||||
// OrganisationFormBlockModule,
|
||||
// P4mNumberFormBlockModule,
|
||||
// NewsletterFormBlockModule,
|
||||
// DeviatingAddressFormBlockComponentModule,
|
||||
// AcceptAGBFormBlockModule,
|
||||
// EmailFormBlockModule,
|
||||
// PhoneNumbersFormBlockModule,
|
||||
// UiFormControlModule,
|
||||
// UiInputModule,
|
||||
// CustomerPipesModule,
|
||||
// UiSpinnerModule,
|
||||
// ],
|
||||
// exports: [UpdateP4MWebshopCustomerComponent],
|
||||
// declarations: [UpdateP4MWebshopCustomerComponent],
|
||||
// })
|
||||
// export class UpdateP4MWebshopCustomerModule {}
|
||||
|
||||
@@ -1,15 +1,33 @@
|
||||
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, inject, effect, untracked } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
ChangeDetectionStrategy,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
inject,
|
||||
effect,
|
||||
untracked,
|
||||
} from '@angular/core';
|
||||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||
import { BehaviorSubject, Subject, Subscription, fromEvent } from 'rxjs';
|
||||
import {
|
||||
BehaviorSubject,
|
||||
Subject,
|
||||
Subscription,
|
||||
firstValueFrom,
|
||||
fromEvent,
|
||||
} from 'rxjs';
|
||||
import { CustomerSearchStore } from './store/customer-search.store';
|
||||
import { provideComponentStore } from '@ngrx/component-store';
|
||||
import { Breadcrumb, BreadcrumbService } from '@core/breadcrumb';
|
||||
import { delay, filter, first, switchMap, takeUntil } from 'rxjs/operators';
|
||||
import { CustomerCreateNavigation, CustomerSearchNavigation } from '@shared/services/navigation';
|
||||
import {
|
||||
CustomerCreateNavigation,
|
||||
CustomerSearchNavigation,
|
||||
} from '@shared/services/navigation';
|
||||
import { CustomerSearchMainAutocompleteProvider } from './providers/customer-search-main-autocomplete.provider';
|
||||
import { FilterAutocompleteProvider } from '@shared/components/filter';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { provideCancelSearchSubject } from '@shared/services/cancel-subject';
|
||||
import { injectFeedbackErrorDialog } from '@isa/ui/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'page-customer-search',
|
||||
@@ -28,6 +46,7 @@ import { provideCancelSearchSubject } from '@shared/services/cancel-subject';
|
||||
standalone: false,
|
||||
})
|
||||
export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
#errorFeedbackDialog = injectFeedbackErrorDialog();
|
||||
private _store = inject(CustomerSearchStore);
|
||||
private _activatedRoute = inject(ActivatedRoute);
|
||||
private _router = inject(Router);
|
||||
@@ -37,7 +56,11 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
|
||||
private searchStore = inject(CustomerSearchStore);
|
||||
|
||||
keyEscPressed = toSignal(fromEvent(document, 'keydown').pipe(filter((e: KeyboardEvent) => e.key === 'Escape')));
|
||||
keyEscPressed = toSignal(
|
||||
fromEvent(document, 'keydown').pipe(
|
||||
filter((e: KeyboardEvent) => e.key === 'Escape'),
|
||||
),
|
||||
);
|
||||
|
||||
get breadcrumb() {
|
||||
let breadcrumb: string;
|
||||
@@ -53,7 +76,9 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
|
||||
private _breadcrumbs$ = this._store.processId$.pipe(
|
||||
filter((id) => !!id),
|
||||
switchMap((id) => this._breadcrumbService.getBreadcrumbsByKeyAndTag$(id, 'customer')),
|
||||
switchMap((id) =>
|
||||
this._breadcrumbService.getBreadcrumbsByKeyAndTag$(id, 'customer'),
|
||||
),
|
||||
);
|
||||
|
||||
side$ = new BehaviorSubject<string | undefined>(undefined);
|
||||
@@ -97,53 +122,77 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
this.checkDetailsBreadcrumb();
|
||||
});
|
||||
|
||||
this._eventsSubscription = this._router.events.pipe(takeUntil(this._onDestroy$)).subscribe((event) => {
|
||||
if (event instanceof NavigationEnd) {
|
||||
this.checkAndUpdateProcessId();
|
||||
this.checkAndUpdateSide();
|
||||
this.checkAndUpdateCustomerId();
|
||||
this.checkBreadcrumbs();
|
||||
}
|
||||
});
|
||||
|
||||
this._store.customerListResponse$
|
||||
this._eventsSubscription = this._router.events
|
||||
.pipe(takeUntil(this._onDestroy$))
|
||||
.subscribe(async ([response, filter, processId, restored, skipNavigation]) => {
|
||||
if (this._store.processId === processId) {
|
||||
if (skipNavigation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.hits === 1) {
|
||||
// Navigate to details page
|
||||
const customer = response.result[0];
|
||||
|
||||
if (customer.id < 0) {
|
||||
// navigate to create customer
|
||||
const route = this._createNavigation.upgradeCustomerRoute({ processId, customerInfo: customer });
|
||||
await this._router.navigate(route.path, { queryParams: route.queryParams });
|
||||
return;
|
||||
} else {
|
||||
const route = this._navigation.detailsRoute({ processId, customerId: customer.id });
|
||||
await this._router.navigate(route.path, { queryParams: filter.getQueryParams() });
|
||||
}
|
||||
} else if (response.hits > 1) {
|
||||
const route = this._navigation.listRoute({ processId, filter });
|
||||
|
||||
if (
|
||||
(['details'].includes(this.breadcrumb) &&
|
||||
response?.result?.some((c) => c.id === this._store.customerId)) ||
|
||||
restored
|
||||
) {
|
||||
await this._router.navigate([], { queryParams: route.queryParams });
|
||||
} else {
|
||||
await this._router.navigate(route.path, { queryParams: route.queryParams });
|
||||
}
|
||||
}
|
||||
|
||||
.subscribe((event) => {
|
||||
if (event instanceof NavigationEnd) {
|
||||
this.checkAndUpdateProcessId();
|
||||
this.checkAndUpdateSide();
|
||||
this.checkAndUpdateCustomerId();
|
||||
this.checkBreadcrumbs();
|
||||
}
|
||||
});
|
||||
|
||||
this._store.customerListResponse$
|
||||
.pipe(takeUntil(this._onDestroy$))
|
||||
.subscribe(
|
||||
async ([response, filter, processId, restored, skipNavigation]) => {
|
||||
if (this._store.processId === processId) {
|
||||
if (skipNavigation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.hits === 1) {
|
||||
// Navigate to details page
|
||||
const customer = response.result[0];
|
||||
|
||||
if (customer.id < 0) {
|
||||
// #5375 - Zusätzlich soll bei Kunden bei denen ein Upgrade möglich ist ein Dialog angezeigt werden, dass Kundenneuanlage mit Kundenkarte nicht möglich ist
|
||||
await firstValueFrom(
|
||||
this.#errorFeedbackDialog({
|
||||
data: {
|
||||
errorMessage:
|
||||
'Kundenneuanlage mit Kundenkarte nicht möglich',
|
||||
},
|
||||
}).closed,
|
||||
);
|
||||
// navigate to create customer
|
||||
// const route = this._createNavigation.upgradeCustomerRoute({ processId, customerInfo: customer });
|
||||
// await this._router.navigate(route.path, { queryParams: route.queryParams });
|
||||
return;
|
||||
} else {
|
||||
const route = this._navigation.detailsRoute({
|
||||
processId,
|
||||
customerId: customer.id,
|
||||
});
|
||||
await this._router.navigate(route.path, {
|
||||
queryParams: filter.getQueryParams(),
|
||||
});
|
||||
}
|
||||
} else if (response.hits > 1) {
|
||||
const route = this._navigation.listRoute({ processId, filter });
|
||||
|
||||
if (
|
||||
(['details'].includes(this.breadcrumb) &&
|
||||
response?.result?.some(
|
||||
(c) => c.id === this._store.customerId,
|
||||
)) ||
|
||||
restored
|
||||
) {
|
||||
await this._router.navigate([], {
|
||||
queryParams: route.queryParams,
|
||||
});
|
||||
} else {
|
||||
await this._router.navigate(route.path, {
|
||||
queryParams: route.queryParams,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.checkBreadcrumbs();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@@ -169,7 +218,11 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
this._store.setProcessId(processId);
|
||||
this._store.reset(this._activatedRoute.snapshot.queryParams);
|
||||
if (!['main', 'filter'].some((s) => s === this.breadcrumb)) {
|
||||
const skipNavigation = ['orders', 'order-details', 'order-details-history'].includes(this.breadcrumb);
|
||||
const skipNavigation = [
|
||||
'orders',
|
||||
'order-details',
|
||||
'order-details-history',
|
||||
].includes(this.breadcrumb);
|
||||
this._store.search({ skipNavigation });
|
||||
}
|
||||
}
|
||||
@@ -229,7 +282,9 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
const mainBreadcrumb = await this.getMainBreadcrumb();
|
||||
|
||||
if (!mainBreadcrumb) {
|
||||
const navigation = this._navigation.defaultRoute({ processId: this._store.processId });
|
||||
const navigation = this._navigation.defaultRoute({
|
||||
processId: this._store.processId,
|
||||
});
|
||||
const breadcrumb: Breadcrumb = {
|
||||
key: this._store.processId,
|
||||
tags: ['customer', 'search', 'main'],
|
||||
@@ -242,14 +297,19 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
this._breadcrumbService.addBreadcrumb(breadcrumb);
|
||||
} else {
|
||||
this._breadcrumbService.patchBreadcrumb(mainBreadcrumb.id, {
|
||||
params: { ...this.snapshot.queryParams, ...(mainBreadcrumb.params ?? {}) },
|
||||
params: {
|
||||
...this.snapshot.queryParams,
|
||||
...(mainBreadcrumb.params ?? {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async getCreateCustomerBreadcrumb(): Promise<Breadcrumb | undefined> {
|
||||
const breadcrumbs = await this.getBreadcrumbs();
|
||||
return breadcrumbs.find((b) => b.tags.includes('create') && b.tags.includes('customer'));
|
||||
return breadcrumbs.find(
|
||||
(b) => b.tags.includes('create') && b.tags.includes('customer'),
|
||||
);
|
||||
}
|
||||
|
||||
async checkCreateCustomerBreadcrumb() {
|
||||
@@ -262,7 +322,9 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
|
||||
async getSearchBreadcrumb(): Promise<Breadcrumb | undefined> {
|
||||
const breadcrumbs = await this.getBreadcrumbs();
|
||||
return breadcrumbs.find((b) => b.tags.includes('list') && b.tags.includes('search'));
|
||||
return breadcrumbs.find(
|
||||
(b) => b.tags.includes('list') && b.tags.includes('search'),
|
||||
);
|
||||
}
|
||||
|
||||
async checkSearchBreadcrumb() {
|
||||
@@ -288,7 +350,9 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
const name = this._store.queryParams?.main_qs || 'Suche';
|
||||
|
||||
if (!searchBreadcrumb) {
|
||||
const navigation = this._navigation.listRoute({ processId: this._store.processId });
|
||||
const navigation = this._navigation.listRoute({
|
||||
processId: this._store.processId,
|
||||
});
|
||||
const breadcrumb: Breadcrumb = {
|
||||
key: this._store.processId,
|
||||
tags: ['customer', 'search', 'list'],
|
||||
@@ -300,7 +364,10 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
|
||||
this._breadcrumbService.addBreadcrumb(breadcrumb);
|
||||
} else {
|
||||
this._breadcrumbService.patchBreadcrumb(searchBreadcrumb.id, { params: this.snapshot.queryParams, name });
|
||||
this._breadcrumbService.patchBreadcrumb(searchBreadcrumb.id, {
|
||||
params: this.snapshot.queryParams,
|
||||
name,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (searchBreadcrumb) {
|
||||
@@ -311,7 +378,9 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
|
||||
async getDetailsBreadcrumb(): Promise<Breadcrumb | undefined> {
|
||||
const breadcrumbs = await this.getBreadcrumbs();
|
||||
return breadcrumbs.find((b) => b.tags.includes('details') && b.tags.includes('search'));
|
||||
return breadcrumbs.find(
|
||||
(b) => b.tags.includes('details') && b.tags.includes('search'),
|
||||
);
|
||||
}
|
||||
|
||||
async checkDetailsBreadcrumb() {
|
||||
@@ -333,7 +402,8 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
].includes(this.breadcrumb)
|
||||
) {
|
||||
const customer = this._store.customer;
|
||||
const fullName = `${customer?.firstName ?? ''} ${customer?.lastName ?? ''}`.trim();
|
||||
const fullName =
|
||||
`${customer?.firstName ?? ''} ${customer?.lastName ?? ''}`.trim();
|
||||
|
||||
if (!detailsBreadcrumb) {
|
||||
const navigation = this._navigation.detailsRoute({
|
||||
@@ -515,7 +585,10 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
async checkOrderDetailsBreadcrumb() {
|
||||
const orderDetailsBreadcrumb = await this.getOrderDetailsBreadcrumb();
|
||||
|
||||
if (this.breadcrumb === 'order-details' || this.breadcrumb === 'order-details-history') {
|
||||
if (
|
||||
this.breadcrumb === 'order-details' ||
|
||||
this.breadcrumb === 'order-details-history'
|
||||
) {
|
||||
if (!orderDetailsBreadcrumb) {
|
||||
const navigation = this._navigation.orderDetialsRoute({
|
||||
processId: this._store.processId,
|
||||
@@ -546,7 +619,8 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async checkOrderDetailsHistoryBreadcrumb() {
|
||||
const orderDetailsHistoryBreadcrumb = await this.getOrderDetailsHistoryBreadcrumb();
|
||||
const orderDetailsHistoryBreadcrumb =
|
||||
await this.getOrderDetailsHistoryBreadcrumb();
|
||||
|
||||
if (this.breadcrumb === 'order-details-history') {
|
||||
if (!orderDetailsHistoryBreadcrumb) {
|
||||
@@ -569,7 +643,9 @@ export class CustomerSearchComponent implements OnInit, OnDestroy {
|
||||
this._breadcrumbService.addBreadcrumb(breadcrumb);
|
||||
}
|
||||
} else if (orderDetailsHistoryBreadcrumb) {
|
||||
this._breadcrumbService.removeBreadcrumb(orderDetailsHistoryBreadcrumb.id);
|
||||
this._breadcrumbService.removeBreadcrumb(
|
||||
orderDetailsHistoryBreadcrumb.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Params, Router, RouterStateSnapshot } from '@angular/router';
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
Params,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
import { DomainCheckoutService } from '@domain/checkout';
|
||||
import { CustomerCreateFormData, decodeFormData } from '../create-customer';
|
||||
import { CustomerCreateNavigation } from '@shared/services/navigation';
|
||||
@@ -9,7 +14,10 @@ export class CustomerCreateGuard {
|
||||
private checkoutService = inject(DomainCheckoutService);
|
||||
private customerCreateNavigation = inject(CustomerCreateNavigation);
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
|
||||
async canActivate(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Promise<boolean> {
|
||||
// exit with true if canActivateChild will be called
|
||||
if (route.firstChild) {
|
||||
return true;
|
||||
@@ -19,10 +27,15 @@ export class CustomerCreateGuard {
|
||||
|
||||
const processId = this.getProcessId(route);
|
||||
const formData = this.getFormData(route);
|
||||
const canActivateCustomerType = await this.setableCustomerTypes(processId, formData);
|
||||
const canActivateCustomerType = await this.setableCustomerTypes(
|
||||
processId,
|
||||
formData,
|
||||
);
|
||||
|
||||
if (canActivateCustomerType[customerType] !== true) {
|
||||
customerType = Object.keys(canActivateCustomerType).find((key) => canActivateCustomerType[key]);
|
||||
customerType = Object.keys(canActivateCustomerType).find(
|
||||
(key) => canActivateCustomerType[key],
|
||||
);
|
||||
}
|
||||
|
||||
await this.navigate(processId, customerType, route.queryParams);
|
||||
@@ -30,9 +43,14 @@ export class CustomerCreateGuard {
|
||||
return true;
|
||||
}
|
||||
|
||||
async canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
|
||||
async canActivateChild(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Promise<boolean> {
|
||||
const processId = this.getProcessId(route);
|
||||
const customerType = route.routeConfig.path?.replace('create/', '')?.replace('/update', '');
|
||||
const customerType = route.routeConfig.path
|
||||
?.replace('create/', '')
|
||||
?.replace('/update', '');
|
||||
|
||||
if (customerType === 'create-customer-main') {
|
||||
return true;
|
||||
@@ -40,29 +58,39 @@ export class CustomerCreateGuard {
|
||||
|
||||
const formData = this.getFormData(route);
|
||||
|
||||
const canActivateCustomerType = await this.setableCustomerTypes(processId, formData);
|
||||
const canActivateCustomerType = await this.setableCustomerTypes(
|
||||
processId,
|
||||
formData,
|
||||
);
|
||||
|
||||
if (canActivateCustomerType[customerType]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const activatableCustomerType = Object.keys(canActivateCustomerType)?.find((key) => canActivateCustomerType[key]);
|
||||
const activatableCustomerType = Object.keys(canActivateCustomerType)?.find(
|
||||
(key) => canActivateCustomerType[key],
|
||||
);
|
||||
|
||||
await this.navigate(processId, activatableCustomerType, route.queryParams);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async setableCustomerTypes(processId: number, formData: CustomerCreateFormData): Promise<Record<string, boolean>> {
|
||||
const res = await this.checkoutService.getSetableCustomerTypes(processId).toPromise();
|
||||
async setableCustomerTypes(
|
||||
processId: number,
|
||||
formData: CustomerCreateFormData,
|
||||
): Promise<Record<string, boolean>> {
|
||||
const res = await this.checkoutService
|
||||
.getSetableCustomerTypes(processId)
|
||||
.toPromise();
|
||||
|
||||
if (res.store) {
|
||||
res['store-p4m'] = true;
|
||||
}
|
||||
// if (res.store) {
|
||||
// res['store-p4m'] = true;
|
||||
// }
|
||||
|
||||
if (res.webshop) {
|
||||
res['webshop-p4m'] = true;
|
||||
}
|
||||
// if (res.webshop) {
|
||||
// res['webshop-p4m'] = true;
|
||||
// }
|
||||
|
||||
if (formData?._meta) {
|
||||
const customerType = formData._meta.customerType;
|
||||
@@ -107,7 +135,11 @@ export class CustomerCreateGuard {
|
||||
return {};
|
||||
}
|
||||
|
||||
navigate(processId: number, customerType: string, queryParams: Params): Promise<boolean> {
|
||||
navigate(
|
||||
processId: number,
|
||||
customerType: string,
|
||||
queryParams: Params,
|
||||
): Promise<boolean> {
|
||||
const path = this.customerCreateNavigation.createCustomerRoute({
|
||||
customerType,
|
||||
processId,
|
||||
|
||||
@@ -31,7 +31,9 @@ export class CantAddCustomerToCartModalComponent {
|
||||
get option() {
|
||||
return (
|
||||
this.ref.data.upgradeableTo?.options.values.find((upgradeOption) =>
|
||||
this.ref.data.required.options.values.some((requiredOption) => upgradeOption.key === requiredOption.key),
|
||||
this.ref.data.required.options.values.some(
|
||||
(requiredOption) => upgradeOption.key === requiredOption.key,
|
||||
),
|
||||
) || { value: this.queryParams }
|
||||
);
|
||||
}
|
||||
@@ -39,7 +41,9 @@ export class CantAddCustomerToCartModalComponent {
|
||||
get queryParams() {
|
||||
let option = this.ref.data.required?.options.values.find((f) => f.selected);
|
||||
if (!option) {
|
||||
option = this.ref.data.required?.options.values.find((f) => (isBoolean(f.enabled) ? f.enabled : true));
|
||||
option = this.ref.data.required?.options.values.find((f) =>
|
||||
isBoolean(f.enabled) ? f.enabled : true,
|
||||
);
|
||||
}
|
||||
return option ? { customertype: option.value } : {};
|
||||
}
|
||||
@@ -57,27 +61,29 @@ export class CantAddCustomerToCartModalComponent {
|
||||
const queryParams: Record<string, string> = {};
|
||||
|
||||
if (customer) {
|
||||
queryParams['formData'] = encodeFormData(mapCustomerDtoToCustomerCreateFormData(customer));
|
||||
queryParams['formData'] = encodeFormData(
|
||||
mapCustomerDtoToCustomerCreateFormData(customer),
|
||||
);
|
||||
}
|
||||
|
||||
if (option === 'webshop' && attributes.some((a) => a.key === 'p4mUser')) {
|
||||
const nav = this.customerCreateNavigation.createCustomerRoute({
|
||||
processId: this.applicationService.activatedProcessId,
|
||||
customerType: 'webshop-p4m',
|
||||
});
|
||||
this.router.navigate(nav.path, {
|
||||
queryParams: { ...nav.queryParams, ...queryParams },
|
||||
});
|
||||
} else {
|
||||
const nav = this.customerCreateNavigation.createCustomerRoute({
|
||||
processId: this.applicationService.activatedProcessId,
|
||||
customerType: option as any,
|
||||
});
|
||||
// if (option === 'webshop' && attributes.some((a) => a.key === 'p4mUser')) {
|
||||
// const nav = this.customerCreateNavigation.createCustomerRoute({
|
||||
// processId: this.applicationService.activatedProcessId,
|
||||
// customerType: 'webshop-p4m',
|
||||
// });
|
||||
// this.router.navigate(nav.path, {
|
||||
// queryParams: { ...nav.queryParams, ...queryParams },
|
||||
// });
|
||||
// } else {
|
||||
const nav = this.customerCreateNavigation.createCustomerRoute({
|
||||
processId: this.applicationService.activatedProcessId,
|
||||
customerType: option as any,
|
||||
});
|
||||
|
||||
this.router.navigate(nav.path, {
|
||||
queryParams: { ...nav.queryParams, ...queryParams },
|
||||
});
|
||||
}
|
||||
this.router.navigate(nav.path, {
|
||||
queryParams: { ...nav.queryParams, ...queryParams },
|
||||
});
|
||||
// }
|
||||
|
||||
this.ref.close();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<div class="font-bold text-center border-t border-b border-solid border-disabled-customer -mx-4 py-4">
|
||||
<div
|
||||
class="font-bold text-center border-t border-b border-solid border-disabled-customer -mx-4 py-4"
|
||||
>
|
||||
{{ customer?.communicationDetails?.email }}
|
||||
</div>
|
||||
<div class="grid grid-flow-row gap-1 text-sm font-bold border-b border-solid border-disabled-customer -mx-4 py-4 px-14">
|
||||
<div
|
||||
class="grid grid-flow-row gap-1 text-sm font-bold border-b border-solid border-disabled-customer -mx-4 py-4 px-14"
|
||||
>
|
||||
@if (customer?.organisation?.name) {
|
||||
<span>{{ customer?.organisation?.name }}</span>
|
||||
}
|
||||
@@ -16,23 +20,26 @@
|
||||
</div>
|
||||
|
||||
<div class="grid grid-flow-col gap-4 justify-around mt-12">
|
||||
<button class="border-2 border-solid border-brand rounded-full font-bold text-brand px-6 py-3 text-lg" (click)="close(false)">
|
||||
<button
|
||||
class="border-2 border-solid border-brand rounded-full font-bold text-brand px-6 py-3 text-lg"
|
||||
(click)="close(false)"
|
||||
>
|
||||
neues Onlinekonto anlegen
|
||||
</button>
|
||||
@if (!isWebshopWithP4M) {
|
||||
<button
|
||||
class="border-2 border-solid border-brand rounded-full font-bold text-white px-6 py-3 text-lg bg-brand"
|
||||
(click)="close(true)"
|
||||
>
|
||||
>
|
||||
Daten übernehmen
|
||||
</button>
|
||||
}
|
||||
@if (isWebshopWithP4M) {
|
||||
<!-- @if (isWebshopWithP4M) {
|
||||
<button
|
||||
class="border-2 border-solid border-brand rounded-full font-bold text-white px-6 py-3 text-lg bg-brand"
|
||||
(click)="selectCustomer()"
|
||||
>
|
||||
Datensatz auswählen
|
||||
</button>
|
||||
}
|
||||
} -->
|
||||
</div>
|
||||
|
||||
@@ -9,11 +9,11 @@ import { CustomerCreateGuard } from './guards/customer-create.guard';
|
||||
import {
|
||||
CreateB2BCustomerComponent,
|
||||
CreateGuestCustomerComponent,
|
||||
CreateP4MCustomerComponent,
|
||||
// CreateP4MCustomerComponent,
|
||||
CreateStoreCustomerComponent,
|
||||
CreateWebshopCustomerComponent,
|
||||
} from './create-customer';
|
||||
import { UpdateP4MWebshopCustomerComponent } from './create-customer/update-p4m-webshop-customer';
|
||||
// import { UpdateP4MWebshopCustomerComponent } from './create-customer/update-p4m-webshop-customer';
|
||||
import { CreateCustomerComponent } from './create-customer/create-customer.component';
|
||||
import { CustomerDataEditB2BComponent } from './customer-search/edit-main-view/customer-data-edit-b2b.component';
|
||||
import { CustomerDataEditB2CComponent } from './customer-search/edit-main-view/customer-data-edit-b2c.component';
|
||||
@@ -40,8 +40,16 @@ export const routes: Routes = [
|
||||
path: '',
|
||||
component: CustomerSearchComponent,
|
||||
children: [
|
||||
{ path: 'search', component: CustomerMainViewComponent, data: { side: 'main', breadcrumb: 'main' } },
|
||||
{ path: 'search/list', component: CustomerResultsMainViewComponent, data: { breadcrumb: 'search' } },
|
||||
{
|
||||
path: 'search',
|
||||
component: CustomerMainViewComponent,
|
||||
data: { side: 'main', breadcrumb: 'main' },
|
||||
},
|
||||
{
|
||||
path: 'search/list',
|
||||
component: CustomerResultsMainViewComponent,
|
||||
data: { breadcrumb: 'search' },
|
||||
},
|
||||
{
|
||||
path: 'search/filter',
|
||||
component: CustomerFilterMainViewComponent,
|
||||
@@ -80,7 +88,10 @@ export const routes: Routes = [
|
||||
{
|
||||
path: 'search/:customerId/orders/:orderId/:orderItemId/history',
|
||||
component: CustomerOrderDetailsHistoryMainViewComponent,
|
||||
data: { side: 'order-details', breadcrumb: 'order-details-history' },
|
||||
data: {
|
||||
side: 'order-details',
|
||||
breadcrumb: 'order-details-history',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'search/:customerId/edit/b2b',
|
||||
@@ -140,13 +151,13 @@ export const routes: Routes = [
|
||||
{ path: 'create/webshop', component: CreateWebshopCustomerComponent },
|
||||
{ path: 'create/b2b', component: CreateB2BCustomerComponent },
|
||||
{ path: 'create/guest', component: CreateGuestCustomerComponent },
|
||||
{ path: 'create/webshop-p4m', component: CreateP4MCustomerComponent, data: { customerType: 'webshop' } },
|
||||
{ path: 'create/store-p4m', component: CreateP4MCustomerComponent, data: { customerType: 'store' } },
|
||||
{
|
||||
path: 'create/webshop-p4m/update',
|
||||
component: UpdateP4MWebshopCustomerComponent,
|
||||
data: { customerType: 'webshop' },
|
||||
},
|
||||
// { path: 'create/webshop-p4m', component: CreateP4MCustomerComponent, data: { customerType: 'webshop' } },
|
||||
// { path: 'create/store-p4m', component: CreateP4MCustomerComponent, data: { customerType: 'store' } },
|
||||
// {
|
||||
// path: 'create/webshop-p4m/update',
|
||||
// component: UpdateP4MWebshopCustomerComponent,
|
||||
// data: { customerType: 'webshop' },
|
||||
// },
|
||||
{
|
||||
path: 'create-customer-main',
|
||||
outlet: 'side',
|
||||
|
||||
@@ -3,7 +3,10 @@ import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { CustomerInfoDTO } from '@generated/swagger/crm-api';
|
||||
import { NavigationRoute } from './defs/navigation-route';
|
||||
import { encodeFormData, mapCustomerInfoDtoToCustomerCreateFormData } from 'apps/isa-app/src/page/customer';
|
||||
import {
|
||||
encodeFormData,
|
||||
mapCustomerInfoDtoToCustomerCreateFormData,
|
||||
} from 'apps/isa-app/src/page/customer';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CustomerCreateNavigation {
|
||||
@@ -33,7 +36,9 @@ export class CustomerCreateNavigation {
|
||||
|
||||
navigateToDefault(params: { processId: NumberInput }): Promise<boolean> {
|
||||
const route = this.defaultRoute(params);
|
||||
return this._router.navigate(route.path, { queryParams: route.queryParams });
|
||||
return this._router.navigate(route.path, {
|
||||
queryParams: route.queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
createCustomerRoute(params: {
|
||||
@@ -54,7 +59,9 @@ export class CustomerCreateNavigation {
|
||||
];
|
||||
|
||||
let formData = params?.customerInfo
|
||||
? encodeFormData(mapCustomerInfoDtoToCustomerCreateFormData(params.customerInfo))
|
||||
? encodeFormData(
|
||||
mapCustomerInfoDtoToCustomerCreateFormData(params.customerInfo),
|
||||
)
|
||||
: undefined;
|
||||
|
||||
const urlTree = this._router.createUrlTree(path, {
|
||||
@@ -79,7 +86,9 @@ export class CustomerCreateNavigation {
|
||||
processId: NumberInput;
|
||||
customerInfo: CustomerInfoDTO;
|
||||
}): NavigationRoute {
|
||||
const formData = encodeFormData(mapCustomerInfoDtoToCustomerCreateFormData(customerInfo));
|
||||
const formData = encodeFormData(
|
||||
mapCustomerInfoDtoToCustomerCreateFormData(customerInfo),
|
||||
);
|
||||
const path = [
|
||||
'/kunde',
|
||||
coerceNumberProperty(processId),
|
||||
@@ -88,14 +97,16 @@ export class CustomerCreateNavigation {
|
||||
outlets: {
|
||||
primary: [
|
||||
'create',
|
||||
customerInfo?.features?.find((feature) => feature.key === 'webshop') ? 'webshop-p4m' : 'store-p4m',
|
||||
// customerInfo?.features?.find((feature) => feature.key === 'webshop') ? 'webshop-p4m' : 'store-p4m',
|
||||
],
|
||||
side: 'create-customer-main',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const urlTree = this._router.createUrlTree(path, { queryParams: { formData } });
|
||||
const urlTree = this._router.createUrlTree(path, {
|
||||
queryParams: { formData },
|
||||
});
|
||||
|
||||
return {
|
||||
path,
|
||||
|
||||
Reference in New Issue
Block a user