Cashup: fix change tin count — use bag values not coin face values
Qty entered for coins = number of bags, so total = BAG_VALUES[denom] × qty not denom × qty. Fixes totalCounted, row totals, change order counted column, and save payload. Also shows £X/bag hint under coin denomination labels. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8193b05acc
commit
4b0b73c520
1 changed files with 14 additions and 6 deletions
|
|
@ -237,7 +237,10 @@ export function FloatCountForm({ type }: { type: CountType }) {
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}, [type])
|
}, [type])
|
||||||
|
|
||||||
const totalCounted = denoms.reduce((s, d) => s + d.value * (denomQtys[d.value] ?? 0), 0)
|
function unitVal(d: { value: number }) {
|
||||||
|
return type === 'change_tin' ? (BAG_VALUES[d.value] ?? d.value) : d.value
|
||||||
|
}
|
||||||
|
const totalCounted = denoms.reduce((s, d) => s + unitVal(d) * (denomQtys[d.value] ?? 0), 0)
|
||||||
const totalReceipts = receipts.reduce((s, r) => s + (parseFloat(r.amount) || 0), 0)
|
const totalReceipts = receipts.reduce((s, r) => s + (parseFloat(r.amount) || 0), 0)
|
||||||
const targetAmount = type === 'petty_cash' ? pettyTarget : type === 'change_tin'
|
const targetAmount = type === 'petty_cash' ? pettyTarget : type === 'change_tin'
|
||||||
? Object.entries(changeTinTargets).reduce((s, [, v]) => s + (v || 0), 0)
|
? Object.entries(changeTinTargets).reduce((s, [, v]) => s + (v || 0), 0)
|
||||||
|
|
@ -252,7 +255,7 @@ export function FloatCountForm({ type }: { type: CountType }) {
|
||||||
try {
|
try {
|
||||||
const denominations = denoms.filter(d => (denomQtys[d.value] ?? 0) > 0).map(d => ({
|
const denominations = denoms.filter(d => (denomQtys[d.value] ?? 0) > 0).map(d => ({
|
||||||
denomination: d.value, quantity: denomQtys[d.value] ?? 0, bag_quantity: 0,
|
denomination: d.value, quantity: denomQtys[d.value] ?? 0, bag_quantity: 0,
|
||||||
total: d.value * (denomQtys[d.value] ?? 0),
|
total: unitVal(d) * (denomQtys[d.value] ?? 0),
|
||||||
}))
|
}))
|
||||||
const result = await api.post<{ count_id: number }>('/floats/save', {
|
const result = await api.post<{ count_id: number }>('/floats/save', {
|
||||||
count_type: type,
|
count_type: type,
|
||||||
|
|
@ -308,10 +311,15 @@ export function FloatCountForm({ type }: { type: CountType }) {
|
||||||
<h2 style={{ fontSize: '0.875rem', fontWeight: 700, marginBottom: '0.75rem', color: 'var(--text-mid)' }}>DENOMINATIONS</h2>
|
<h2 style={{ fontSize: '0.875rem', fontWeight: 700, marginBottom: '0.75rem', color: 'var(--text-mid)' }}>DENOMINATIONS</h2>
|
||||||
{denoms.map(d => {
|
{denoms.map(d => {
|
||||||
const qty = denomQtys[d.value] ?? 0
|
const qty = denomQtys[d.value] ?? 0
|
||||||
const rowTotal = d.value * qty
|
const uv = unitVal(d)
|
||||||
|
const rowTotal = uv * qty
|
||||||
|
const isBag = type === 'change_tin' && BAG_VALUES[d.value] !== undefined
|
||||||
return (
|
return (
|
||||||
<div key={d.value} style={{ display: 'grid', gridTemplateColumns: '64px 1fr 90px', gap: '0.4rem 0.75rem', alignItems: 'center', marginBottom: '0.35rem' }}>
|
<div key={d.value} style={{ display: 'grid', gridTemplateColumns: '80px 1fr 90px', gap: '0.4rem 0.75rem', alignItems: 'center', marginBottom: '0.35rem' }}>
|
||||||
<span style={{ fontWeight: 600, fontSize: '0.875rem' }}>{d.label}</span>
|
<div>
|
||||||
|
<span style={{ fontWeight: 600, fontSize: '0.875rem' }}>{d.label}</span>
|
||||||
|
{isBag && <div style={{ fontSize: '0.65rem', color: 'var(--text-mid)' }}>{fmtGBP(uv)}/bag</div>}
|
||||||
|
</div>
|
||||||
<input type="number" min="0" step="1" value={qty || ''}
|
<input type="number" min="0" step="1" value={qty || ''}
|
||||||
onChange={e => setDenomQtys(prev => ({ ...prev, [d.value]: parseInt(e.target.value) || 0 }))}
|
onChange={e => setDenomQtys(prev => ({ ...prev, [d.value]: parseInt(e.target.value) || 0 }))}
|
||||||
placeholder="0" style={inpSt} />
|
placeholder="0" style={inpSt} />
|
||||||
|
|
@ -380,7 +388,7 @@ export function FloatCountForm({ type }: { type: CountType }) {
|
||||||
const target = parseFloat(String(changeTinTargets[d.value.toFixed(2)] ?? 0))
|
const target = parseFloat(String(changeTinTargets[d.value.toFixed(2)] ?? 0))
|
||||||
if (target <= 0) return null
|
if (target <= 0) return null
|
||||||
const targetUnits = unitVal > 0 ? Math.round(target / unitVal) : 0
|
const targetUnits = unitVal > 0 ? Math.round(target / unitVal) : 0
|
||||||
const counted = d.value * (denomQtys[d.value] ?? 0)
|
const counted = unitVal * (denomQtys[d.value] ?? 0)
|
||||||
const needed = target - counted
|
const needed = target - counted
|
||||||
const orderUnits = needed > 0.005 ? Math.ceil(needed / unitVal) : 0
|
const orderUnits = needed > 0.005 ? Math.ceil(needed / unitVal) : 0
|
||||||
return { d, target, targetUnits, counted, orderUnits, unitLabel }
|
return { d, target, targetUnits, counted, orderUnits, unitLabel }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue