feat(cashbox): book a catalog penalty directly as a transaction
Adds a catalog picker to the member-booking form in the cashbox (prefills amount/note/type, stays editable) and a "Buchen" button on each penalty catalog entry that jumps to the cashbox with that entry preselected via a penaltyId query param. No backend changes — reuses the existing POST /transactions flow, the catalog only supplies starting values. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { CurrencyPipe, DatePipe, registerLocaleData } from '@angular/common';
|
||||
import localeDe from '@angular/common/locales/de';
|
||||
import { Component, LOCALE_ID, computed, effect, inject, signal } from '@angular/core';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
@@ -13,8 +14,10 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { AuthStore } from '../../../core/auth/auth-store';
|
||||
import { PenaltyApi } from '../../../core/team/penalty-api';
|
||||
import { TeamStore } from '../../../core/team/team-store';
|
||||
import { TransactionsApi } from '../../../core/team/transactions-api';
|
||||
import { Penalty } from '../../../models/penalty.model';
|
||||
import {
|
||||
CreatePlayerTransaction,
|
||||
CreateTeamWalletTransaction,
|
||||
@@ -52,13 +55,20 @@ export class Cashbox {
|
||||
private readonly authStore = inject(AuthStore);
|
||||
private readonly dialog = inject(MatDialog);
|
||||
private readonly formBuilder = inject(FormBuilder);
|
||||
private readonly penaltyApi = inject(PenaltyApi);
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
private readonly router = inject(Router);
|
||||
private readonly snackBar = inject(MatSnackBar);
|
||||
private readonly teamStore = inject(TeamStore);
|
||||
private readonly transactionsApi = inject(TransactionsApi);
|
||||
private loadedTeamId: number | null = null;
|
||||
private pendingPenaltyId: number | null = Number(
|
||||
this.route.snapshot.queryParamMap.get('penaltyId'),
|
||||
) || null;
|
||||
|
||||
protected readonly team = this.teamStore.team;
|
||||
protected readonly activities = signal<TeamActivity[]>([]);
|
||||
protected readonly penalties = signal<Penalty[]>([]);
|
||||
protected readonly loading = signal(false);
|
||||
protected readonly saving = signal(false);
|
||||
protected readonly playerTransactionTypes = [
|
||||
@@ -109,8 +119,33 @@ export class Cashbox {
|
||||
if (teamId && teamId !== this.loadedTeamId) {
|
||||
this.loadedTeamId = teamId;
|
||||
this.loadActivities(teamId);
|
||||
this.loadPenalties(teamId);
|
||||
}
|
||||
});
|
||||
effect(() => {
|
||||
if (this.pendingPenaltyId === null) return;
|
||||
const penalty = this.penalties().find((p) => p.id === this.pendingPenaltyId);
|
||||
if (!penalty) return;
|
||||
this.pendingPenaltyId = null;
|
||||
this.applyPenaltyPreset(penalty);
|
||||
void this.router.navigate([], { queryParams: {}, replaceUrl: true });
|
||||
});
|
||||
}
|
||||
|
||||
protected onPenaltySelect(penaltyId: number): void {
|
||||
const penalty = this.penalties().find((p) => p.id === penaltyId);
|
||||
if (penalty) this.applyPenaltyPreset(penalty);
|
||||
}
|
||||
|
||||
private applyPenaltyPreset(penalty: Penalty): void {
|
||||
this.playerForm.patchValue({ amount: penalty.amount, note: penalty.description, type: 11 });
|
||||
}
|
||||
|
||||
private loadPenalties(teamId: number): void {
|
||||
this.penaltyApi.loadPenalties(teamId).subscribe({
|
||||
next: (penalties) => this.penalties.set(penalties),
|
||||
error: () => this.penalties.set([]),
|
||||
});
|
||||
}
|
||||
|
||||
protected submitPlayerBooking(): void {
|
||||
|
||||
Reference in New Issue
Block a user