Files
cbsnexora/src/app/loans/edit-loans-account/edit-loans-account.component.ts
T

216 lines
8.4 KiB
TypeScript

/**
* Copyright since 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { Component, ViewChild, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { LoansService } from '../loans.service';
import { LoansAccountDetailsStepComponent } from '../loans-account-stepper/loans-account-details-step/loans-account-details-step.component';
import { LoansAccountTermsStepComponent } from '../loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component';
import { LoansAccountChargesStepComponent } from '../loans-account-stepper/loans-account-charges-step/loans-account-charges-step.component';
/** Custom Services */
import { SettingsService } from 'app/settings/settings.service';
import { Dates } from 'app/core/utils/dates';
import { MatStepper, MatStepperIcon, MatStep, MatStepLabel } from '@angular/material/stepper';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { LoansAccountScheduleStepComponent } from '../loans-account-stepper/loans-account-schedule-step/loans-account-schedule-step.component';
import { LoansAccountPreviewStepComponent } from '../loans-account-stepper/loans-account-preview-step/loans-account-preview-step.component';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
* Edit Loans
*/
@Component({
selector: 'mifosx-edit-loans-account',
templateUrl: './edit-loans-account.component.html',
styleUrls: ['./edit-loans-account.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
MatStepper,
MatStepperIcon,
FaIconComponent,
MatStep,
MatStepLabel,
LoansAccountDetailsStepComponent,
LoansAccountTermsStepComponent,
LoansAccountChargesStepComponent,
LoansAccountScheduleStepComponent,
LoansAccountPreviewStepComponent
]
})
export class EditLoansAccountComponent {
private route = inject(ActivatedRoute);
private router = inject(Router);
private dateUtils = inject(Dates);
private loansService = inject(LoansService);
private settingsService = inject(SettingsService);
@ViewChild(LoansAccountDetailsStepComponent, { static: true })
loansAccountDetailsStep: LoansAccountDetailsStepComponent;
@ViewChild(LoansAccountTermsStepComponent, { static: true }) loansAccountTermsStep: LoansAccountTermsStepComponent;
@ViewChild(LoansAccountChargesStepComponent, { static: true })
loansAccountChargesStep: LoansAccountChargesStepComponent;
loansAccountAndTemplate: any;
/** Loans Account Product Template */
loansAccountProductTemplate: any;
/** Collateral Options */
collateralOptions: any;
/** Loan Id */
loanId: any;
/** Currency Code */
currencyCode: string;
/**
* Sets loans account edit form.
* @param {route} ActivatedRoute Activated Route.
* @param {router} Router Router.
* @param {Dates} dateUtils Date Utils
* @param {loansService} LoansService Loans Service
* @param {SettingsService} settingsService Settings Service
*/
constructor() {
this.route.data.subscribe((data: { loansAccountAndTemplate: any }) => {
this.loansAccountAndTemplate = data.loansAccountAndTemplate;
});
this.loanId = this.route.snapshot.params['loanId'];
}
/**
* Sets loans account product template and collateral template
* @param {any} $event API response
*/
setTemplate($event: any) {
this.loansAccountProductTemplate = $event;
this.currencyCode = this.loansAccountProductTemplate.currency.code;
if (this.loansAccountProductTemplate.loanProductId) {
this.loansService
.getLoansCollateralTemplateResource(this.loansAccountProductTemplate.loanProductId)
.subscribe((response: any) => {
this.collateralOptions = response.loanCollateralOptions;
});
}
}
/** Get Loans Account Details Form Data */
get loansAccountDetailsForm() {
return this.loansAccountDetailsStep.loansAccountDetailsForm;
}
/** Get Loans Account Terms Form Data */
get loansAccountTermsForm() {
return this.loansAccountTermsStep.loansAccountTermsForm;
}
/** Checks wheter all the forms in different steps are valid and not pristine */
get loansAccountFormValidAndNotPristine() {
return (
this.loansAccountDetailsForm.valid &&
this.loansAccountTermsForm.valid &&
(!this.loansAccountDetailsForm.pristine ||
!this.loansAccountTermsForm.pristine ||
!this.loansAccountTermsStep.pristine ||
!this.loansAccountChargesStep.pristine)
);
}
/** Retrieves Data of all forms except Currency to submit the data */
get loansAccount() {
return {
...this.loansAccountDetailsStep.loansAccountDetails,
...this.loansAccountTermsStep.loansAccountTerms,
...this.loansAccountChargesStep.loansAccountCharges,
...this.loansAccountTermsStep.loanCollateral,
...this.loansAccountTermsStep.disbursementData
};
}
/**
* Submits Data to create loan account
*/
submit() {
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
const loanType = 'individual';
const uniqueCharges = new Map<number | string, any>();
(this.loansAccount.charges ?? []).forEach((charge: any) => {
const chargeId = charge.chargeId;
if (chargeId == null) {
return;
} // Skip malformed entries
uniqueCharges.set(chargeId, charge);
});
const loansAccountData = {
...this.loansAccount,
clientId: this.loansAccountAndTemplate.clientId,
charges: Array.from(uniqueCharges.values()).map((charge: any) => {
const result: any = {
chargeId: charge.chargeId,
amount: charge.amount,
dueDate: charge.dueDate && this.dateUtils.formatDate(charge.dueDate, dateFormat)
};
if (charge.id && charge.id !== charge.chargeId) {
result.id = charge.id;
}
return result;
}),
collateral: this.loansAccount.collateral.map((collateralEle: any) => ({
type: collateralEle.type,
value: collateralEle.value,
description: collateralEle.description
})),
disbursementData: this.loansAccount.disbursementData.map((item: any) => ({
expectedDisbursementDate: this.dateUtils.formatDate(item.expectedDisbursementDate, dateFormat),
principal: item.principal
})),
interestChargedFromDate: this.dateUtils.formatDate(this.loansAccount.interestChargedFromDate, dateFormat),
repaymentsStartingFromDate: this.dateUtils.formatDate(this.loansAccount.repaymentsStartingFromDate, dateFormat),
submittedOnDate: this.dateUtils.formatDate(this.loansAccount.submittedOnDate, dateFormat),
expectedDisbursementDate: this.dateUtils.formatDate(this.loansAccount.expectedDisbursementDate, dateFormat),
dateFormat,
locale,
loanType
};
delete loansAccountData.isValid;
if (loansAccountData.syncRepaymentsWithMeeting) {
loansAccountData.calendarId = this.loansAccountProductTemplate.calendarOptions[0].id;
delete loansAccountData.syncRepaymentsWithMeeting;
}
if (loansAccountData.recalculationRestFrequencyDate) {
loansAccountData.recalculationRestFrequencyDate = this.dateUtils.formatDate(
this.loansAccount.recalculationRestFrequencyDate,
dateFormat
);
}
if (loansAccountData.interestCalculationPeriodType === 0) {
loansAccountData.allowPartialPeriodInterestCalculation = false;
}
if (
!loansAccountData.isLoanProductLinkedToFloatingRate ||
loansAccountData.isLoanProductLinkedToFloatingRate === false
) {
delete loansAccountData.isFloatingInterestRate;
}
loansAccountData.principal = loansAccountData.principalAmount;
delete loansAccountData.principalAmount;
delete loansAccountData.multiDisburseLoan;
// In Fineract, the POST and PUT endpoints for /v1/loans have a typo in the field
// allowPartialPeriodInterestCalculation. Until that is fixed, we need to replace the field name in the payload.
loansAccountData.allowPartialPeriodInterestCalculation = loansAccountData.allowPartialPeriodInterestCalculation;
delete loansAccountData.allowPartialPeriodInterestCalculation;
this.loansService.updateLoansAccount(this.loanId, loansAccountData).subscribe((response: any) => {
this.router.navigate(['../'], { relativeTo: this.route });
});
}
}