Show refunds as refunds in transaction breakdown checklist

Refunds were rendered like payments (abs value, no marker). Backend now
flags items with is_refund from NewBook item_type (refunds_raised /
refunds_voided) and labels the type '-refund'; frontend shows them in
red with a leading minus.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-09-21 10:50:06 +00:00
parent b750004714
commit af1560d58f
3 changed files with 11 additions and 4 deletions

View file

@ -279,7 +279,8 @@ export function parseTransactionBreakdown(rawData) {
const desc = t.item_description || '' const desc = t.item_description || ''
const payType = t.payment_type || '' const payType = t.payment_type || ''
const isVoided = t.item_type === 'payments_voided' || t.item_type === 'refunds_voided' const isVoided = t.item_type === 'payments_voided' || t.item_type === 'refunds_voided'
const displayType = isVoided ? payType + ' -void' : payType const isRefund = t.item_type === 'refunds_raised' || t.item_type === 'refunds_voided'
const displayType = (isRefund ? payType + ' -refund' : payType) + (isVoided ? ' -void' : '')
const category = categorise(payType) const category = categorise(payType)
const item = { const item = {
@ -288,6 +289,7 @@ export function parseTransactionBreakdown(rawData) {
details: '', details: '',
amount: parseFloat(t.item_amount || 0), amount: parseFloat(t.item_amount || 0),
is_voided: isVoided, is_voided: isVoided,
is_refund: isRefund,
} }
const ticketMatch = desc.match(/^Ticket:\s*(\d+)\s*-\s*(.+)$/i) const ticketMatch = desc.match(/^Ticket:\s*(\d+)\s*-\s*(.+)$/i)

View file

@ -929,6 +929,8 @@ function TransactionChecklist({ breakdown, checked, onToggle }: {
{items.map((item, i) => { {items.map((item, i) => {
const key = `${section}:${category}:${i}` const key = `${section}:${category}:${i}`
const isDone = checked.has(key) const isDone = checked.has(key)
// Refunds are a transaction type, not a negative value — amount stays positive
const isRefund = item.is_refund
return ( return (
<div key={key} onClick={() => onToggle(key)} style={{ <div key={key} onClick={() => onToggle(key)} style={{
display: 'grid', gridTemplateColumns: '20px 1fr auto auto', display: 'grid', gridTemplateColumns: '20px 1fr auto auto',
@ -949,9 +951,11 @@ function TransactionChecklist({ breakdown, checked, onToggle }: {
<span style={{ fontSize: '0.7rem', color: 'var(--text-mid)', marginLeft: '0.5rem' }}>{item.time.slice(11, 16)}</span> <span style={{ fontSize: '0.7rem', color: 'var(--text-mid)', marginLeft: '0.5rem' }}>{item.time.slice(11, 16)}</span>
)} )}
</div> </div>
<span style={{ fontSize: '0.7rem', color: 'var(--text-mid)' }}>{item.payment_type}</span> <span style={{ fontSize: '0.7rem', color: 'var(--text-mid)' }}>
<span style={{ fontSize: '0.8rem', fontWeight: 600, color: item.is_voided ? 'var(--danger)' : undefined }}> {item.payment_type}
{item.is_voided ? '-' : ''}{fmtGBP(Math.abs(item.amount))} </span>
<span style={{ fontSize: '0.8rem', fontWeight: 600, color: item.is_voided || isRefund ? 'var(--danger)' : undefined }}>
{item.is_voided || isRefund ? '-' : ''}{fmtGBP(Math.abs(item.amount))}
</span> </span>
</div> </div>
) )

View file

@ -75,6 +75,7 @@ export interface TransactionItem {
details: string details: string
amount: number amount: number
is_voided: boolean is_voided: boolean
is_refund: boolean
} }
export interface TransactionBreakdown { export interface TransactionBreakdown {