185 lines
6.9 KiB
HTML
185 lines
6.9 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/.
|
||
-->
|
||
|
||
<div class="pg">
|
||
<header class="pg-head">
|
||
<div>
|
||
<div class="pg-eyebrow">CASHIER · POSITION REPORT</div>
|
||
<h1 class="pg-title">Cashier Position</h1>
|
||
<p class="pg-sub">
|
||
Denomination-wise net cash held by a cashier as of a date (allocations − settlements − inter-cashier transfers).
|
||
</p>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="pg-toolbar pg-toolbar--mat">
|
||
<!-- Teller + Cashier filters — hidden for cashier role (auto-loads own position) -->
|
||
@if (!isCashierMode) {
|
||
@if (tellers.length === 1) {
|
||
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
||
<mat-label>Teller</mat-label>
|
||
<input matInput type="text" [value]="tellers[0].name" readonly />
|
||
</mat-form-field>
|
||
} @else {
|
||
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
||
<mat-label>Teller (optional)</mat-label>
|
||
<mat-select [value]="selectedTellerId" (selectionChange)="onTellerSelect($event.value)">
|
||
<mat-option [value]="null">All Tellers</mat-option>
|
||
@for (t of tellers; track t.id) {
|
||
<mat-option [value]="t.id">{{ t.name }}</mat-option>
|
||
}
|
||
</mat-select>
|
||
</mat-form-field>
|
||
}
|
||
|
||
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
||
<mat-label>Cashier (optional)</mat-label>
|
||
<mat-select [value]="selectedCashierId" (selectionChange)="selectedCashierId = $event.value">
|
||
<mat-option [value]="null">All Cashiers</mat-option>
|
||
@for (c of cashiers; track c.id) {
|
||
<mat-option [value]="c.id">{{ c.label }}</mat-option>
|
||
}
|
||
</mat-select>
|
||
</mat-form-field>
|
||
}
|
||
|
||
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
||
<mat-label>As of Date</mat-label>
|
||
<input matInput type="date" [value]="asOfDate" (change)="asOfDate = $any($event.target).value" />
|
||
</mat-form-field>
|
||
|
||
@if (isCashierMode) {
|
||
<!-- Cashier mode: just a refresh button -->
|
||
<button type="button" class="pg-btn pg-btn--primary" (click)="loadMe()" [disabled]="loading">
|
||
<mat-icon>refresh</mat-icon> Refresh
|
||
</button>
|
||
} @else {
|
||
<button type="button" class="pg-btn pg-btn--primary" (click)="load()" [disabled]="loading">
|
||
<mat-icon>bar_chart</mat-icon> Load Position
|
||
</button>
|
||
}
|
||
</div>
|
||
|
||
@if (errorMsg) {
|
||
<div class="pg-empty" style="color: #dc2626">{{ errorMsg }}</div>
|
||
}
|
||
|
||
@if (loading) {
|
||
<div class="pg-empty">Loading…</div>
|
||
}
|
||
|
||
@for (pos of results; track pos.cashierId) {
|
||
<div class="pg-card" style="margin-bottom: 0">
|
||
<!-- Header: cashier name + current total -->
|
||
<div class="pos-header">
|
||
<span class="pos-cashier">{{ pos.cashierName || labelForCashier(pos.cashierId) }}</span>
|
||
<span class="pos-total">₹{{ pos.totalAmount | number: '1.2-2' }}</span>
|
||
</div>
|
||
|
||
<!-- Morning vs Current comparison bar (only when morning data available) -->
|
||
@if (pos.morningTotal > 0) {
|
||
<div class="pos-compare-bar">
|
||
<div class="pos-compare-item pos-compare-item--morning">
|
||
<mat-icon>wb_sunny</mat-icon>
|
||
<div>
|
||
<span class="pos-compare-label">Morning Opening</span>
|
||
<strong class="pos-compare-val">₹{{ pos.morningTotal | number: '1.2-2' }}</strong>
|
||
</div>
|
||
</div>
|
||
<mat-icon class="pos-compare-arrow">arrow_forward</mat-icon>
|
||
<div class="pos-compare-item pos-compare-item--current">
|
||
<mat-icon>account_balance_wallet</mat-icon>
|
||
<div>
|
||
<span class="pos-compare-label">Current Position</span>
|
||
<strong class="pos-compare-val">₹{{ pos.totalAmount | number: '1.2-2' }}</strong>
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="pos-compare-delta"
|
||
[class.pos-compare-delta--pos]="pos.totalAmount > pos.morningTotal"
|
||
[class.pos-compare-delta--neg]="pos.totalAmount < pos.morningTotal"
|
||
>
|
||
<mat-icon>{{ pos.totalAmount >= pos.morningTotal ? 'trending_up' : 'trending_down' }}</mat-icon>
|
||
{{ pos.totalAmount - pos.morningTotal >= 0 ? '+' : '' }}₹{{
|
||
pos.totalAmount - pos.morningTotal | number: '1.2-2'
|
||
}}
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
@if (pos.denominations.length === 0) {
|
||
<div class="pg-empty">No balance.</div>
|
||
}
|
||
|
||
@if (notes(pos).length > 0) {
|
||
<div class="pos-section-label">Notes</div>
|
||
<table class="pg-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Denomination</th>
|
||
@if (pos.morningTotal > 0) {
|
||
<th class="num pos-col-morning" title="Count received from vault this morning">Morning</th>
|
||
}
|
||
<th style="text-align: center">Current Count</th>
|
||
<th class="num">Amount</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (d of notes(pos); track d.denominationId) {
|
||
<tr>
|
||
<td>
|
||
<span class="pg-chip">₹{{ d.denominationValue }}</span>
|
||
</td>
|
||
@if (pos.morningTotal > 0) {
|
||
<td class="num pos-morning-val">{{ d.morningCount || '—' }}</td>
|
||
}
|
||
<td style="text-align: center; font-weight: 700">{{ d.count }}</td>
|
||
<td class="num">₹{{ d.amount | number: '1.2-2' }}</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
}
|
||
|
||
@if (coins(pos).length > 0) {
|
||
<div class="pos-section-label pos-section-label--coin">Coins</div>
|
||
<table class="pg-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Denomination</th>
|
||
@if (pos.morningTotal > 0) {
|
||
<th class="num pos-col-morning" title="Count received from vault this morning">Morning</th>
|
||
}
|
||
<th style="text-align: center">Current Count</th>
|
||
<th class="num">Amount</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (d of coins(pos); track d.denominationId) {
|
||
<tr>
|
||
<td>
|
||
<span class="pg-chip pg-chip--coin">₹{{ d.denominationValue }}</span>
|
||
</td>
|
||
@if (pos.morningTotal > 0) {
|
||
<td class="num pos-morning-val">{{ d.morningCount || '—' }}</td>
|
||
}
|
||
<td style="text-align: center; font-weight: 700">{{ d.count }}</td>
|
||
<td class="num">₹{{ d.amount | number: '1.2-2' }}</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
}
|
||
</div>
|
||
}
|
||
|
||
@if (!loading && results.length === 0 && !errorMsg) {
|
||
<div class="pg-empty">Select filters and click "Load Position".</div>
|
||
}
|
||
</div>
|