- Clerk manually enters token no with today-date unique validation (backend enforced) - Cashier token lookup: auto-fill amount/account, lock amount field, status-specific errors - Confirm dialog shows CASH DISBURSEMENT (blue) with no balance re-deduction warning - Disbursement denomination saved to m_savings_txn_denomination for vault position update - Block direct cashier withdrawal without approved maker-checker token - DISBURSED status shown in My Requests and Checker inbox views with cashier/time info - Remove getNextToken() service method and m_daily_token_counter table (0326 migration) - Race condition protection: UPDATE WHERE status=APPROVED prevents double disbursement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
167 lines
6.6 KiB
TypeScript
167 lines
6.6 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 { NgModule } from '@angular/core';
|
|
import { Routes, RouterModule } from '@angular/router';
|
|
|
|
import { Route } from '../core/route/route.service';
|
|
import { CashierOnlyGuard } from '../core/authentication/cashier-only.guard';
|
|
import { CashExchangeEntryComponent } from './cash-exchange-entry/cash-exchange-entry.component';
|
|
import { CurrencyExchangeDetailComponent } from './currency-exchange-detail/currency-exchange-detail.component';
|
|
import { CashTransferComponent } from './cash-transfer/cash-transfer.component';
|
|
import { CashSettlementComponent } from './cash-settlement/cash-settlement.component';
|
|
import { InterCashierTransferComponent } from './inter-cashier-transfer/inter-cashier-transfer.component';
|
|
import { CashierPositionComponent } from './cashier-position/cashier-position.component';
|
|
import { ReconciliationComponent } from './reconciliation/reconciliation.component';
|
|
import { CashHistoryComponent } from './cash-history/cash-history.component';
|
|
import { ClosingCashReportComponent } from './closing-cash-report/closing-cash-report.component';
|
|
import { ExcessTransactionReportComponent } from './excess-transaction-report/excess-transaction-report.component';
|
|
import { ShareCollectionComponent } from './share-collection/share-collection.component';
|
|
|
|
const routes: Routes = [
|
|
Route.withShell([
|
|
{
|
|
path: 'clerk',
|
|
data: { title: 'Clerk', breadcrumb: 'Clerk' },
|
|
children: [
|
|
{
|
|
path: 'dashboard',
|
|
loadComponent: () =>
|
|
import('../clerk/clerk-dashboard/clerk-dashboard.component').then((m) => m.ClerkDashboardComponent),
|
|
data: { title: 'Clerk Dashboard', breadcrumb: 'Clerk Dashboard' }
|
|
},
|
|
{
|
|
path: 'withdrawal-request',
|
|
loadComponent: () =>
|
|
import('../clerk/withdrawal-request/withdrawal-request.component').then(
|
|
(m) => m.WithdrawalRequestComponent
|
|
),
|
|
data: { title: 'New Withdrawal Request', breadcrumb: 'New Withdrawal Request', mode: 'create' }
|
|
},
|
|
{
|
|
path: 'withdrawal-request/:id',
|
|
loadComponent: () =>
|
|
import('../clerk/withdrawal-edit/withdrawal-edit.component').then((m) => m.WithdrawalEditComponent),
|
|
data: { title: 'Edit Withdrawal Request', breadcrumb: 'Edit Withdrawal Request' }
|
|
},
|
|
{
|
|
path: 'withdrawal-requests',
|
|
loadComponent: () => import('../clerk/my-requests/my-requests.component').then((m) => m.MyRequestsComponent),
|
|
data: { title: 'My Withdrawal Requests', breadcrumb: 'My Withdrawal Requests' }
|
|
},
|
|
{
|
|
path: 'account-facilities',
|
|
loadComponent: () =>
|
|
import('../clerk/account-facilities/account-facilities.component').then(
|
|
(m) => m.AccountFacilitiesComponent
|
|
),
|
|
data: { title: 'Account Facilities', breadcrumb: 'Account Facilities' }
|
|
},
|
|
{
|
|
path: 'photo-signature',
|
|
loadComponent: () =>
|
|
import('../clerk/photo-signature/photo-signature.component').then((m) => m.PhotoSignatureComponent),
|
|
data: { title: 'Photo & Signature', breadcrumb: 'Photo & Signature' }
|
|
},
|
|
{
|
|
path: 'standing-instructions',
|
|
loadComponent: () =>
|
|
import('../clerk/standing-instructions/standing-instructions.component').then(
|
|
(m) => m.StandingInstructionsComponent
|
|
),
|
|
data: { title: 'Standing Instructions', breadcrumb: 'Standing Instructions' }
|
|
},
|
|
{
|
|
path: 'today-activity',
|
|
loadComponent: () =>
|
|
import('../clerk/today-activity/today-activity.component').then((m) => m.TodayActivityComponent),
|
|
data: { title: "Today's Activity", breadcrumb: "Today's Activity" }
|
|
}
|
|
]
|
|
},
|
|
{
|
|
path: 'cashier',
|
|
data: { title: 'Cashier', breadcrumb: 'Cashier' },
|
|
children: [
|
|
{
|
|
path: 'cash-exchange',
|
|
component: CashExchangeEntryComponent,
|
|
data: { title: 'Cash Exchange Entry', breadcrumb: 'Cash Exchange Entry' }
|
|
},
|
|
{
|
|
path: 'exchange-detail',
|
|
component: CurrencyExchangeDetailComponent,
|
|
data: { title: 'Currency Exchange Detail', breadcrumb: 'Currency Exchange Detail' }
|
|
},
|
|
{
|
|
path: 'cash-transfer',
|
|
component: CashTransferComponent,
|
|
data: { title: 'Cash Transfer', breadcrumb: 'Cash Transfer' }
|
|
},
|
|
{
|
|
path: 'cash-settlement',
|
|
component: CashSettlementComponent,
|
|
data: { title: 'Cash Settlement', breadcrumb: 'Cash Settlement' }
|
|
},
|
|
{
|
|
path: 'inter-cashier',
|
|
component: InterCashierTransferComponent,
|
|
data: { title: 'Inter-Cashier Transfer', breadcrumb: 'Inter-Cashier Transfer' }
|
|
},
|
|
{
|
|
path: 'cashier-position',
|
|
component: CashierPositionComponent,
|
|
data: { title: 'Cashier Position', breadcrumb: 'Cashier Position' }
|
|
},
|
|
{
|
|
path: 'reconciliation',
|
|
component: ReconciliationComponent,
|
|
data: { title: 'Reconciliation', breadcrumb: 'Reconciliation' }
|
|
},
|
|
{
|
|
path: 'cash-history',
|
|
component: CashHistoryComponent,
|
|
data: { title: 'Cash History', breadcrumb: 'Cash History' }
|
|
},
|
|
{
|
|
path: 'closing-report',
|
|
component: ClosingCashReportComponent,
|
|
data: { title: 'Closing Cash Report', breadcrumb: 'Closing Cash Report' }
|
|
},
|
|
{
|
|
path: 'excess-report',
|
|
component: ExcessTransactionReportComponent,
|
|
data: { title: 'Excess Transaction Report', breadcrumb: 'Excess Transaction Report' }
|
|
},
|
|
{
|
|
path: 'share-collection',
|
|
component: ShareCollectionComponent,
|
|
data: { title: 'Share Collection', breadcrumb: 'Share Collection' }
|
|
},
|
|
{
|
|
path: 'transaction-entry',
|
|
canActivate: [CashierOnlyGuard],
|
|
loadComponent: () =>
|
|
import('./transaction-entry/transaction-entry.component').then((m) => m.TransactionEntryComponent),
|
|
data: {
|
|
title: 'Cashier Transaction Entry',
|
|
breadcrumb: 'Transaction Entry',
|
|
hideShellLayout: true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
])
|
|
];
|
|
|
|
@NgModule({
|
|
imports: [RouterModule.forChild(routes)],
|
|
exports: [RouterModule]
|
|
})
|
|
export class CashierRoutingModule {}
|