WEB-296: add undo write-off in the upper right menu

This commit is contained in:
Attila Budai
2025-09-16 10:41:19 +02:00
committed by Aleksandar Vidakovic
parent 6a1a8a660a
commit 622a738caa
8 changed files with 183 additions and 3 deletions
@@ -79,6 +79,8 @@ export class LoanActionButtonResolver {
return this.loansService.getLoanActionTemplate(loanId, 'contractTermination');
} else if (loanActionButton === 'Buy Down Fee') {
return this.loansService.getLoanActionTemplate(loanId, 'buyDownFee');
} else if (loanActionButton === 'Undo Write-off') {
return undefined;
} else {
return undefined;
}
@@ -66,3 +66,4 @@
[dataObject]="navigationData"
*ngIf="actions['Add Interest Pause']"
></mifosx-add-interest-pause>
<mifosx-undo-write-off [dataObject]="actionButtonData" *ngIf="actions['Undo Write-off']"></mifosx-undo-write-off>
@@ -30,6 +30,7 @@ import { AssetTransferLoanComponent } from './asset-transfer-loan/asset-transfer
import { LoanReagingComponent } from './loan-reaging/loan-reaging.component';
import { LoanReamortizeComponent } from './loan-reamortize/loan-reamortize.component';
import { AddInterestPauseComponent } from './add-interest-pause/add-interest-pause.component';
import { UndoWriteOffComponent } from './undo-write-off/undo-write-off.component';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
@@ -69,7 +70,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
AssetTransferLoanComponent,
LoanReagingComponent,
LoanReamortizeComponent,
AddInterestPauseComponent
AddInterestPauseComponent,
UndoWriteOffComponent
]
})
export class LoanAccountActionsComponent {
@@ -116,6 +118,7 @@ export class LoanAccountActionsComponent {
'Capitalized Income': boolean;
'Contract Termination': boolean;
'Buy Down Fee': boolean;
'Undo Write-off': boolean;
} = {
Close: false,
'Undo Approval': false,
@@ -154,7 +157,8 @@ export class LoanAccountActionsComponent {
'Add Interest Pause': false,
'Capitalized Income': false,
'Contract Termination': false,
'Buy Down Fee': false
'Buy Down Fee': false,
'Undo Write-off': false
};
actionButtonData: any;
@@ -0,0 +1,32 @@
<div class="container mat-elevation-z8">
<mat-card>
<form [formGroup]="undoWriteOffLoanForm" (ngSubmit)="submit()">
<mat-card-content>
<div class="layout-column">
<p class="m-b-20">
{{ 'labels.text.Undo Write-off Description' | translate }}
</p>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Note' | translate }}</mat-label>
<textarea matInput formControlName="note" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
</mat-form-field>
</div>
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
<button type="button" mat-raised-button [routerLink]="['../../general']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button
mat-raised-button
color="primary"
[disabled]="!undoWriteOffLoanForm.valid"
*mifosxHasPermission="'UNDOWRITEOFF_LOAN'"
>
{{ 'labels.buttons.Submit' | translate }}
</button>
</mat-card-actions>
</mat-card-content>
</form>
</mat-card>
</div>
@@ -0,0 +1,32 @@
.container {
max-width: 37rem;
}
.mat-card {
padding: 20px;
}
.layout-column {
display: flex;
flex-direction: column;
gap: 20px;
}
.mat-card-actions {
padding-top: 20px;
}
.gap-5px {
gap: 5px;
}
.responsive-column {
@media (width <= 768px) {
flex-direction: column;
align-items: stretch;
}
}
.m-b-20 {
margin-bottom: 20px;
}
@@ -0,0 +1,102 @@
/** Angular Imports */
import { Component, OnInit, Input } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
/** Custom Services */
import { LoansService } from 'app/loans/loans.service';
import { SettingsService } from 'app/settings/settings.service';
import { AlertService } from 'app/core/alert/alert.service';
import { Dates } from 'app/core/utils/dates';
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
* Loan Undo Write-off Action
*/
@Component({
selector: 'mifosx-undo-write-off',
templateUrl: './undo-write-off.component.html',
styleUrls: ['./undo-write-off.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
CdkTextareaAutosize
]
})
export class UndoWriteOffComponent implements OnInit {
@Input() dataObject: any;
/** Loan Id */
loanId: string;
/** Minimum Date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum Date allowed. */
maxDate = new Date();
/** Undo Write-off Loan Form */
undoWriteOffLoanForm: UntypedFormGroup;
/**
* @param {FormBuilder} formBuilder Form Builder.
* @param {LoansService} loanService Loan Service.
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
* @param {SettingsService} settingsService Settings Service
*/
constructor(
private formBuilder: UntypedFormBuilder,
private loanService: LoansService,
private route: ActivatedRoute,
private router: Router,
private dateUtils: Dates,
private settingsService: SettingsService,
private alertService: AlertService
) {
this.loanId = this.route.snapshot.params['loanId'];
}
/**
* Creates the undo write-off loan form
* and initialize with the required values
*/
ngOnInit() {
this.maxDate = this.settingsService.businessDate;
this.createUndoWriteOffLoanForm();
}
/**
* Creates the undo write-off loan form
*/
createUndoWriteOffLoanForm() {
this.undoWriteOffLoanForm = this.formBuilder.group({
note: ['']
});
}
/** Submits the undo write-off form */
submit() {
const undoWriteOffLoanFormData = this.undoWriteOffLoanForm.value;
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
const operationDate = this.settingsService.businessDate;
const data = {
...undoWriteOffLoanFormData,
transactionDate: this.dateUtils.formatDate(operationDate && new Date(operationDate), dateFormat),
transactionAmount: 0,
dateFormat,
locale
};
this.loanService.submitLoanActionButton(this.loanId, data, 'undowriteoff').subscribe({
next: (response: any) => {
this.router.navigate(['../../general'], { relativeTo: this.route });
},
error: (error) => {
console.error('Undo write-off failed:', error);
this.alertService.alert({
type: 'Undo Write-off Failed',
message:
'An error occurred while processing the undo write-off transaction. Please try again or contact support if the problem persists.'
});
}
});
}
}
@@ -124,6 +124,11 @@ export class LoansAccountButtonConfiguration {
name: 'Recovery Payment',
icon: 'briefcase',
taskPermissionName: 'RECOVERYPAYMENT_LOAN'
},
{
name: 'Undo Write-off',
icon: 'undo',
taskPermissionName: 'UNDOWRITEOFF_LOAN'
}
];
break;