import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators, FormArray, ValidatorFn, AbstractControl } from '@angular/forms'; import { PaymentsService } from '../../../services/payments.service'; import { ToastrService } from 'ngx-toastr'; import { AlertModalComponent } from '../../common/alert-modal/alert-modal.component'; import { BsModalRef, BsModalService } from 'ngx-bootstrap'; import { newInvoicePaymentDefaults } from '../../../schemas/Invoices/new-invoice-payment-defaults'; import { InvoicesService } from '../../../services/invoices.service'; import { AccountNameService } from '../../../services/account.name.service'; type customer = { sso: string, customer_location: number, wallet_value: number } @Component({ selector: 'app-new-invoice-payment', templateUrl: './new-invoice-payment.component.html', styleUrls: ['./new-invoice-payment.component.css'] }) export class NewInvoicePaymentComponent implements OnInit { invoicePaymentForm: FormGroup; customerValid: boolean; amountDisabled: boolean; totalDueAmt = 0; walletCreditsLeft = 0; initialCredit = 0; errorInAmount = false; totalAmountPaid = 0; customers: any[]; prevValue = 0; invoiceDetail: FormArray; errorInAmountPaid = false; errorCredit = false; paymentModeOptions: { payment_mode_id: number; payment_mode: string; isdefault: boolean; }[]; depositToOptions: { account_type_id: number; account_type_name: string; }[]; paymentData: any bsModalRef: BsModalRef; constructor(private fb: FormBuilder, private paymentService: PaymentsService, private accountService: AccountNameService , private invoiceService: InvoicesService, private toastr: ToastrService, private modalService: BsModalService) { this.accountService.getAllAccount_Names().subscribe((result: { status: string, message: string, data }) => { this.depositToOptions = result.data; }); } ngOnInit(): void { this.invoicePaymentForm = this.fb.group({ customerSSO: ['', { validators: [Validators.required, Validators.minLength(9), Validators.pattern(/^[0-9]*$/)] }], amount: ['', { validators: [Validators.required, this.validateAmount.bind(this)], updateOn: 'blur' }], payFullAmount: [false], referenceNumber: [''], // default value of bill date is current date. validated as required paymentDate: [new Date(), Validators.required], // default value for terms is Due on Receipt. paymentMode: [, Validators.required], depositTo: [, Validators.required], invoiceDetails: this.fb.array([]), notes: [] }); } validateCustomer(customerSSO): customer { // applying linear search, may need to apply proper search according to requirement inputs. return this.customers.find((customer) => { return customer.sso === (customerSSO); }); } get customerSSO() { return this.invoicePaymentForm.get('customerSSO'); } get referenceNumber() { return this.invoicePaymentForm.get('referenceNumber') } get amount() { return this.invoicePaymentForm.get('amount') } get paymentDate() { return this.invoicePaymentForm.get('paymentDate') } get paymentMode() { return this.invoicePaymentForm.get('paymentMode') } get depositTo() { return this.invoicePaymentForm.get('depositTo') } showAlertPopup(data: string) { this.bsModalRef = this.modalService.show(AlertModalComponent, { backdrop: 'static', keyboard: false, animated: true, ignoreBackdropClick: true, initialState: { data: data, infoPopup: true } }); } addinvoiceDetail(date?, invoiceNum?, invoiceAmt?, amtDue?) { this.invoiceDetail = this.invoicePaymentForm.get('invoiceDetails') as FormArray; this.invoiceDetail.push(this.createinvoiceDetail(date, invoiceNum, invoiceAmt, amtDue)); } createinvoiceDetail(date?, invoiceNum?, invoiceAmt?, amtDue?) { let invoiceDate = null; if (date) { invoiceDate = (new Date(date)).toLocaleDateString('en-GB'); } return this.fb.group({ paymentAmt: [null, { validators: [Validators.pattern('^[0-9]*\.?[0-9]*$')], updateOn: 'blur' }], creditUsed: [null, { validators: [Validators.pattern('^[0-9]*\.?[0-9]*$')], updateOn: 'blur' }], invoiceDate: invoiceDate, invoiceNumber: Number(invoiceNum), invoiceAmt: Number(invoiceAmt), amountDue: Number(amtDue) } , { validators: [this.validatePayAmtOnInvoice, this.validateCredit], updateOn: 'blur' } ); } validateAmount(control: AbstractControl) { if (control.value && (control.value > this.totalDueAmt || control.value <= 0)) { this.errorInAmount = true; } else { this.errorInAmount = false; } if (control.value && control.value != this.totalAmountPaid) { this.errorInAmountPaid = true; } else { this.errorInAmountPaid = false; } } validatePayAmtOnInvoice(invoiceDetail: FormGroup) { const payingAmount = +invoiceDetail.get('paymentAmt').value; const walletCreditsUsed = +invoiceDetail.get('creditUsed').value; const amountDue = +invoiceDetail.get('amountDue').value; if (payingAmount + walletCreditsUsed > amountDue || payingAmount < 0) if (!invoiceDetail.get('paymentAmt').errors) invoiceDetail.get('paymentAmt').setErrors({ invalidAmount: 'Invalid Amount' }) else invoiceDetail.get('paymentAmt').errors.invalidAmount = 'Invalid Amount'; else { if (invoiceDetail.get('paymentAmt').errors) { invoiceDetail.get('paymentAmt').errors.invalidAmount = null; invoiceDetail.get('paymentAmt').setErrors(invoiceDetail.get('paymentAmt').errors); } else { invoiceDetail.get('paymentAmt').setErrors(null) } } } validateCredit(invoiceDetail: FormGroup) { const creditAmt = + invoiceDetail.get('creditUsed').value; if (creditAmt < 0) if (!invoiceDetail.get('creditUsed').errors) invoiceDetail.get('creditUsed').setErrors({ invalidCredit: 'Invalid Credit' }) else invoiceDetail.get('creditUsed').errors.invalidCredit = 'Invalid Credit'; else { if (invoiceDetail.get('creditUsed').errors) { invoiceDetail.get('creditUsed').errors.invalidCredit = null; invoiceDetail.get('creditUsed').setErrors(invoiceDetail.get('creditUsed').errors); } else { invoiceDetail.get('creditUsed').setErrors(null) } } } creditChanged(invoiceDetail) { const payingAmount = +invoiceDetail.get('paymentAmt').value; const creditAmt = invoiceDetail.get('creditUsed').value; const amountDue = +invoiceDetail.get('amountDue').value; if (creditAmt > (this.initialCredit) || (creditAmt + payingAmount ) > amountDue ) { if (!invoiceDetail.get('creditUsed').errors) invoiceDetail.get('creditUsed').setErrors({ invalidCredit: 'Invalid Credit' }) else invoiceDetail.get('creditUsed').errors.invalidCredit = 'Invalid Credit'; } else { /* if (invoiceDetail.get('creditUsed').errors) { invoiceDetail.get('creditUsed').errors.invalidCredit = null; invoiceDetail.get('creditUsed').setErrors(invoiceDetail.get('creditUsed').errors); } else { invoiceDetail.get('creditUsed').setErrors(null) } */ this.prevValue = 0; if (creditAmt > 0) { for (const invoiceDetail of this.invoicePaymentForm.value.invoiceDetails) { if (Number(invoiceDetail.creditUsed) > 0) this.prevValue = Number((this.prevValue + Number(invoiceDetail.creditUsed)).toFixed(2)); } this.walletCreditsLeft = this.initialCredit - this.prevValue; } if (creditAmt === '' || creditAmt === 0 || creditAmt === null) { for (const invoiceDetail of this.invoicePaymentForm.value.invoiceDetails) { if (Number(invoiceDetail.creditUsed) > 0) this.prevValue = Number((this.prevValue + Number(invoiceDetail.creditUsed)).toFixed(2)); } this.walletCreditsLeft = this.initialCredit - this.prevValue; } if (this.walletCreditsLeft < 0) { this.errorCredit = true; if (!invoiceDetail.get('creditUsed').errors) invoiceDetail.get('creditUsed').setErrors({ invalidCredit: 'Invalid Credit' }) else invoiceDetail.get('creditUsed').errors.invalidCredit = 'Invalid Credit'; } else this.errorCredit = false; } } removeAllInvoicesFromPayment() { this.invoiceDetail = this.invoicePaymentForm.get('invoiceDetails') as FormArray; this.invoiceDetail.clear(); } customerChanged() { if( this.invoicePaymentForm.get('customerSSO').value ){ this.paymentService.invoicePaymentsDefaultGetRequest().subscribe((defaultsFromDB: newInvoicePaymentDefaults) => { this.customers = defaultsFromDB.data.customers; this.paymentModeOptions = defaultsFromDB.data.paymentModeDetails; const customerSSO = this.invoicePaymentForm.get('customerSSO').value.trim(); const customer: customer = this.validateCustomer(customerSSO); if (customer) { this.customerValid = true; this.amountDisabled = null; this.invoicePaymentForm.get('customerSSO').setValue(customerSSO); this.removeAllInvoicesFromPayment(); this.totalDueAmt = 0; let invoiceDetails; this.initialCredit = customer.wallet_value; this.walletCreditsLeft = this.initialCredit; this.invoiceService.getAllInvoicesOfCustomer(customerSSO).subscribe((defaultsFromDB: { status: string, message: string, data: [] }) => { invoiceDetails = defaultsFromDB.data; if (invoiceDetails) { for (const invoice of invoiceDetails) { this.addinvoiceDetail(invoice.invoice_date, invoice.invoice_id, invoice.total_amount, Number((invoice.total_amount - invoice.paid_amount - invoice.wallet_value_used).toFixed(2))) this.totalDueAmt = Number((this.totalDueAmt + Number(invoice.total_amount) - Number(invoice.paid_amount)-Number(invoice.wallet_value_used)).toFixed(2)); } this.invoicePaymentForm.get('amount').setValue(''); this.invoicePaymentForm.get('payFullAmount').setValue(false); this.payAmtChanged(); } }, (error) => { this.toastr.error("Something Went Wrong! Please try to refresh"); }); } else { this.customerValid = false; this.showAlertPopup('Invalid Customer, Kindly Enter the valid Customer SSO'); this.invoicePaymentForm.get('customerSSO').setValue(''); this.resetFormData(); } }, (error) => { this.toastr.error("Something Went Wrong! Please try to refresh"); }); } } fixedTwoDecimalAmount() { if(this.invoicePaymentForm.value.amount && this.invoicePaymentForm.value.amount != '') this.invoicePaymentForm.get('amount').setValue(this.invoicePaymentForm.value.amount.toFixed(2)); } payAmtChanged() { this.totalAmountPaid = 0; for (const invoiceDetail of this.invoicePaymentForm.value.invoiceDetails) { this.totalAmountPaid = Number((this.totalAmountPaid + Number(invoiceDetail.paymentAmt) + Number(invoiceDetail.creditUsed)).toFixed(2)); } if (this.invoicePaymentForm.value.amount != this.totalAmountPaid) { this.errorInAmountPaid = true; } else { this.errorInAmountPaid = false; } } payInvoiceFull(invoiceIndex) { this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].creditUsed = 0; this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].paymentAmt = this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].amountDue; this.invoicePaymentForm.controls['invoiceDetails'].setValue(this.invoicePaymentForm.value.invoiceDetails) this.payAmtChanged(); } payFullAmtChanged(event) { if (event.currentTarget.checked) { this.invoicePaymentForm.get('amount').setValue(Number(this.totalDueAmt)); for (const invoiceIndex in this.invoicePaymentForm.value.invoiceDetails) { this.payInvoiceFull(invoiceIndex); } this.amountDisabled = true; } else { this.amountDisabled = null; this.invoicePaymentForm.get('amount').setValue(''); for (const invoiceIndex in this.invoicePaymentForm.value.invoiceDetails) { this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].paymentAmt = ''; this.invoicePaymentForm.controls['invoiceDetails'].setValue(this.invoicePaymentForm.value.invoiceDetails) this.payAmtChanged(); } } } onSubmit() { for (const invoiceIndex in this.invoicePaymentForm.value.invoiceDetails) { if (this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].creditUsed < 0) this.errorCredit = true; } this.invoicePaymentForm.controls['depositTo'].markAsTouched(); this.invoicePaymentForm.controls['paymentMode'].markAsTouched(); this.invoicePaymentForm.controls['amount'].markAllAsTouched(); if (this.invoicePaymentForm.valid && !this.errorInAmount && !this.errorInAmountPaid && !this.errorCredit) { for (const invoiceIndex in this.invoicePaymentForm.value.invoiceDetails) { this.invoicePaymentForm.value.customerId = this.invoicePaymentForm.get('customerSSO').value; this.invoicePaymentForm.value.invoiceId = this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].invoiceNumber; this.invoicePaymentForm.value.amountRecieved = this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].paymentAmt; this.invoicePaymentForm.value.amountDue = this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].amountDue; this.invoicePaymentForm.value.creditUsed = this.invoicePaymentForm.value.invoiceDetails[invoiceIndex].creditUsed; this.invoicePaymentForm.value.totalCreditLeft = this.walletCreditsLeft; this.invoicePaymentForm.value.paymentDate = this.invoicePaymentForm.get('paymentDate').value; this.invoicePaymentForm.value.depositTo = this.invoicePaymentForm.get('depositTo').value; if (this.invoicePaymentForm.value.amountRecieved > 0) this.paymentService.createInvoicePayment(this.invoicePaymentForm.value).subscribe((createdPayment: { status: string, message: string, data }) => { if (createdPayment.status === "success") { this.toastr.success("Invoice Payment created successfully for invoice id:" + createdPayment.data.invoice_id) this.resetPage(true); } else { this.toastr.error("Something Went Wrong! Please try to refresh"); } }, (error) => { this.toastr.error("Something Went Wrong! Please try to refresh"); }); } } } resetPage(OnSubmit?: boolean) { this.customerValid = false; if (!OnSubmit) { this.bsModalRef = this.modalService.show(AlertModalComponent, { backdrop: 'static', keyboard: false, animated: true, ignoreBackdropClick: true, initialState: { title: 'Alert', data: 'Are you want to leave the page without saving!', buttonText: 'Stay on Page', deleteBtn: 'Leave' } }); this.bsModalRef.content.event.subscribe(modelResult => { this.resetFormData(); }); } this.resetFormData(); } resetFormData() { this.invoiceDetail = this.invoicePaymentForm.get('invoiceDetails') as FormArray; this.invoiceDetail.clear(); this.invoicePaymentForm.reset(); this.invoicePaymentForm.get('paymentDate').setValue(new Date()); this.totalDueAmt = 0; this.totalAmountPaid = 0; } }