Fix cash summary quantity bug; add Safe Count as own nav item

- Cash summary: derive total_quantity from total_amount/denomination_value
  so value_entered rows are counted (previously SUM(quantity) returned
  NULL for those rows)
- Safe Count: moved safe_cash out of Float Management tabs into its own
  /safe/* route with a dedicated sidebar entry (Vault icon)
- FloatManagement now only shows Petty Cash and Change Tin tabs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-01 21:36:19 +00:00
parent e6188fb337
commit 4ea5238e62
5 changed files with 25 additions and 7 deletions

View file

@ -193,7 +193,9 @@ export async function reportRoutes(app) {
if (!from || !to) return reply.status(400).send({ error: 'from and to required' }) if (!from || !to) return reply.status(400).send({ error: 'from and to required' })
const { rows } = await pool.query( const { rows } = await pool.query(
`SELECT d.denomination_value, SUM(d.quantity) AS total_quantity, SUM(d.total_amount) AS total_value `SELECT d.denomination_value,
ROUND(SUM(d.total_amount) / NULLIF(d.denomination_value, 0)) AS total_quantity,
SUM(d.total_amount) AS total_value
FROM denominations d FROM denominations d
JOIN cash_ups c ON d.cash_up_id = c.id JOIN cash_ups c ON d.cash_up_id = c.id
WHERE c.session_date >= $1 AND c.session_date <= $2 AND d.count_type = 'takings' WHERE c.session_date >= $1 AND c.session_date <= $2 AND d.count_type = 'takings'

View file

@ -5,6 +5,7 @@ import { DailyCashUp } from './pages/DailyCashUp'
import { History } from './pages/History' import { History } from './pages/History'
import { MultiDayReport } from './pages/MultiDayReport' import { MultiDayReport } from './pages/MultiDayReport'
import { FloatManagement } from './pages/FloatManagement' import { FloatManagement } from './pages/FloatManagement'
import { SafeCount } from './pages/SafeCount'
import { CashSummary } from './pages/CashSummary' import { CashSummary } from './pages/CashSummary'
import { SettingsPage } from './pages/Settings' import { SettingsPage } from './pages/Settings'
import type { User } from './types' import type { User } from './types'
@ -18,6 +19,7 @@ function AppRoutes({ user }: { user: User }) {
<Route path="/history" element={<History />} /> <Route path="/history" element={<History />} />
<Route path="/report" element={<MultiDayReport />} /> <Route path="/report" element={<MultiDayReport />} />
<Route path="/floats/*" element={<FloatManagement />} /> <Route path="/floats/*" element={<FloatManagement />} />
<Route path="/safe/*" element={<SafeCount />} />
<Route path="/summary" element={<CashSummary />} /> <Route path="/summary" element={<CashSummary />} />
<Route path="/settings" element={<SettingsPage user={user} />} /> <Route path="/settings" element={<SettingsPage user={user} />} />
<Route path="*" element={<Navigate to="/daily" replace />} /> <Route path="*" element={<Navigate to="/daily" replace />} />

View file

@ -1,6 +1,6 @@
import { NavLink, useNavigate } from 'react-router-dom' import { NavLink, useNavigate } from 'react-router-dom'
import { import {
Banknote, ClipboardList, BarChart2, Wallet, FileText, Settings, LogOut, Banknote, ClipboardList, BarChart2, Wallet, Vault, FileText, Settings, LogOut,
} from 'lucide-react' } from 'lucide-react'
import type { User } from '../types' import type { User } from '../types'
@ -14,6 +14,7 @@ const navItems = [
{ to: '/history', label: 'History', icon: ClipboardList }, { to: '/history', label: 'History', icon: ClipboardList },
{ to: '/report', label: 'Weekly Report', icon: BarChart2 }, { to: '/report', label: 'Weekly Report', icon: BarChart2 },
{ to: '/floats', label: 'Float Management', icon: Wallet }, { to: '/floats', label: 'Float Management', icon: Wallet },
{ to: '/safe', label: 'Safe Count', icon: Vault },
{ to: '/summary', label: 'Cash Summary', icon: FileText }, { to: '/summary', label: 'Cash Summary', icon: FileText },
{ to: '/settings',label: 'Settings', icon: Settings }, { to: '/settings',label: 'Settings', icon: Settings },
] ]

View file

@ -16,7 +16,7 @@ const TYPE_LABELS: Record<CountType, string> = {
// Denominations relevant for each type (change_tin uses bags, no £0.02/£0.01) // Denominations relevant for each type (change_tin uses bags, no £0.02/£0.01)
const CHANGE_TIN_DENOMS = GBP_DENOMINATIONS.filter(d => d.value >= 0.05) const CHANGE_TIN_DENOMS = GBP_DENOMINATIONS.filter(d => d.value >= 0.05)
function FloatCountForm({ type }: { type: CountType }) { export function FloatCountForm({ type }: { type: CountType }) {
const navigate = useNavigate() const navigate = useNavigate()
const [denomQtys, setDenomQtys] = useState<Record<number, number>>({}) const [denomQtys, setDenomQtys] = useState<Record<number, number>>({})
const [receipts, setReceipts] = useState<Array<{ amount: string; description: string }>>([]) const [receipts, setReceipts] = useState<Array<{ amount: string; description: string }>>([])
@ -173,7 +173,7 @@ function FloatCountForm({ type }: { type: CountType }) {
) )
} }
function FloatHistory({ type }: { type: CountType }) { export function FloatHistory({ type }: { type: CountType }) {
const [rows, setRows] = useState<FloatCount[]>([]) const [rows, setRows] = useState<FloatCount[]>([])
const [total, setTotal] = useState(0) const [total, setTotal] = useState(0)
const [offset, setOffset] = useState(0) const [offset, setOffset] = useState(0)
@ -279,9 +279,8 @@ function FloatHistory({ type }: { type: CountType }) {
export function FloatManagement() { export function FloatManagement() {
const tabs: Array<{ path: string; label: string; type: CountType }> = [ const tabs: Array<{ path: string; label: string; type: CountType }> = [
{ path: 'petty-cash', label: 'Petty Cash', type: 'petty_cash' }, { path: 'petty-cash', label: 'Petty Cash', type: 'petty_cash' },
{ path: 'change-tin', label: 'Change Tin', type: 'change_tin' }, { path: 'change-tin', label: 'Change Tin', type: 'change_tin' },
{ path: 'safe-cash', label: 'Safe Cash', type: 'safe_cash' },
] ]
return ( return (

View file

@ -0,0 +1,14 @@
import { Routes, Route, Navigate } from 'react-router-dom'
import { FloatCountForm, FloatHistory } from './FloatManagement'
export function SafeCount() {
return (
<div style={{ padding: '1.5rem' }}>
<Routes>
<Route index element={<FloatCountForm type="safe_cash" />} />
<Route path="history" element={<FloatHistory type="safe_cash" />} />
<Route path="*" element={<Navigate to="" replace />} />
</Routes>
</div>
)
}