feat(clerk): add GL disbursement maker-checker flow

- Add ClerkDisbursementService for submit/approve/reject HTTP calls
- Add DisbursementRequestsComponent (manager inbox tab under checker tasks)
- Add DisbursementReviewComponent (manager approve/reject detail page)
- Add MyDisbursementRequestsComponent (clerk's own disbursement history)
- Add 'My Disbursements' nav tab to clerk shell navigation header
- Wire routes in cashier-routing and tasks-routing modules
- Add 'My Disbursements' button to transaction-entry clerk footer
- Include accountName in creditEntries payload for manager review display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaanu423
2026-06-16 10:43:29 +05:30
co-authored by Claude Sonnet 4.6
parent 89d1167145
commit efb01d5441
18 changed files with 2594 additions and 27 deletions
@@ -0,0 +1,374 @@
/**
* 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/.
*/
:host {
display: block;
}
.dri {
display: flex;
flex-direction: column;
min-height: 100vh;
background: #f8fafc;
}
.dri-loading {
display: flex;
align-items: center;
gap: 12px;
justify-content: center;
padding: 60px 24px;
font-size: 15px;
color: #64748b;
&__icon {
font-size: 28px;
width: 28px;
height: 28px;
color: #94a3b8;
}
}
.dri-body {
padding: 20px;
display: flex;
flex-direction: column;
gap: 16px;
max-width: 900px;
margin: 0 auto;
width: 100%;
}
.dri-card {
background: #fff;
border-radius: 10px;
border: 1px solid #e2e8f0;
overflow: hidden;
&--header {
border-top: 3px solid #0f4f3c;
}
&--rejected {
border-top: 3px solid #ef4444;
}
&--approved {
border-top: 3px solid #22c55e;
}
}
.dri-card-header {
padding: 16px 20px;
display: flex;
flex-direction: column;
gap: 10px;
&__left {
display: flex;
align-items: center;
gap: 12px;
}
&__meta {
display: flex;
flex-wrap: wrap;
gap: 16px;
color: #64748b;
}
}
.dri-voucher {
font-family: 'Courier New', monospace;
font-size: 20px;
font-weight: 700;
color: #1e40af;
letter-spacing: 0.06em;
}
.dri-status {
display: inline-flex;
align-items: center;
padding: 3px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.04em;
&--pending {
background: #fef3c7;
color: #92400e;
}
&--approved {
background: #dcfce7;
color: #166534;
}
&--rejected {
background: #fee2e2;
color: #991b1b;
}
}
.dri-meta-item {
display: flex;
align-items: center;
gap: 4px;
font-size: 12px;
mat-icon {
font-size: 14px;
width: 14px;
height: 14px;
color: #94a3b8;
}
}
.dri-section-title {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 20px;
font-size: 12px;
font-weight: 700;
color: #475569;
text-transform: uppercase;
letter-spacing: 0.06em;
border-bottom: 1px solid #f1f5f9;
background: #f8fafc;
mat-icon {
font-size: 16px;
width: 16px;
height: 16px;
color: #0f4f3c;
}
}
.dri-detail-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
padding: 16px 20px;
gap: 12px 24px;
}
.dri-detail-item {
display: flex;
flex-direction: column;
gap: 3px;
&--full {
grid-column: 1 / -1;
}
}
.dri-detail-label {
font-size: 11px;
font-weight: 600;
color: #94a3b8;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.dri-detail-value {
font-size: 14px;
color: #0d1b2a;
font-weight: 500;
}
.dri-amount {
font-weight: 700;
font-size: 18px;
color: #dc2626;
}
.dri-cr-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
th,
td {
padding: 10px 16px;
text-align: left;
border-bottom: 1px solid #f1f5f9;
}
th {
font-size: 11px;
font-weight: 700;
color: #64748b;
text-transform: uppercase;
letter-spacing: 0.06em;
background: #f8fafc;
}
.num {
text-align: right;
}
}
.dri-cr-idx {
width: 36px;
color: #94a3b8;
font-size: 12px;
}
.dri-type-badge {
display: inline-flex;
align-items: center;
padding: 2px 8px;
border-radius: 10px;
background: #f1f5f9;
font-size: 11px;
font-weight: 600;
color: #475569;
text-transform: uppercase;
}
.dri-cr-amount {
font-weight: 700;
color: #166534;
}
.dri-cr-total-row {
background: #f0fdf4;
td {
border-top: 2px solid #bbf7d0;
padding: 10px 16px;
}
}
.dri-cr-total-label {
font-weight: 700;
color: #166534;
text-align: right;
}
.dri-cr-total-amount {
font-weight: 700;
color: #166534;
font-size: 15px;
}
.dri-rejection-text {
padding: 14px 20px;
margin: 0;
font-size: 13px;
color: #dc2626;
font-style: italic;
}
.dri-txn-refs {
padding: 14px 20px;
margin: 0;
font-size: 12px;
color: #166534;
}
.dri-actions {
display: flex;
gap: 12px;
align-items: flex-start;
padding: 4px 0 8px;
}
.dri-btn {
display: inline-flex;
align-items: center;
gap: 6px;
border-radius: 8px;
font-family: inherit;
font-weight: 600;
font-size: 14px;
cursor: pointer;
border: none;
transition: background 0.15s;
padding: 10px 20px;
mat-icon {
font-size: 18px;
width: 18px;
height: 18px;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
&--approve {
background: #0f4f3c;
color: #fff;
&:hover:not(:disabled) {
background: #0a3d2e;
}
}
&--reject {
background: #fee2e2;
color: #991b1b;
border: 1px solid #fca5a5;
&:hover:not(:disabled) {
background: #fecaca;
}
}
&--ghost {
background: #f1f5f9;
color: #475569;
&:hover:not(:disabled) {
background: #e2e8f0;
}
}
}
.dri-reject-form {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
max-width: 480px;
}
.dri-reject-label {
font-size: 12px;
font-weight: 700;
color: #991b1b;
}
.dri-reject-textarea {
width: 100%;
padding: 10px 12px;
border: 1px solid #fca5a5;
border-radius: 8px;
font-family: inherit;
font-size: 13px;
resize: vertical;
color: #0d1b2a;
outline: none;
box-sizing: border-box;
&:focus {
border-color: #ef4444;
}
}
.dri-reject-actions {
display: flex;
gap: 8px;
}
.cell-mono {
font-family: 'Courier New', monospace;
}