Files
2026-07-12 10:17:17 -04:00

42 lines
2.3 KiB
Markdown

# Recent Quotes Status Derivation (v2)
## The Bug
In the Recent Quotes panel (`src/pages/QuoteGenerator.tsx`), the status badge was showing "Draft" even when ALL services had been decided (approved or declined) by shop staff in the QuoteGenerator.
## Root Cause
The quote's `status` field in PocketBase is only a **lifecycle** field:
- `'draft'` — set on Save (QuoteSummary.tsx:123)
- `'sent'` — set on Share (QuoteSummary.tsx:246)
- `'approved'` / `'declined'` — set by the customer via QuoteApprove.tsx:221-225
When shop staff approve/decline individual services in the QuoteGenerator, the `customerDecision` values are saved inside the services JSON blob, but the quote-level `status` field is NOT updated. It stays `'draft'`.
## The Fix
In `loadRecentQuotes()` (QuoteGenerator.tsx:196), derive the display status from individual service decisions when ALL services have been decided:
```typescript
const hasPending = servicesList.some((s: any) => !s.customerDecision || s.customerDecision === 'pending');
let derivedStatus: QuoteRecord['status'] = record.status;
if (!hasPending && servicesList.length > 0) {
const allApproved = servicesList.every((s: any) => s.customerDecision === 'approved');
const allDeclined = servicesList.every((s: any) => s.customerDecision === 'declined');
if (allApproved) derivedStatus = 'approved';
else if (allDeclined) derivedStatus = 'declined';
}
// Use derivedStatus in the returned object's `status` field
```
This overrides status to:
- `'approved'` — when ALL services have `customerDecision === 'approved'`
- `'declined'` — when ALL services have `customerDecision === 'declined'`
- Keeps original PocketBase status — when some services are still pending, or when decisions are mixed (some approved, some declined)
Because the mapped object's `status` field feeds both the `RecentStatusBadge` component and the filter/count logic (`recentCounts`, `matchesRecentStatusFilter`), this single change fixes the badge, the filter tabs, and the filter counts.
## Also Fixed
The `hasPending` check was previously `servicesList.some(s => s.customerDecision === 'pending')`. A service with no `customerDecision` field at all would NOT be counted as pending. Changed to `servicesList.some(s => !s.customerDecision || s.customerDecision === 'pending')` to handle services that don't have the field yet (edge case with legacy data).