Loan account transaction tab enhacements

This commit is contained in:
Jose Alberto Hernandez
2024-03-20 21:18:11 -06:00
committed by Jose Alberto Hernandez
parent 2f863c42a1
commit bb7f084138
30 changed files with 395 additions and 180 deletions
@@ -1,18 +1,19 @@
<div class="tab-container mat-typography">
<div class="mat-elevation-z1 m-b-25" [hidden]="!accountWithTransactions">
<div fxLayout="row" fxLayoutAlign="start">
<div class="m-b-10">
<h3>All Transactions</h3>
<h3>{{"labels.headings.All Transactions" | translate }}</h3>
</div>
<div class="action-button m-b-20" fxLayout="row" fxLayoutGap="20px" *ngIf="checkStatus()">
<mat-checkbox [formControl]="hideReversedParam" (click)="hideReversed()" class="accruals">
{{"labels.inputs.Hide Reversed" | translate}}</mat-checkbox>
<mat-checkbox [formControl]="hideAccrualsParam" (click)="hideAccruals()" class="accruals">
{{"labels.inputs.Hide Accruals" | translate}}</mat-checkbox>
<!--
<button mat-raised-button color="primary" [routerLink]="['/accounting', 'journal-entries']">View Journal Entries</button>
<button mat-raised-button color="primary" [routerLink]="['export']">Export</button>
-->
<button mat-raised-button color="primary" [routerLink]="['export']">{{"labels.buttons.Export" | translate}}</button>
</div>
</div>
@@ -24,51 +25,64 @@
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Id </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}"> {{ transaction.id }} </td>
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{"labels.inputs.Id" | translate}} </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)" (click)="showTransactions(transaction)"> {{ transaction.id }} </td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell class="center" *matHeaderCellDef mat-sort-header> Transaction Date </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}"> {{ transaction.date | dateFormat }} </td>
<th mat-header-cell class="center" *matHeaderCellDef mat-sort-header> {{"labels.inputs.Transaction Date" | translate}} </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)"> {{ transaction.date | dateFormat }} </td>
</ng-container>
<ng-container matColumnDef="transactionType">
<th mat-header-cell class="center" *matHeaderCellDef> Transaction Type </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}"> {{ transaction.transactionType.value }} </td>
<th mat-header-cell class="center" *matHeaderCellDef> {{"labels.inputs.Transaction Type" | translate}} </th>
<td mat-cell *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)"> {{ transaction.transactionType.value }} </td>
</ng-container>
<ng-container matColumnDef="debit">
<th mat-header-cell class="r-amount" *matHeaderCellDef> Debit </th>
<td mat-cell class="r-amount" *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}"> {{ isDebit(transaction.transactionType) ? (transaction.amount | formatNumber) : 'N/A'}} </td>
<th mat-header-cell class="r-amount" *matHeaderCellDef> {{"labels.inputs.Debit" | translate}} </th>
<td mat-cell class="r-amount" *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)"> {{ isDebit(transaction.transactionType) ? (transaction.amount | formatNumber) : 'N/A'}} </td>
</ng-container>
<ng-container matColumnDef="credit">
<th mat-header-cell class="r-amount" *matHeaderCellDef> Credit </th>
<td mat-cell class="r-amount" *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}"> {{ !isDebit(transaction.transactionType) ? (transaction.amount | formatNumber) : 'N/A' }} </td>
<th mat-header-cell class="r-amount" *matHeaderCellDef> {{"labels.inputs.Credit" | translate}} </th>
<td mat-cell class="r-amount" *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)"> {{ !isDebit(transaction.transactionType) ? (transaction.amount | formatNumber) : 'N/A' }} </td>
</ng-container>
<ng-container matColumnDef="balance">
<th mat-header-cell class="r-amount" *matHeaderCellDef> Balance </th>
<td mat-cell class="r-amount" *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}"> {{ transaction.runningBalance | formatNumber }} </td>
<th mat-header-cell class="r-amount" *matHeaderCellDef> {{"labels.inputs.Balance" | translate}} </th>
<td mat-cell class="r-amount" *matCellDef="let transaction" [ngClass]="savingsTransactionColor(transaction)"> {{ transaction.runningBalance | formatNumber }} </td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell class="center" *matHeaderCellDef> Actions </th>
<td mat-cell class="center" *matCellDef="let transaction" [ngClass]="{'strike': transaction.reversed}">
<button class="account-action-button" mat-raised-button color="primary" (click)="routeEdit($event)" [routerLink]="[transaction.id, 'reciept']">
<i class="fa fa-file" matTooltip="View Reciept"></i>
</button>
<button class="account-action-button" mat-raised-button color="primary" matTooltip="View Journal Entries"
matTooltipPosition="left" (click)="routeEdit($event)"
[routerLink]="['/','journal-entry', 'view', 'S'+transaction.id ]">
<i class="fa fa-arrow-circle-right"></i>
<th mat-header-cell class="center" *matHeaderCellDef> {{"labels.inputs.Actions" | translate}} </th>
<td mat-cell class="center" *matCellDef="let transaction">
<button mat-icon-button [matMenuTriggerFor]="transactionMenu" aria-label="" class="action-button">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #transactionMenu="matMenu">
<button mat-menu-item (click)="showTransactions(transaction)">
<mat-icon><fa-icon icon="eye" size="sm"></fa-icon></mat-icon>
<span>{{ 'labels.text.View Transaction' | translate}}</span>
</button>
<button mat-menu-item *mifosxHasPermission="'ADJUST_LOAN'" (click)="undoTransaction(transaction, $event)">
<mat-icon><fa-icon icon="undo" size="sm"></fa-icon></mat-icon>
<span>{{ 'tooltips.Undo Transaction' | translate}}</span>
</button>
<button mat-menu-item class="account-action-button" (click)="routeEdit($event)" [routerLink]="[transaction.id, 'reciept']">
<mat-icon><fa-icon icon="receipt" size="sm"></fa-icon></mat-icon>
<span>{{ 'tooltips.View Receipts' | translate}}</span>
</button>
<button mat-menu-item (click)="routeEdit($event)" [routerLink]="['/','journal-entry', 'view', 'S'+transaction.id ]">
<mat-icon><fa-icon icon="table-cells" size="sm"></fa-icon></mat-icon>
<span>{{ 'tooltips.View Journal Entries' | translate}}</span>
</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row" (click)="showTransactions(row)"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row"></tr>
</table>
@@ -1,3 +1,5 @@
@import "assets/styles/helper";
.tab-container {
padding: 1%;
margin: 1%;
@@ -27,4 +29,8 @@
.strike {
text-decoration: line-through;
color: red;
}
.transfer {
color: $status-transfer;
}
@@ -5,7 +5,12 @@ import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ActivatedRoute, Router } from '@angular/router';
import { SavingsAccountTransaction } from 'app/savings/models/savings-account-transaction.model';
import { Dates } from 'app/core/utils/dates';
import { SavingsAccountTransaction, SavingsAccountTransactionType } from 'app/savings/models/savings-account-transaction.model';
import { SavingsService } from 'app/savings/savings.service';
import { SettingsService } from 'app/settings/settings.service';
import { UndoTransactionDialogComponent } from '../custom-dialogs/undo-transaction-dialog/undo-transaction-dialog.component';
import { MatDialog } from '@angular/material/dialog';
/**
* Transactions Tab Component.
@@ -35,17 +40,24 @@ export class TransactionsTabComponent implements OnInit {
accountWithTransactions = false;
accountId: string;
/**
* Retrieves savings account data from `resolve`.
* @param {ActivatedRoute} route Activated Route.
*/
constructor(private route: ActivatedRoute,
private router: Router) {
private router: Router,
private savingsService: SavingsService,
private settingsService: SettingsService,
private dialog: MatDialog,
private dateUtils: Dates) {
this.route.parent.parent.data.subscribe((data: { savingsAccountData: any }) => {
this.transactionsData = data.savingsAccountData.transactions;
this.tempTransaction = this.transactionsData;
this.status = data.savingsAccountData.status.value;
});
this.accountId = this.route.parent.parent.snapshot.params['savingAccountId'];
}
ngOnInit() {
@@ -76,12 +88,12 @@ export class TransactionsTabComponent implements OnInit {
* Checks if transaction is debit.
* @param {any} transactionType Transaction Type
*/
isDebit(transactionType: any) {
isDebit(transactionType: SavingsAccountTransactionType) {
return transactionType.withdrawal === true || transactionType.feeDeduction === true
|| transactionType.overdraftInterest === true || transactionType.withholdTax === true;
}
isAccrual(transactionType: any): boolean {
isAccrual(transactionType: SavingsAccountTransactionType): boolean {
return (transactionType.accrual || transactionType.code === 'savingsAccountTransactionType.accrual');
}
@@ -100,7 +112,7 @@ export class TransactionsTabComponent implements OnInit {
* Show Transactions Details
* @param transactionsData Transactions Data
*/
showTransactions(transactionsData: any) {
showTransactions(transactionsData: SavingsAccountTransaction) {
if (transactionsData.transfer) {
this.router.navigate([`../transfer-funds/account-transfers/${transactionsData.transfer.id}`], { relativeTo: this.route });
} else {
@@ -139,4 +151,39 @@ export class TransactionsTabComponent implements OnInit {
this.dataSource.sort = this.sort;
}
savingsTransactionColor(transaction: SavingsAccountTransaction): string {
if (transaction.reversed) {
return 'strike';
}
if (transaction.transfer) {
return 'transfer';
}
return '';
}
undoTransaction(transactionData: SavingsAccountTransaction): void {
const undoTransactionAccountDialogRef = this.dialog.open(UndoTransactionDialogComponent);
undoTransactionAccountDialogRef.afterClosed().subscribe((response: any) => {
if (response.confirm) {
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
const data = {
transactionDate: this.dateUtils.parseDate(transactionData.date),
transactionAmount: 0,
dateFormat,
locale
};
this.savingsService.executeSavingsAccountTransactionsCommand(this.accountId, 'undo', data, transactionData.id).subscribe(() => {
this.reload();
});
}
});
}
private reload() {
const clientId = this.route.parent.parent.snapshot.params['clientId'];
const url: string = this.router.url;
this.router.navigateByUrl(`/clients/${clientId}/savings-accounts`, { skipLocationChange: true })
.then(() => this.router.navigate([url]));
}
}
@@ -4,20 +4,20 @@
<span *mifosxHasPermission="'ADJUSTTRANSACTION_SAVINGSACCOUNT'">
<button mat-raised-button color="primary" *ngIf="transactionData.transactionType.value == 'Transfer' || transactionData.reversed == 'true'
|| transactionData.transactionType.id==3 || transactionData.transactionType.id==17" [routerLink]="'edit'">
<fa-icon icon="edit" class="m-r-10"></fa-icon>Edit
<fa-icon icon="edit" class="m-r-10"></fa-icon>{{"labels.buttons.Edit" | translate}}
</button>
</span>
</span>
<span *ngIf="!transactionData.reversed && transactionData.transactionType.amountHold">
<button mat-raised-button color="primary" *mifosxHasPermission="'RELEASEAMOUNT_SAVINGSACCOUNT'"
(click)="releaseAmount()">
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>Release Amount
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>{{"labels.buttons.Release Amount" | translate}}
</button>
</span>
<span *ngIf="allowUndo()">
<button mat-raised-button color="warn" *mifosxHasPermission="'UNDOTRANSACTION_SAVINGSACCOUNT'"
(click)="undoTransaction()">
<fa-icon icon="undo" class="m-r-10"></fa-icon>Undo
<fa-icon icon="undo" class="m-r-10"></fa-icon>{{"labels.buttons.Undo" | translate}}
</button>
</span>
</div>
@@ -31,7 +31,7 @@
<div fxLayout="row wrap" class="content">
<div fxFlex="50%" class="mat-body-strong">
Transaction Id
{{"labels.inputs.Id" | translate}}
</div>
<div fxFlex="50%">
@@ -39,7 +39,7 @@
</div>
<div fxFlex="50%" class="mat-body-strong">
Type
{{"labels.inputs.Transaction Type" | translate}}
</div>
<div fxFlex="50%">
@@ -47,7 +47,7 @@
</div>
<div fxFlex="50%" class="mat-body-strong">
Transaction Date
{{"labels.inputs.Transaction Date" | translate}}
</div>
<div fxFlex="50%">
@@ -55,7 +55,7 @@
</div>
<div fxFlex="50%" class="mat-body-strong">
Currency
{{"labels.inputs.Currency" | translate}}
</div>
<div fxFlex="50%">
@@ -63,18 +63,18 @@
</div>
<div fxFlex="50%" class="mat-body-strong">
Amount
{{"labels.inputs.Amount" | translate}}
</div>
<div fxFlex="50%">
{{ transactionData.amount | currency:transactionData.currency.code }}
</div>
<div fxFlex="50%" class="mat-body-strong">
Note
<div fxFlex="50%" class="mat-body-strong" *ngIf="transactionData.note">
{{"labels.inputs.Note" | translate}}
</div>
<div fxFlex="50%">
<div fxFlex="50%" *ngIf="transactionData.note">
{{ transactionData.note }}
</div>