♻️ refactor(customer): merge continueReward and continue methods into unified flow

Consolidate the separate continueReward() and continue() methods in the customer
details view into a single unified continue() method that handles both reward
selection and regular checkout flows.

Key changes:
- Remove separate continueReward() method
- Move hasReturnUrl() check to end of continue() method
- Share all validation and setup logic between both flows:
  * Customer validation (canAddCustomer, canAddShippingAddress)
  * Destination updates
  * Guest with order checks
  * Customer/buyer/payer/shipping setup
  * Notification channel updates
- Diverge only at navigation step based on hasReturnUrl()
- Simplify template from 3 conditional buttons to 1 unified button with
  conditional content

Benefits:
- Reduced code duplication (~39 lines removed)
- Consistent validation for both flows
- Enhanced reward flow with full business rule checks
- Single point of maintenance
- Cleaner template with reduced conditional complexity

Related to #5262 (Prämienshop-Modus)
This commit is contained in:
Lorenz Hilpert
2025-10-23 15:15:47 +02:00
parent 1c5bc8de12
commit 973ef5d3e8
2 changed files with 36 additions and 59 deletions

View File

@@ -173,41 +173,19 @@
</div>
</shared-loader>
@if (hasReturnUrl()) {
<button
type="button"
(click)="continueReward()"
class="w-60 text-white text-lg bg-brand rounded-full px-5 py-3 absolute top-[calc(100vh-19.375rem)] left-1/2 -translate-x-1/2 font-bold disabled:bg-inactive-branch"
[disabled]="!(hasKundenkarte$ | async)"
>
<shared-loader [loading]="showLoader$ | async" spinnerSize="32"
>Auswählen</shared-loader
>
</button>
} @else {
@if (shoppingCartHasNoItems$ | async) {
<button
type="button"
(click)="continue()"
class="text-white text-lg bg-brand rounded-full px-5 py-3 absolute top-[calc(100vh-19.375rem)] left-1/2 -translate-x-1/2 font-bold disabled:bg-inactive-branch"
[disabled]="showLoader$ | async"
>
<shared-loader [loading]="showLoader$ | async" spinnerSize="32"
>Weiter zur Artikelsuche</shared-loader
>
</button>
}
@if (shoppingCartHasItems$ | async) {
<button
type="button"
(click)="continue()"
class="text-white text-lg bg-brand rounded-full px-5 py-3 absolute top-[calc(100vh-19.375rem)] left-1/2 -translate-x-1/2 font-bold disabled:bg-inactive-branch"
[disabled]="showLoader$ | async"
>
<shared-loader [loading]="showLoader$ | async" spinnerSize="32"
>Weiter zum Warenkorb</shared-loader
>
</button>
}
}
<button
type="button"
(click)="continue()"
[class]="'text-white text-lg bg-brand rounded-full px-5 py-3 absolute top-[calc(100vh-19.375rem)] left-1/2 -translate-x-1/2 font-bold disabled:bg-inactive-branch' + (hasReturnUrl() ? ' w-60' : '')"
[disabled]="hasReturnUrl() ? !(hasKundenkarte$ | async) : (showLoader$ | async)"
>
<shared-loader [loading]="showLoader$ | async" spinnerSize="32">
@if (hasReturnUrl()) {
Auswählen
} @else if (shoppingCartHasItems$ | async) {
Weiter zum Warenkorb
} @else {
Weiter zur Artikelsuche
}
</shared-loader>
</button>

View File

@@ -352,32 +352,12 @@ export class CustomerDetailsViewMainComponent
this._onDestroy$.complete();
}
@logAsync
// #5262 Für die Auswahl des Kunden im "Prämienshop-Modus" (Getrennt vom regulären Checkout-Prozess)
async continueReward() {
if (this.hasReturnUrl()) {
this._setSelectedCustomerIdInTab();
// Restore from preserved context (auto-scoped to current tab) and clean up
const context = await this._navigationState.restoreAndClearContext<{
returnUrl?: string;
}>('select-customer');
if (context?.returnUrl) {
await this._router.navigateByUrl(context.returnUrl);
return;
}
// No returnUrl found, navigate to default reward page
await this._router.navigate(['/', this.processId, 'reward']);
}
}
@logAsync
async continue() {
if (this.isBusy) return;
this.setIsBusy(true);
// Shared validation and setup for all flows
const canAddCustomer = await this._canAddCustomerAsync();
if (this.shoppingCartHasItems && !canAddCustomer) {
this.setIsBusy(false);
@@ -420,6 +400,25 @@ export class CustomerDetailsViewMainComponent
this._setShippingAddress();
// #5262 Check for reward selection flow before navigation
if (this.hasReturnUrl()) {
// Restore from preserved context (auto-scoped to current tab) and clean up
const context = await this._navigationState.restoreAndClearContext<{
returnUrl?: string;
}>('select-customer');
if (context?.returnUrl) {
await this._router.navigateByUrl(context.returnUrl);
} else {
// No returnUrl found, navigate to default reward page
await this._router.navigate(['/', this.processId, 'reward']);
}
this.setIsBusy(false);
return;
}
// Regular checkout navigation
if (this.shoppingCartHasItems) {
await this.#rewardSelectionPopUpFlow(this.processId);
} else {