Files
cbsnexora/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.html
T

310 lines
13 KiB
HTML

<!--
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/.
-->
@if (isJournalEntryLoaded) {
<div class="txn-detail-page">
<!-- Header Bar -->
<div class="txn-header-bar">
<div class="txn-header-bar__left">
<button mat-icon-button (click)="goBack()" class="txn-back-btn" matTooltip="Go Back">
<fa-icon icon="arrow-left"></fa-icon>
</button>
<div class="txn-header-bar__title-group">
<h3 class="txn-header-bar__title">
<fa-icon icon="receipt" class="m-r-8"></fa-icon>
Transaction Detail
</h3>
@if (transactionId) {
<span class="txn-header-bar__txn-id">ID: {{ transactionId }}</span>
}
</div>
</div>
</div>
<!-- One branch's part of a transfer between branches: say so, name both branches, link the other part -->
@if (interBranch) {
<div class="txn-interbranch">
<div class="txn-interbranch__icon"><fa-icon icon="link"></fa-icon></div>
<div class="txn-interbranch__body">
<div class="txn-interbranch__title">
Inter-branch transfer
<span class="txn-interbranch__voucher">{{ interBranch.voucherNo }}</span>
</div>
<div class="txn-interbranch__route">
<strong>{{ branchesOf(interBranch.from) }}</strong>
<span class="txn-interbranch__arrow">→</span>
<strong>{{ branchesOf(interBranch.to) }}</strong>
<span class="txn-interbranch__amount">{{ interBranch.amount | formatNumber }}</span>
</div>
<div class="txn-interbranch__text">
This is the <strong>{{ thisBranchPart?.branchName }}</strong> branch's part of the transfer. Each branch
posts its own part, and the two are joined through Liability Transfer Suspense (200901), so they cancel out
across the bank.
</div>
<div class="txn-interbranch__legs">
@for (leg of interBranch.from; track leg.accountNo) {
<span class="txn-interbranch__leg"
><b>From</b> {{ leg.accountNo }} · {{ leg.accountName }} ({{ leg.branchName }})</span
>
}
@for (leg of interBranch.to; track leg.accountNo) {
<span class="txn-interbranch__leg"
><b>To</b> {{ leg.accountNo }} · {{ leg.accountName }} ({{ leg.branchName }})</span
>
}
</div>
@if (interBranch.raisedBy) {
<div class="txn-interbranch__text">
Raised by <strong>{{ interBranch.raisedBy }}</strong> on {{ interBranch.raisedAt | datetimeFormat }},
approved by <strong>{{ interBranch.approvedBy }}</strong> on
{{ interBranch.approvedAt | datetimeFormat }}.
</div>
}
<div class="txn-interbranch__text">
@for (part of otherBranchParts; track part.transactionId) {
The <strong>{{ part.branchName }}</strong> part:
<button type="button" class="txn-interbranch__link" (click)="openTransaction(part.transactionId)">
{{ part.transactionId }}
</button>
}
</div>
<div class="txn-interbranch__warn">
<fa-icon icon="exclamation-triangle" class="m-r-6"></fa-icon>
Do not revert one branch's part on its own: the other branch's part would stay and the books would not
balance.
</div>
</div>
</div>
}
<!-- Transaction Info Cards -->
@if (isViewTransaction()) {
@if (dataSource) {
<div class="txn-info-grid">
<div
class="txn-info-card"
[ngClass]="dataSource.data[0].manualEntry ? 'txn-info-card--manual' : 'txn-info-card--system'"
>
<div class="txn-info-card__icon">
<fa-icon [icon]="dataSource.data[0].manualEntry ? 'pencil-alt' : 'cog'"></fa-icon>
</div>
<div class="txn-info-card__body">
<div class="txn-info-card__label">Entry Type</div>
<div class="txn-info-card__value">
{{ dataSource.data[0].manualEntry ? 'Manual Entry' : 'System Entry' }}
</div>
</div>
</div>
<div class="txn-info-card txn-info-card--blue">
<div class="txn-info-card__icon"><fa-icon icon="building"></fa-icon></div>
<div class="txn-info-card__body">
<div class="txn-info-card__label">Office</div>
<div class="txn-info-card__value">{{ dataSource.data[0].officeName }}</div>
</div>
</div>
<div class="txn-info-card txn-info-card--teal">
<div class="txn-info-card__icon"><fa-icon icon="calendar-alt"></fa-icon></div>
<div class="txn-info-card__body">
<div class="txn-info-card__label">Transaction Date</div>
<div class="txn-info-card__value">{{ dataSource.data[0].transactionDate | dateFormat }}</div>
</div>
</div>
<div class="txn-info-card txn-info-card--purple">
<div class="txn-info-card__icon"><fa-icon icon="clock"></fa-icon></div>
<div class="txn-info-card__body">
<div class="txn-info-card__label">Submitted On</div>
<div class="txn-info-card__value txn-info-card__value--small">
{{ dataSource.data[0].submittedOnDate | datetimeFormat }}
</div>
</div>
</div>
<div class="txn-info-card txn-info-card--grey">
<div class="txn-info-card__icon"><fa-icon icon="user"></fa-icon></div>
<div class="txn-info-card__body">
<div class="txn-info-card__label">Created By</div>
<div class="txn-info-card__value">{{ dataSource.data[0].createdByUserName }}</div>
</div>
</div>
@if (dataSource.data[0].externalAssetOwner) {
<div class="txn-info-card txn-info-card--orange">
<div class="txn-info-card__icon"><fa-icon icon="link"></fa-icon></div>
<div class="txn-info-card__body">
<div class="txn-info-card__label">External Asset Owner</div>
<div class="txn-info-card__value">{{ dataSource.data[0].externalAssetOwner }}</div>
</div>
</div>
}
</div>
<!-- DR/CR Summary Bar -->
<div class="txn-summary-bar">
<div class="txn-summary-bar__item txn-summary-bar__item--dr">
<fa-icon icon="arrow-up" class="m-r-6"></fa-icon>
Total Debit: <strong>{{ getTotalDebit() | formatNumber }}</strong>
</div>
<div class="txn-summary-bar__divider"></div>
<div class="txn-summary-bar__item txn-summary-bar__item--cr">
<fa-icon icon="arrow-down" class="m-r-6"></fa-icon>
Total Credit: <strong>{{ getTotalCredit() | formatNumber }}</strong>
</div>
<div class="txn-summary-bar__divider"></div>
<div
class="txn-summary-bar__item"
[ngClass]="isBalanced() ? 'txn-summary-bar__item--balanced' : 'txn-summary-bar__item--unbalanced'"
>
<fa-icon [icon]="isBalanced() ? 'check-circle' : 'exclamation-triangle'" class="m-r-6"></fa-icon>
{{ isBalanced() ? 'Balanced' : 'Unbalanced' }}
</div>
</div>
}
}
<!-- Journal Entries Table -->
<mat-card class="txn-entries-card mat-elevation-z2">
<mat-card-header class="txn-entries-card__header">
<mat-card-title>
<fa-icon icon="table" class="m-r-6"></fa-icon>
Journal Entries
<span class="txn-entries-count">{{ dataSource?.data?.length || 0 }} entries</span>
</mat-card-title>
</mat-card-header>
<mat-card-content class="txn-entries-card__content">
<div class="txn-table-wrapper">
<table mat-table [dataSource]="dataSource" matSort class="txn-table">
<!-- Entry ID -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="txn-th"># ID</th>
<td mat-cell *matCellDef="let entry" class="txn-td">
<span class="txn-entry-id">{{ entry.id }}</span>
</td>
</ng-container>
<!-- Account Type -->
<ng-container matColumnDef="glAccountType">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="txn-th">Account Type</th>
<td mat-cell *matCellDef="let entry" class="txn-td">
<span class="txn-acct-type-badge" [ngClass]="getAccountTypeBadgeClass(entry.glAccountType?.value)">
{{ entry.glAccountType?.value }}
</span>
</td>
</ng-container>
<!-- Account Code -->
<ng-container matColumnDef="glAccountCode">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="txn-th">Code</th>
<td mat-cell *matCellDef="let entry" class="txn-td">
<span class="txn-acct-code">{{ entry.glAccountCode }}</span>
</td>
</ng-container>
<!-- Account Name -->
<ng-container matColumnDef="glAccountName">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="txn-th">Account Name</th>
<td mat-cell *matCellDef="let entry" class="txn-td">
<span class="txn-acct-name">{{ entry.glAccountName }}</span>
</td>
</ng-container>
<!-- Savings / CA Account No -->
<ng-container matColumnDef="savingsAccountNo">
<th mat-header-cell *matHeaderCellDef class="txn-th">Account No</th>
<td mat-cell *matCellDef="let entry" class="txn-td">
<span *ngIf="entry.savingsAccountNo" class="txn-acct-no-chip" [matTooltip]="entry.savingsAccountNo">
{{ entry.savingsAccountNo }}
</span>
<span *ngIf="!entry.savingsAccountNo" class="txn-amount--empty">—</span>
</td>
</ng-container>
<!-- DR/CR Badge -->
<ng-container matColumnDef="entryType">
<th mat-header-cell *matHeaderCellDef class="txn-th txn-th--center">DR / CR</th>
<td mat-cell *matCellDef="let entry" class="txn-td txn-td--center">
<span
class="txn-drcr-badge"
[ngClass]="entry.entryType?.value === 'DEBIT' ? 'txn-drcr-badge--dr' : 'txn-drcr-badge--cr'"
>
{{ entry.entryType?.value === 'DEBIT' ? 'DR' : 'CR' }}
</span>
</td>
</ng-container>
<!-- Debit -->
<ng-container matColumnDef="debit">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="txn-th txn-th--amount txn-th--dr">
Debit (Dr)
</th>
<td mat-cell *matCellDef="let entry" class="txn-td txn-td--amount">
@if (entry.entryType?.value === 'DEBIT') {
<span class="txn-amount txn-amount--dr">
{{ entry.currency?.displaySymbol || entry.currency?.code }}
{{ entry.amount | formatNumber }}
</span>
} @else {
<span class="txn-amount--empty">—</span>
}
</td>
</ng-container>
<!-- Credit -->
<ng-container matColumnDef="credit">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="txn-th txn-th--amount txn-th--cr">
Credit (Cr)
</th>
<td mat-cell *matCellDef="let entry" class="txn-td txn-td--amount">
@if (entry.entryType?.value === 'CREDIT') {
<span class="txn-amount txn-amount--cr">
{{ entry.currency?.displaySymbol || entry.currency?.code }}
{{ entry.amount | formatNumber }}
</span>
} @else {
<span class="txn-amount--empty">—</span>
}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns" class="txn-header-row"></tr>
<tr
mat-row
*matRowDef="let row; columns: displayedColumns"
(click)="viewJournalEntry(row)"
class="txn-data-row"
[ngClass]="row.entryType?.value === 'DEBIT' ? 'txn-row--dr' : 'txn-row--cr'"
></tr>
</table>
</div>
</mat-card-content>
</mat-card>
<!-- Back Button -->
<div class="txn-footer-actions">
<button mat-stroked-button color="primary" (click)="goBack()">
<fa-icon icon="arrow-left" class="m-r-6"></fa-icon> Back
</button>
</div>
</div>
}
@if (!isJournalEntryLoaded) {
<div class="txn-no-data">
<div class="txn-no-data__box">
<fa-icon icon="search" size="2x" class="txn-no-data__icon"></fa-icon>
<h4>No Journal Entry Found</h4>
<p>The transaction you are looking for does not exist or has been removed.</p>
<button mat-raised-button color="primary" (click)="goBack()">
<fa-icon icon="arrow-left" class="m-r-6"></fa-icon> Go Back
</button>
</div>
</div>
}