# Salesman Van Mobile App

## Existing customer profile completion — 2026-08-16

Approved customer details provide **Update Customer Information**, reusing onboarding sections. Salesmen may update contact/location/legal/VAT/security-cheque evidence and notes, but cannot edit account type, lifecycle or approved credit controls. Incomplete profiles remain invoice eligible. Checkout offers ON ACCOUNT (default) and CASH for every approved active customer.

## Checkout stabilization — 2026-08-16

Flutter persists and submits only the explicit master `product_id`; it no longer treats a catalog row `id` as a product fallback. Checkout calls `/orders/preflight` immediately before creating the draft. Price/source/stock changes stop checkout with a readable affected-SKU message and never silently change quantity.

## Stock Replenishment

Salesmen select Main/Clearance products, see own VAN quantity and evidence-based 30-day demand, save/resume Drafts, copy/PDF, submit, track and receive their own shipment. Managers review and action the same workflow. The shared barcode scanner is reused.

## Customer applications

The list contains active approved customers and the authenticated salesman's own applications. Only approved active records are invoice-selectable. Draft/needs-changes are editable; submitted/under-review are locked. Territory options and private documents are authorized by Laravel.

For On Account submissions, Laravel requires the existing private `security_cheque` document plus bank, cheque number, account holder and positive amount. `security_cheque_undated=true` permits a null date; otherwise the cheque date is mandatory. Cash submissions have no cheque requirement. The mobile payload and customer review payload expose the metadata, but never a public document URL.

Editable Draft and Needs Changes records remain Laravel-authoritative. The customer list payload includes the complete onboarding state and current private-document metadata so Flutter can offer Resume Draft and restore the form. Switching to Cash persists `requested_account_type=cash` and clears stale credit/cheque metadata; approval independently persists the administrator's explicit final `account_type`.

Flutter Path

/Users/scarmac/Documents/Develop/snyt_van_app

Current Status

✓ Login

✓ Dashboard

✓ Van Boxes

✓ Box Details

Next

- Mobile API Login
- Dashboard
- Boxes
- Products
- Barcode Scanner
- Offline Mode

<!-- SNYT_MOBILE_BASELINE_START -->

## Current SNYT Van Baseline - 2026-08-08

Current release baseline: `1.1.0+2`.

Implemented or present in the current Flutter source:

- Login, auto-login, and logout
- Salesman and manager navigation
- Dashboard
- Main / Clearance / Salesman / unified catalog flows
- Product search and product details
- Product source / fulfillment support
- Persistent cart
- Customers and customer-location work
- Saved Customer and Walk-in checkout
- Draft order creation
- My Orders and order details
- Confirm / Cancel / Deliver order lifecycle
- Authenticated order PDF printing
- My Van
- Barcode scanner
- Inventory Check
- Chat / conversations
- Manager dashboard and team views
- Sales routes / operations foundation
- Sales Hub and sales tools
- Daily Sales Report
- Smart Import mobile flow
- Quote builder / export foundation

### Backend authority

Flutter may display previews and local UI state, but Laravel remains authoritative for persisted orders, sellable stock, stock movements, invoice type, discount eligibility, discount percentage, taxable amount, VAT, and final invoice totals.

### Approved next Flutter work

- RMA / Customer Returns
- RMA warehouse handover
- Incremental Warehouse Stock Receiving
- PDF-assisted stock receiving
- Cash / On Account invoice selection
- Laravel-configured Cash discount display
- Clearance discount exclusion
- Invoice editing before delivery
- Unified release builder with version / build-number increment and rollback archive

<!-- SNYT_MOBILE_BASELINE_END -->

<!-- SNYT_RETURNS_RMA_MOBILE_V1_START -->
## Returns Mobile Integration

The Flutter application now includes a dedicated **Returns** top-level navigation destination.

Implemented screens:

- Returns list with search and status/type filters.
- New Return draft.
- Customer Return / Resellable selector.
- RMA / Defective selector.
- SKU/name/barcode live search.
- Barcode scanner.
- Multi-item return documents.
- Optional return photos.
- Direct replacement from van for RMA items when sellable stock is available.
- Return details with independent operational and financial status.
- Admin/Supervisor accounting review from mobile.
- RMA handover batches.
- Warehouse dispatch and confirmation.
- A4 handover PDF printing.
- Customer profile tabs for Sales / Returns / Payments.

The app-wide visual system is updated to the approved dark SNYT style: deep navy/black surfaces, cyan primary actions, teal success states, amber accounting states, red RMA states, bordered cards, and compact mobile-first layouts.
<!-- SNYT_RETURNS_RMA_MOBILE_V1_END -->
## Returns mobile hardening — 2026-08-09

- Flutter and Laravel now use the same `item_ids` handover payload.
- Opening RMA remains an atomic sellable-to-RMA reclassification.
- Laravel remains authoritative for quantity, ownership, settlement, and customer-invoice validation.
## Explicit Return review workflow

Mobile saves a Draft, submits it explicitly, and then exposes Approve/Reject only to admin/supervisor users. An unsubmitted Draft is excluded from warehouse handover.
## RMA Stock authorization and handover

Salesmen see only their own RMA balance. Admin/supervisor users may view all or filter by salesman. Ready quantity can enter the existing handover workflow; prepared, in-transit, and warehouse-confirmed quantities cannot be selected again.

## Warehouse handover audit trail

Laravel now records the originating handover batch directly on every new warehouse dispatch and rejected-quantity restoration stock movement. This is an audit-only relation: movement quantities, stock calculations, Flutter actions, and existing Return workflow rules are unchanged. Historical movements are intentionally left without a handover ID where the association cannot be proven.

## Opening RMA reclassification

`POST /api/mobile/returns/opening-rma` accepts required `client_uuid`, `product_id`, positive `qty`, and optional notes. It requires no customer and creates no Customer Return. Laravel locks the salesman's current sellable stock, rejects unavailable/insufficient/foreign stock, moves Sellable VAN to RMA atomically, and returns fresh balances. Duplicate UUIDs return the prior result. Flutter uses the existing stable scanner/manual-entry lifecycle and confirms before submission.
