Files
service-finder/docs/cost_ui_audit.md
2026-06-23 21:11:21 +00:00

178 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cost UI Audit Report — Dashboard Cost Actions & Existing Cost Forms
**Date:** 2026-06-21
**Author:** Fast Coder (Core Developer)
**Scope:** P0 READ & PLAN — Dual-Entry Cost System UX Audit
**Status:** Audit Complete — No code modified
---
## 1. Dashboard Cost Actions Card (`CostsActionsCard.vue`)
**File:** [`frontend/src/components/dashboard/CostsActionsCard.vue`](frontend/src/components/dashboard/CostsActionsCard.vue)
### Current Template Structure
The card is a 350px-tall bento-grid tile with:
| Element | Description |
|---------|-------------|
| **Header** | Dark slate bar with `💰` icon + `t('dashboard.costsTitle')` label |
| **Vehicle Selector** | `<select>` dropdown listing all `vehicleStore.sortedVehicles` by license plate + brand/model |
| **No Vehicle Warning** | Amber alert box shown when no vehicle is selected |
| **⛽ Record Fueling** | Big gradient button (sf-accent→emerald) — calls `openFuelModal()` |
| **🅿️ Parking / Toll** | Medium secondary button — calls `openFeeModal()` |
| ** Additional Costs** | Medium secondary button — calls `openComplexModal()` |
### Events Emitted
- **`cost-saved`** — Emitted with `vehicleId: string` after any modal saves successfully. Parent (`DashboardView`) forwards this to `VehicleDetailModal` to trigger cost refresh.
### Modals Opened
| Modal | Trigger | Mode |
|-------|---------|------|
| `SimpleFuelModal` | `openFuelModal()` | Fuel entry (liters, odometer) |
| `ComplexExpenseModal` (Fee mode) | `openFeeModal()` | `isFeeMode=true` → Parking/Toll |
| `ComplexExpenseModal` (Complex mode) | `openComplexModal()` | `isFeeMode=false` → Full category cascade |
### Key Observations
-**Quick Actions exist** for Fuel, Parking/Toll, and "Other" costs.
-**No "Invoice / Számla" button** — there is no deep-entry wizard for supplier invoices with line items.
-**No supplier field, no invoice number, no VAT breakdown** in any of the current modals.
- ✅ The card is well-structured and uses a clean vehicle selector + action button pattern.
---
## 2. Existing Cost Form Audit
### 2.1 `SimpleFuelModal.vue`
**File:** [`frontend/src/components/dashboard/SimpleFuelModal.vue`](frontend/src/components/dashboard/SimpleFuelModal.vue)
| Field | Type | Required |
|-------|------|----------|
| Vehicle (read-only) | Display | — |
| Date | `date` input | ✅ |
| Amount (HUF) | `number` | ✅ |
| Quantity (Liters/kWh) | `number` | ✅ |
| Odometer | `number` | ❌ |
**Payload:** `asset_id`, `category_id` (FUEL resolved by code), `amount_gross`, `currency`, `date`, `mileage_at_cost`, `description`, `data.quantity`, `data.fuel_type`.
### 2.2 `ComplexExpenseModal.vue`
**File:** [`frontend/src/components/dashboard/ComplexExpenseModal.vue`](frontend/src/components/dashboard/ComplexExpenseModal.vue)
| Field | Type | Required |
|-------|------|----------|
| Vehicle (read-only) | Display | — |
| Date | `date` input | ✅ |
| Amount (HUF) | `number` | ✅ |
| Main Category | `<select>` cascade | ✅ (if not fee mode) |
| Sub Category | `<select>` cascade | ✅ (if available) |
| Description / Notes | `<textarea>` | ❌ |
| Recurring Toggle | Checkbox | ❌ (hidden in fee mode) |
**Dual Mode:**
- `isFeeMode=true` → Pre-fills category as FEES (code lookup), hides category cascade.
- `isFeeMode=false` → Full category cascade from `/dictionaries/cost-categories`.
### 2.3 `CostManagerModal.vue`
**File:** [`frontend/src/components/cost/CostManagerModal.vue`](frontend/src/components/cost/CostManagerModal.vue)
This is a **read-only cost list viewer**, not an entry form. It displays paginated costs from `/expenses` with date, type badge, amount, vehicle, and description columns. No create/edit functionality.
### 2.4 `FinancialsTab.vue` (Vehicle Detail)
**File:** [`frontend/src/components/vehicles/tabs/FinancialsTab.vue`](frontend/src/components/vehicles/tabs/FinancialsTab.vue)
Shows **purchasing/leasing financials** (purchase price, down payment, monthly installment, contract number, etc.). This is about vehicle acquisition financing, not operational cost entry.
### 2.5 `FinancialCard.vue` (Dashboard)
**File:** [`frontend/src/components/dashboard/FinancialCard.vue`](frontend/src/components/dashboard/FinancialCard.vue)
Shows wallet/credit balance (purchased credits, service coins, earned, voucher). No cost entry functionality.
---
## 3. Gap Analysis: What's Missing for Dual-Entry Cost System
### Current State (Quick Actions Only)
| Feature | Status |
|---------|--------|
| Fuel entry (liters + odometer) | ✅ `SimpleFuelModal` |
| Parking / Toll quick entry | ✅ `ComplexExpenseModal` (fee mode) |
| Other cost with category cascade | ✅ `ComplexExpenseModal` (complex mode) |
| Recurring cost toggle | ✅ In complex mode |
| **Supplier / Vendor field** | ❌ **Missing** |
| **Invoice number** | ❌ **Missing** |
| **Invoice date (separate from cost date)** | ❌ **Missing** |
| **VAT amount / VAT rate** | ❌ **Missing** |
| **Net amount (split from gross)** | ❌ **Missing** |
| **Line items (multi-item invoice)** | ❌ **Missing** |
| **Document upload (PDF invoice)** | ❌ **Missing** |
| **Payment due date** | ❌ **Missing** |
| **Cost center / department allocation** | ❌ **Missing** |
### Verdict: Build from Scratch or Extend?
**Recommendation: BUILD FROM SCRATCH** for the Deep Wizard (`CostEntryWizard.vue`).
**Rationale:**
1. The existing `ComplexExpenseModal` is tightly coupled to the "quick entry" paradigm — single amount, single category, no supplier.
2. Adding supplier + invoice number + VAT + line items would require a complete form rewrite anyway.
3. The Quick Actions (Fuel, Parking, Other) are **perfect as-is** for the "Dual-Entry" left side. They should remain untouched.
4. The Deep Wizard should be a **new, separate component** (`CostEntryWizard.vue`) with multi-step or multi-section layout:
- **Step 1:** Vehicle + Supplier + Invoice metadata
- **Step 2:** Line items (category, net, VAT, gross)
- **Step 3:** Document upload + Review
---
## 4. Proposed Architecture for Dual-Entry Cost System
```
┌─────────────────────────────────────────────────────┐
│ CostsActionsCard.vue (EXISTING) │
│ │
│ ┌──────────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ ⛽ Fuel │ │ 🅿️ Park │ │ Other │ │
│ │ (Quick) │ │ (Quick) │ │ (Quick) │ │
│ └──────────────┘ └──────────┘ └───────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 📄 Invoice / Számla (Deep Wizard) [NEW] │ │
│ │ → Opens CostEntryWizard.vue │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
```
### New Component: `CostEntryWizard.vue`
- **Location:** `frontend/src/components/cost/CostEntryWizard.vue`
- **Trigger:** New "📄 Invoice" button on `CostsActionsCard`
- **Features:**
- Supplier autocomplete (from `/providers` API)
- Invoice number + invoice date
- Net amount + VAT amount + Gross amount (auto-calc)
- Multi-line item support (dynamic rows)
- Category cascade (reuse from `ComplexExpenseModal`)
- Document upload (PDF/image)
- Payment due date
- Notes field
---
## 5. Summary
| Aspect | Finding |
|--------|---------|
| **Quick Actions** | ✅ Fully functional for Fuel, Parking/Toll, Other costs |
| **Deep Invoice Entry** | ❌ Does not exist — must be built as `CostEntryWizard.vue` |
| **Reusable Form Parts** | ⚠️ Category cascade logic can be extracted from `ComplexExpenseModal` |
| **Supplier Data** | ✅ Provider API exists (`/providers`) — can be reused |
| **Backend Readiness** | ⚠️ Need to verify if `asset_costs` table supports `supplier_id`, `invoice_number`, `vat_amount`, `net_amount` fields |