import { Component, ElementRef, Inject, ViewChild } from '@angular/core'; import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { distinctUntilChanged, map, tap } from 'rxjs/operators'; import { ReceivePaymentItem } from '../../core/receive-payment-item'; import { SettleOption } from '../../core/settle-option'; import { SettleOptionService } from '../../settle-option/settle-option.service'; import { VoucherType } from '../bills/voucher-type'; import { ReceivePaymentDatasource } from './receive-payment-datasource'; @Component({ selector: 'app-receive-payment', templateUrl: './receive-payment.component.html', styleUrls: ['./receive-payment.component.css'], }) export class ReceivePaymentComponent { @ViewChild('son', { static: true }) son?: ElementRef; choices: ReceivePaymentItem[] = []; type: VoucherType; amount: number; balance: number; reason = ''; displayReason: boolean; displayTable: boolean; form: FormGroup; dataSource: ReceivePaymentDatasource; displayedColumns = ['name', 'amount']; constructor( public dialogRef: MatDialogRef, private fb: FormBuilder, private ser: SettleOptionService, @Inject(MAT_DIALOG_DATA) public data: { type: VoucherType; amount: number }, ) { this.form = this.fb.group({ amounts: '', son: '', }); this.type = data.type; this.amount = data.amount; this.balance = data.amount; this.displayReason = false; this.displayTable = false; this.ser .listForType(data.type) .pipe( tap( (x: SettleOption[]) => (this.displayReason = x.reduce((o, n) => o || n.hasReason, this.displayReason)), ), tap((x: SettleOption[]) => (this.displayTable = x.length > 1)), map((x: SettleOption[]) => x.map( (y) => ({ ...y, amount: !this.displayTable ? this.amount : 0 } as ReceivePaymentItem), ), ), ) .subscribe((x) => { this.choices = x; this.form.setControl( 'amounts', this.fb.array( this.choices.map((y: ReceivePaymentItem) => this.fb.group({ name: [y.name], amount: [y.amount === 0 ? '' : '' + this.amount], }), ), ), ); this.dataSource = new ReceivePaymentDatasource(this.choices); this.listenToAmountChange(); this.balance = this.amount - this.choices.reduce((a, c) => a + c.amount, 0); }); this.dataSource = new ReceivePaymentDatasource(this.choices); this.listenToAmountChange(); } listenToAmountChange() { const array = this.form.get('amounts') as FormArray; this.choices.forEach((z, i) => array.controls[i].valueChanges.pipe(distinctUntilChanged()).subscribe((x) => { (this.choices.find((s) => s.name === x.name) as ReceivePaymentItem).amount = x.amount === '' ? 0 : parseInt(x.amount, 10); this.balance = this.amount - this.choices.reduce((a, c) => a + c.amount, 0); }), ); } select(reason: string) { this.reason = reason.trim(); return true; } accept(): void { this.dialogRef.close({ choices: this.choices, reason: this.reason }); } }