import { CdkScrollableModule } from '@angular/cdk/scrolling'; import { CurrencyPipe } from '@angular/common'; import { Component, computed, inject, linkedSignal, signal } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatTableModule } from '@angular/material/table'; import { ReceivePaymentItem } from '../../core/receive-payment-item'; import { SettleOptionService } from '../../settle-option/settle-option.service'; import { ErrorStateComponent } from '../../shared/error-state/error-state.component'; import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component'; import { VoucherType } from '../bills/voucher-type'; export interface ReceivePaymentFormData { amounts: ReceivePaymentItem[]; son: string; } @Component({ selector: 'app-receive-payment', templateUrl: './receive-payment.component.html', styleUrls: ['./receive-payment.component.css'], imports: [ CdkScrollableModule, CurrencyPipe, MatButtonModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatTableModule, FormField, ErrorStateComponent, SkeletonLoaderComponent, ], }) export class ReceivePaymentComponent { private ser = inject(SettleOptionService); dialogRef = inject>(MatDialogRef); data = inject<{ type: VoucherType; amount: number; }>(MAT_DIALOG_DATA); type = this.data.type; typeSignal = signal(this.type); settleOptionsResource = this.ser.listForType(this.typeSignal); displayReason = computed(() => this.settleOptionsResource.value()?.some((n) => n.hasReason) ?? false); displayTable = computed(() => (this.settleOptionsResource.value()?.length ?? 0) > 1); formModel = linkedSignal({ source: () => this.settleOptionsResource.value(), computation: (options): ReceivePaymentFormData => { if (!options) { return { amounts: [], son: '' }; } const isTable = options.length > 1; return { amounts: options.map( (y) => ({ ...y, amount: !isTable ? this.data.amount : 0, }) as ReceivePaymentItem, ), son: '', }; }, }); form = form(this.formModel); balance = computed(() => { return this.data.amount - this.formModel().amounts.reduce((a, c) => a + (c.amount ?? 0), 0); }); displayedColumns = ['name', 'amount']; reason = ''; trackByRow = (_: number, row: ReceivePaymentItem) => row.id ?? row.name ?? _; select(reason: string) { this.reason = reason.trim(); return true; } accept(): void { this.dialogRef.close({ choices: this.formModel().amounts, reason: this.formModel().son.trim() || this.reason }); } maxAmount(row: ReceivePaymentItem, index: number) { this.formModel.update((f) => { const newAmounts = [...f.amounts]; if (newAmounts[index]) { newAmounts[index] = { ...newAmounts[index], amount: row.amount + this.balance() }; } return { ...f, amounts: newAmounts }; }); } }