import { Component, Inject, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { round } from 'mathjs'; import { Observable, of as observableOf } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators'; import { Batch } from '../core/batch'; import { Inventory } from '../core/inventory'; import { Product } from '../core/product'; import { ProductSku } from '../core/product-sku'; import { ProductService } from '../product/product.service'; import { MathService } from '../shared/math.service'; @Component({ selector: 'app-purchase-dialog', templateUrl: './purchase-dialog.component.html', styleUrls: ['./purchase-dialog.component.css'], }) export class PurchaseDialogComponent implements OnInit { products: Observable; form: FormGroup<{ product: FormControl; quantity: FormControl; price: FormControl; tax: FormControl; discount: FormControl; }>; product: ProductSku = new ProductSku(); constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: { inventory: Inventory }, private math: MathService, private productSer: ProductService, ) { this.form = new FormGroup({ product: new FormControl(null), quantity: new FormControl('', { nonNullable: true }), price: new FormControl('', { nonNullable: true }), tax: new FormControl('', { nonNullable: true }), discount: new FormControl('', { nonNullable: true }), }); // Listen to Product Autocomplete Change this.products = this.form.controls.product.valueChanges.pipe( map((x) => ((x as ProductSku).name !== undefined ? (x as ProductSku).name : (x as string))), map((x) => (x !== null && x.length >= 1 ? x : null)), debounceTime(150), distinctUntilChanged(), switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocompleteSku(x, true))), ); } ngOnInit() { this.form.setValue({ product: this.data.inventory.batch?.sku, quantity: `${this.data.inventory.quantity}`, price: `${this.data.inventory.rate}`, tax: `${this.data.inventory.tax}`, discount: `${this.data.inventory.discount}`, }); this.product = this.data.inventory.batch?.sku; } displayFn(product?: Product): string { return product ? product.name : ''; } productSelected(event: MatAutocompleteSelectedEvent): void { const product: ProductSku = event.option.value; this.product = product; this.form.controls.price.setValue(`${product.costPrice}`); if (product.isRateContracted) { this.form.controls.price.disable(); this.form.controls.tax.disable(); this.form.controls.discount.disable(); this.form.controls.tax.setValue('RC'); this.form.controls.discount.setValue('RC'); } else { this.form.controls.price.enable(); this.form.controls.tax.enable(); this.form.controls.discount.enable(); this.form.controls.tax.setValue(''); this.form.controls.discount.setValue(''); } } accept(): void { const formValue = this.form.value; const quantity = this.math.parseAmount(formValue.quantity, 2); const price = this.math.parseAmount(formValue.price, 2); const tax = this.math.parseAmount(formValue.tax, 5); const discount = this.math.parseAmount(formValue.discount, 5); if (this.data.inventory.batch === null) { this.data.inventory.batch = new Batch(); } this.data.inventory.batch.sku = this.product; this.data.inventory.quantity = quantity; this.data.inventory.rate = price; this.data.inventory.tax = tax; this.data.inventory.discount = discount; this.data.inventory.amount = round(quantity * price * (1 + tax) * (1 - discount), 2); this.dialogRef.close(this.data.inventory); } }