/** * 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 { DayBookComponent } from './day-book/day-book.component'; import { VoucherReportComponent } from './voucher-report/voucher-report.component'; import { BranchDayComponent } from './branch-day/branch-day.component'; import { VaultPositionComponent } from './vault-position/vault-position.component'; import { AccountRegisterComponent } from './account-register/account-register.component'; import { ClosingCashReportComponent } from './closing-cash-report/closing-cash-report.component'; import { ExcessTransactionReportComponent } from './excess-transaction-report/excess-transaction-report.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: 'my-disbursement-requests', loadComponent: () => import('../clerk/my-disbursement-requests/my-disbursement-requests.component').then( (m) => m.MyDisbursementRequestsComponent ), data: { title: 'Disbursements & Transfer', breadcrumb: 'Disbursements & Transfer' } }, { path: 'share-withdrawal-request', loadComponent: () => import('../clerk/share-withdrawal-request/share-withdrawal-request.component').then( (m) => m.ShareWithdrawalRequestComponent ), data: { title: 'New Share Withdrawal Request', breadcrumb: 'New Share Withdrawal Request', mode: 'create' } }, { path: 'share-withdrawal-requests', loadComponent: () => import('../clerk/my-share-withdrawal-requests/my-share-withdrawal-requests.component').then( (m) => m.MyShareWithdrawalRequestsComponent ), data: { title: 'My Share Requests', breadcrumb: 'My Share Requests' } }, { path: 'closure-requests', loadComponent: () => import('../clerk/my-closure-requests/my-closure-requests.component').then( (m) => m.MyClosureRequestsComponent ), data: { title: 'My Closure Requests', breadcrumb: 'My Closure Requests' } }, { path: 'account-facilities', loadComponent: () => import('../clerk/account-facilities/account-facilities.component').then( (m) => m.AccountFacilitiesComponent ), data: { title: 'Account Facilities', breadcrumb: 'Account Facilities' } }, { path: 'account-facilities/cheque-book', loadComponent: () => import('../clerk/cheque-book/cheque-book.component').then((m) => m.ClerkChequeBookComponent), data: { title: 'Cheque Book', breadcrumb: 'Cheque Book' } }, { path: 'account-facilities/cheque-book/:id', loadComponent: () => import('../clerk/cheque-book/cheque-book-detail.component').then((m) => m.ClerkChequeBookDetailComponent), data: { title: 'Cheque Book Detail', breadcrumb: 'Cheque Book Detail' } }, { path: 'photo-signature', loadComponent: () => import('../clerk/photo-signature/photo-signature.component').then((m) => m.PhotoSignatureComponent), data: { title: 'Photo & Signature', breadcrumb: 'Photo & Signature' } }, // The same register the cashier screens use, without their cash-only filter: a clerk raises // book entries — a closure settled to savings, a share redemption, an interest posting the // system made on their approval — and cash-only would hide exactly those. { path: 'received-report', component: VoucherReportComponent, data: { title: 'Received Vouchers', breadcrumb: 'Received Vouchers', side: 'CR', cashOnly: false, cashiersOnly: true } }, { path: 'payment-report', component: VoucherReportComponent, data: { title: 'Payment Vouchers', breadcrumb: 'Payment Vouchers', side: 'DR', cashOnly: false, cashiersOnly: true } }, // Both sides in one list, scoped to whoever is signed in — the "what did I do today" // question the two registers above cannot answer, because an approval raises no voucher. { path: 'my-work', loadComponent: () => import('../cashier/my-work/my-work.component').then((m) => m.MyWorkComponent), data: { title: 'My Vouchers', breadcrumb: 'My Vouchers' } }, { path: 'end-of-day', loadComponent: () => import('../cashier/end-of-day-report/end-of-day-report.component').then((m) => m.EndOfDayReportComponent), data: { title: 'End of the Day Report', breadcrumb: 'End of the Day Report' } }, // The system's own postings — interest, charges, escheats, journals. Both sides in one // list: a night's run credits and debits, and splitting it across two screens would hide // half of it from whichever one you opened. { path: 'system-vouchers', component: VoucherReportComponent, data: { title: 'System Vouchers', breadcrumb: 'System Vouchers', side: 'ALL', cashOnly: false, cashiersOnly: false, systemOnly: true } }, { 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: 'dividend-dashboard', loadComponent: () => import('../clerk/dividend-dashboard/dividend-dashboard.component').then( (m) => m.DividendDashboardComponent ), data: { title: 'Dividend Dashboard', breadcrumb: 'Dividend Dashboard' } } ] }, { // Branch-level operations, kept out of the cashier tree on purpose: opening and closing the // day governs the whole branch, and is not something a cashier does. path: 'branch-ops', data: { title: 'Branch Operations', breadcrumb: 'Branch Operations' }, children: [ { path: 'day-register', component: BranchDayComponent, data: { title: 'Day Open / Day Close', breadcrumb: 'Day Register' } }, { // Same screen, narrowed to the days that were never closed. A separate route rather than // a second link to the register, so choosing it visibly does something. path: 'missed-close', component: BranchDayComponent, data: { title: 'Missed Close Register', breadcrumb: 'Missed Close', missedOnly: true } }, { // Lives here alongside the day register because both answer "what did this branch look // like on that date"; it is linked from the Reports menu, where people go to find it. path: 'account-register', component: AccountRegisterComponent, data: { title: 'Account Register', breadcrumb: 'Account Register' } }, { // Same branch-level scope as the day register: this is the vault's own stock, not any // one cashier's float, so it sits with the other branch-wide screens. path: 'vault-position', component: VaultPositionComponent, data: { title: 'Vault Position', breadcrumb: 'Vault Position' } }, { // The same day book the clerk and cashier read, reached from where a principal officer // signing the day off actually looks. It carries the Officer Verification Sheet — each // person's own credit, debit and net — which is the branch-level reading of the day, not // a counter one. path: 'day-book', component: DayBookComponent, data: { title: 'Day Book & Verification', breadcrumb: 'Day Book' } }, // The one sheet the day is signed off on: the transaction summary, the drawer counted // against the books, and the notes that say why it cannot be closed yet. { path: 'end-of-day', loadComponent: () => import('./end-of-day-report/end-of-day-report.component').then((m) => m.EndOfDayReportComponent), data: { title: 'End of the Day Report', breadcrumb: 'End of the Day Report' } } ] }, { 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: 'day-book', component: DayBookComponent, data: { title: 'Day Book', breadcrumb: 'Day Book' } }, // The register is read one side at a time: Received is the CR side, Payment the DR side. // Same component both times — the side it shows comes from `data.side`. // // `cashOnly` is what makes these the cashier's own registers rather than the whole voucher // book: a cashier deals in notes and coins, so only vouchers that actually moved cash // belong here, and the two reports then reconcile against the drawer and the closing // report. A back-office screen wanting every voucher points at the same component without // the flag. { path: 'received-report', component: VoucherReportComponent, data: { title: 'Received Report', breadcrumb: 'Received Report', side: 'CR', cashOnly: true, cashiersOnly: true } }, { path: 'payment-report', component: VoucherReportComponent, data: { title: 'Payment Report', breadcrumb: 'Payment Report', side: 'DR', cashOnly: true, cashiersOnly: true } }, { path: 'my-work', loadComponent: () => import('./my-work/my-work.component').then((m) => m.MyWorkComponent), data: { title: 'My Vouchers', breadcrumb: 'My Vouchers' } }, { path: 'closing-report', component: ClosingCashReportComponent, data: { title: 'Closing Cash Report', breadcrumb: 'Closing Cash Report' } }, { path: 'end-of-day', loadComponent: () => import('./end-of-day-report/end-of-day-report.component').then((m) => m.EndOfDayReportComponent), data: { title: 'End of the Day Report', breadcrumb: 'End of the Day Report' } }, { path: 'excess-report', component: ExcessTransactionReportComponent, data: { title: 'Excess Transaction Report', breadcrumb: 'Excess Transaction Report' } }, { 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 } }, { path: 'my-deposit-requests', loadComponent: () => import('./my-deposit-requests/my-deposit-requests.component').then((m) => m.MyDepositRequestsComponent), data: { title: 'My Deposit Requests', breadcrumb: 'My Deposit Requests' } }, { path: 'cash-clearing-transfer-summary', loadComponent: () => import('./cash-clearing-transfer-summary/cash-clearing-transfer-summary.component').then( (m) => m.CashClearingTransferSummaryComponent ), data: { title: 'Cash / Clearing / Transfer - Summary Report', breadcrumb: 'Cash / Clearing / Transfer - Summary Report' } } ] } ]) ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class CashierRoutingModule {}