# Testing Checklist

## Stock Receipts

Flutter tests cover numeric API parsing, remaining quantity, completion, and matched/short/excess/damaged classifications. Physical QA must verify upload, parsing, one-hand repeated scans, increment, pause/resume, summary, and that production VAN stock does not change before an intentional confirmation.

## Invoice / checkout stabilization — 2026-08-16

Flutter tests verify catalog membership ID and master product ID remain distinct through Cart serialization. Server coverage verifies Main, Clearance, mixed carts, account types, safe errors, current prices, and stock limits.

## Stock Replenishment v1 closure — 2026-08-15

Closure validation passed on the SM X135G debug build: the salesman sees no admin workflow actions, and Laravel returned 403 for an attempted approve action. Flutter analyze reported no issues and all 13 tests passed. Isolated Laravel Stock + QA completed 18 tests / 134 assertions; the full suite completed 104 passing tests / 606 assertions with only the unchanged unrelated PriceImport fake-PDF failure. Preparation and Receiving PDFs passed production visual QA. Actual camera barcode scanning remains manual/environment blocked.

## Stock Replenishment — 2026-08-15

`dart format .` completed, `flutter analyze` reports no issues, and all 21 Flutter tests pass. SM X135G runtime, Stock Requests empty state, New Request portrait/landscape layout, scanner launch/manual-entry control, keyboard-safe Save Draft, and the extended action fix were verified physically. End-to-end draft/submit/prepare/receive, discrepancy camera evidence persistence and PDF opening remain blocked by the absence of a dedicated safe QA request/data on the production account.

Isolated Laravel completion coverage: Stock Replenishment 10 tests / 58 assertions; combined Customer/Pricing, Returns/RMA and Stock Replenishment regression 44 tests / 298 assertions. Full Laravel: 96 passed / 530 assertions and the unchanged unrelated empty-fake-PDF failure in `PriceImportWorkflowTest`. Preparation and Receiving PDFs were rendered to A4/A4 landscape and visually checked with no clipping or overlap.

QA Dataset coverage: 4 focused tests validate idempotent creation, exact-owner/admin visibility, other-salesman/public isolation, barcode/customer access, QA replenishment, Accepted Qty posting exactly once, dry-run immutability, reset baselines and cleanup protection. QA + Stock + Returns + Customer/Pricing regression: 48 passed / 332 assertions. Full suite: 100 passed / 564 assertions plus the unchanged `PriceImportWorkflowTest` empty fake PDF failure.

- Verify drafts and needs-changes are editable; submitted/under-review are locked.
- Verify pending/rejected/suspended customers cannot be selected at checkout.
- Verify Cash/On Account choice appears only for approved On Account customers.
- Verify regular cash lines receive the configured discount while Clearance lines do not.
- Verify customer Sales/Returns/Payments tabs never show another customer's records.
- Verify Cash onboarding submits without cheque data.
- Verify On Account requires a cheque document, bank, number, account holder and positive amount.
- Verify an undated cheque accepts no date, while a dated cheque requires a valid date.
- Verify the admin review displays cheque metadata and streams the cheque image only through an authorized route.
- Verify submitted applications appear in Customer Applications and salesmen receive 403 for review actions.
- Verify leaving and resuming a Draft restores every section and current document markers.
- Verify On Account → Cash clears/deactivates credit and cheque data and final approval uses the explicit admin account type.

## Authentication

- [ ] Login succeeds
- [ ] Invalid login shows an error
- [ ] Auto login succeeds
- [ ] Logout clears the session

## Dashboard

- [ ] Product count loads
- [ ] Piece count loads
- [ ] Box count loads
- [ ] Dashboard refreshes after stock changes

## Catalogs

- [ ] Main catalog loads
- [ ] Clearance catalog loads
- [ ] Salesman catalog loads
- [ ] Search works
- [ ] Product images load
- [ ] Product details open
- [ ] Van quantity is correct
- [ ] Add to cart works
- [ ] Unavailable product is blocked

## Scanner

- [ ] Barcode scanner opens
- [ ] Valid barcode is detected
- [ ] Duplicate scan is blocked
- [ ] Manual barcode entry works
- [ ] Scanner lifecycle is stable

## My Van

- [ ] Inventory loads
- [ ] Search works
- [ ] Product details open
- [ ] Quantity refreshes after Confirm Sale
- [ ] Quantity refreshes after confirmed-order cancellation

## Customers

- [ ] Customer list loads
- [ ] Search works
- [ ] Customer details open
- [ ] Saved customer can be selected
- [ ] Walk-in customer can be used during checkout

## Cart

- [ ] Cart persists after app restart
- [ ] Quantity can be increased and decreased
- [ ] Maximum van quantity is enforced
- [ ] Cart clears only after draft save succeeds

## Orders

- [ ] Draft order saves
- [ ] Draft appears in My Orders
- [ ] Search works
- [ ] Status filters work
- [ ] Order details load
- [ ] Timeline is correct
- [ ] Confirm Sale deducts stock once
- [ ] Mark Delivered changes status only
- [ ] Cancel Draft does not change stock
- [ ] Cancel Confirmed restores stock
- [ ] Delivered order cannot be cancelled

## Printing

- [ ] Print works from Draft Saved
- [ ] Print works from Order Details
- [ ] Native print dialog opens
- [ ] PDF shows order number
- [ ] PDF shows customer
- [ ] PDF shows salesman
- [ ] PDF shows product photo
- [ ] PDF shows SKU and barcode
- [ ] PDF shows quantity and totals
- [ ] Printing does not deduct stock

<!-- SNYT_RETURNS_RMA_TESTING_FLUTTER_V1_START -->
## Returns / RMA Test Matrix

Required device tests:

1. Create resellable return → verify VAN sellable qty does not change before accountant approval.
2. Approve resellable return → verify sellable qty increases once.
3. Create RMA return → verify returned qty appears only in RMA, not catalog sellable qty.
4. Direct exchange → verify RMA +returned qty and sellable VAN -replacement qty.
5. Edit pre-handover RMA → verify backend reversal/reapply produces correct final quantity.
6. Dispatch handover → verify RMA leaves in-van bucket.
7. Partially reject handover → verify rejected qty returns to salesman RMA.
8. Print handover → verify A4 table and signature areas.
9. Customer profile → verify Sales and Returns are customer-scoped.
<!-- SNYT_RETURNS_RMA_TESTING_FLUTTER_V1_END -->

<!-- SNYT_ANALYZER_BACKUP_RULE_V1 -->
## Analyzer and Internal Backups

Internal source backups under `project_backups/` and release archives under `releases/` are intentionally excluded from `flutter analyze`. They are rollback artifacts, not active application source. Active code under `lib/` and tests under `test/` remain analyzed normally.


## Returns / RMA v1 Baseline - 2026-08-08

Revalidated on 2026-08-09 after the handover contract, accounting validation, and Opening RMA changes:

- `flutter analyze`: PASS — No issues found.
- `flutter test`: PASS — 9 tests passed.

Validation completed:

- flutter analyze: PASS — No issues found
- flutter test: PASS — 9 tests passed

Next QA stage:

- Device UI validation
- Customer Return / Resellable workflow
- Accountant approval
- Defective / RMA workflow
- Direct replacement
- Opening RMA reclassification
- Warehouse handover
- Partial warehouse acceptance
- Rejected quantity restoration
## Explicit Return workflow — 2026-08-09

- Flutter analyzer: no issues.
- Flutter tests: all 9 passed.
- Laravel focused test source covers draft, submit, duplicate submit, approval, duplicate approval stock safety, rejection reason/RMA preservation, edit lock, and ownership isolation.
- Production server cannot execute PHPUnit because development test dependencies are not installed.
## RMA Stock validation — 2026-08-09

- Flutter model tests cover RMA item balance and summary parsing.
- `flutter analyze`: PASS — no issues.
- `flutter test`: PASS — 11 tests.
- Laravel test source covers ownership isolation, admin filtering, balance states, confirmed exclusion, Opening RMA, rejected restoration, and approve/reject authorization.
- Production PHPUnit remains unavailable because Composer dev dependencies are intentionally absent.
## Returns / RMA isolated validation — 2026-08-09

- Environment: isolated Laravel clone outside `public_html` at `/home/snyt/test-environments/catalog-returns-rma-20260809`.
- Database: SQLite test database / PHPUnit in-memory SQLite; production database was never used.
- Related Laravel suite: 16 tests, 100 assertions, all passed.
- Flutter suite: 14 tests, all passed; analyzer reports no issues.
- Added coverage for all 21 agreed workflow scenarios, stock invariants, movement audit, and manual settlement cases.
- The complete Laravel suite produced 51 passes and one unrelated existing failure in `PriceImportWorkflowTest` because a fake empty PDF reaches the PDF parser instead of returning the expected validation error.
- Warehouse movement audit patch: `van_stock_movements.return_handover_id` now directly identifies the handover batch for dispatch and rejected-quantity restoration movements.
- Related Laravel suite after the patch: 16 tests, 106 assertions, all passed; all 21 Returns/RMA scenarios remain passing.
- Full Laravel suite after the patch: 51 passed and one unchanged, unrelated `PriceImportWorkflowTest` failure.
- Historical movement rows remain `NULL` because a deterministic handover association cannot be proven safely from existing data.

## Android runtime and release validation — 2026-08-09

- Root cause repaired: the manifest declared `.MainActivity`, but no Android activity source existed.
- Restored Flutter embedding v2 activity as `xyz.snyt.vanapp.MainActivity`.
- Physical SM X135G validation: Dart VM attached, existing session restored, Dashboard rendered, and Returns, Customers, and Catalog opened successfully.
- Current process log: no fatal or unhandled Flutter exception.
- `flutter analyze`: PASS — no issues.
- `flutter test`: PASS — 15 tests, including a 390×844 phone-sized foundation render check.

## Full Flutter visual QA — 2026-08-09

- Physical device: Samsung SM X135G, 800×1340 rendered surface.
- Verified the complete reachable salesman navigation path, responsive tablet grids, horizontal filters, detail screens, forms, loading/empty states, scanner camera, map tiles, and fixed bottom actions.
- Final runtime pass after the shared-card repair produced no Flutter framework exception, RenderFlex overflow, fatal exception, or unhandled Dart exception.
- `dart format .`: PASS — 120 files, no pending formatting changes.
- `flutter analyze`: PASS — no issues.
- `flutter test`: PASS — 15 tests, including a 390×844 phone-sized foundation render check.
- Manager/admin-only and post-transaction success/review screens were not reachable from the active salesman session; their source compiles and their shared visual tokens were checked without bypassing permissions or creating business records.
## Customer onboarding + Cash / On Account validation — 2026-08-09

Validation used the isolated Laravel environment at `/home/snyt/test-environments/catalog-returns-rma-20260809`; no production records were created or changed.

| # | Scenario | Result | Validation method |
|---:|---|---|---|
| 1 | Customers list | PASS | `AllWebPagesSmokeTest` plus Flutter Customers source/widget foundation inspection |
| 2 | Customer data isolation | PARTIAL | `CustomerDataIsolationTest` proves orders and salesman ownership; dedicated payments isolation fixture is not present |
| 3 | Create Cash Customer Draft | PARTIAL | `CustomerOnboardingWorkflowTest::test_salesman_can_save_submit_and_admin_approve_exactly_once`; physical document-form editing remains manual |
| 4 | Territory restriction | PASS | `CustomerOnboardingWorkflowTest::test_application_outside_salesman_territory_is_rejected` and allowed-area workflow |
| 5 | Document upload | PARTIAL | Private local storage, MIME and 15 MB rules inspected; camera and representative file uploads require manual QA |
| 6 | VAT conditional fields | PARTIAL | `CustomerOnboardingService::submit` inspected; dedicated yes/no fixture assertions are still required |
| 7 | Cash Customer Submit | PASS | onboarding workflow test proves submit timestamp, freeze, and pending customer invoice rejection |
| 8 | Admin approval — Cash | PARTIAL | approval idempotency/code preservation is tested; existing test finishes as On Account, so a dedicated Cash approval assertion remains |
| 9 | Cash customer invoice restriction | PASS | authoritative `CustomerOrderService` guard plus focused pricing suite |
| 10 | Cash pricing — normal product | PASS | mixed cash pricing test proves 100 less 5%, VAT-inclusive calculation and item snapshot |
| 11 | Cash pricing setting change + snapshot | PARTIAL | persisted snapshot fields inspected; dedicated 5%→4% regression test remains |
| 12 | Create On Account customer | PARTIAL | onboarding approval test covers approved terms; full cheque draft payload requires dedicated fixture |
| 13 | Security cheque conditional requirements | PASS | focused tests cover required private document/core metadata, undated null date, dated missing/valid date, persistence and authorized admin review |
| 14 | Needs Changes workflow | PASS | `test_submitted_application_is_frozen_and_needs_changes_can_be_resubmitted` |
| 15 | Reject workflow | PASS | `test_rejection_preserves_application_and_reason` and pending invoice guard |
| 16 | Admin approval — On Account | PASS | onboarding workflow test asserts approved/active, stable code and retained account type/limits |
| 17 | On Account default invoice type | PASS | authoritative default in `CustomerOrderService`; Cash remains accepted for On Account customers |
| 18 | On Account pricing | PARTIAL | no-discount path is covered; dedicated exact 100/95.24/4.76 assertions remain |
| 19 | On Account customer creates Cash invoice | PASS | mixed cash pricing test starts with an On Account customer and preserves account snapshot |
| 20 | Clearance Cash exclusion | PASS | mixed cash test proves zero clearance discount with VAN fulfillment |
| 21 | Mixed Cash invoice | PASS | `test_cash_discount_excludes_clearance_and_preserves_vat_inclusive_snapshots` proves 200/5/195 and VAT 9.29 |
| 22 | Maximum Single Order | PARTIAL | over-limit block is tested; exact-boundary allow needs a dedicated assertion |
| 23 | Pending customer cannot invoice | PASS | `test_pending_or_suspended_customer_cannot_be_invoiced` plus authoritative eligibility predicate |
| 24 | Suspended customer | PARTIAL | suspended block is tested; reactivation and historical visibility remain manual/dedicated QA |
| 25 | Duplicate warning | PARTIAL | warning-only endpoint and four signals inspected; normalization edge cases require dedicated API assertions |
| 26 | Repeated phone numbers | PARTIAL | fields have no mutual-uniqueness rule; dedicated submission fixture remains |
| 27 | Google Maps / location | PARTIAL | model/API fields and coordinate validation inspected; physical GPS UX is manual |
| 28 | Customer detail tabs | PARTIAL | Flutter tabs and customer-scoped order/return requests inspected; dedicated payments/returns leakage assertions remain |
| 29 | Private document security | PARTIAL | authenticated ownership guard and private local disk inspected; three-way HTTP fixture remains |
| 30 | Cash order/invoice details | PASS | pricing test verifies persisted invoice type, gross, discount, final, taxable/VAT snapshots |
| 31 | Cash PDF | PARTIAL | real invoice template/render route inspected; content-level PDF extraction test remains |
| 32 | On Account PDF | PARTIAL | same real render path and invoice label inspected; generated-content assertion remains |
| 33 | Clearance line in Cash PDF | PARTIAL | item snapshots and template bindings inspected; extracted PDF line assertion remains |
| 34 | Historical pricing snapshot | PARTIAL | immutable stored snapshot architecture inspected; dedicated settings-change/reload regression remains |
| 35 | Final Flutter UI/runtime validation | PARTIAL | physical SM X135G launch passed with no Flutter fatal/overflow log; authenticated screen-by-screen and keyboard/camera flows remain manual |

Automated results: focused Customer/Pricing 10 tests, 31 assertions, all passed; Returns/RMA 16 tests, 106 assertions, all passed; Flutter 18 tests, all passed; `flutter analyze` reported no issues. Full Laravel: 61 passed and one unrelated known `PriceImportWorkflowTest` failure caused by the empty fake PDF fixture (left untouched). No production code or data was deployed.
## Customer + Pricing QA coverage hardening — 2026-08-09

This matrix supersedes the earlier Customer validation matrix below. Automated tests use the isolated Laravel SQLite environment; device checks used the authenticated SM X135G without creating business transactions.

| # | Scenario | Result | Deterministic proof / remaining human action |
|---:|---|---|---|
| 1 | Customers list | PASS | Smoke test plus authenticated physical Customers list/search/action load |
| 2 | Customer data isolation | PARTIAL | Orders, Returns, Documents and salesman ownership are automated; no authoritative Payments backend model exists |
| 3 | Create Cash Customer Draft | PASS | Complete persisted/editable Cash draft fixture with legal-document reference |
| 4 | Territory restriction | PASS | Allowed territory and authoritative rejection automated |
| 5 | Document upload | PARTIAL | JPG/PNG/PDF, invalid MIME, oversize, private storage and version replacement automated; human must assess camera UX |
| 6 | VAT conditional fields | PASS | VAT NO, missing TRN, missing certificate and valid VAT submission automated |
| 7 | Cash Customer Submit | PASS | Submit, freeze and invoice eligibility automated |
| 8 | Admin approval — Cash | PASS | Active Cash account, stable code and duplicate approval automated |
| 9 | Cash customer invoice restriction | PASS | Manipulated On Account request rejected by Laravel |
| 10 | Cash pricing — normal product | PASS | Exact 100/5/95/90.48/4.52 values automated |
| 11 | Pricing setting change + snapshot | PASS | 5%→4% new order and immutable old snapshot automated |
| 12 | On Account draft | PARTIAL | Account type, cheque document, credit limit/days/max order persisted; cheque metadata fields are not implemented |
| 13 | Security cheque rules | PARTIAL | Missing document rejection and Cash exemption automated; dated/undated metadata is not implemented |
| 14 | Needs Changes workflow | PASS | Reason, edit and resubmit automated |
| 15 | Reject workflow | PASS | Reason/audit/ineligibility automated |
| 16 | Admin approval — On Account | PASS | Active/code/terms/limits automated |
| 17 | On Account default invoice type | PASS | Laravel default and Cash alternative automated/source-backed by request tests |
| 18 | On Account pricing | PASS | Exact 100/0/100/95.24/4.76 automated |
| 19 | On Account customer creates Cash invoice | PASS | Cash order and retained account snapshot automated |
| 20 | Clearance Cash exclusion | PASS | VAN fulfillment remains zero-discount when pricing source is Clearance |
| 21 | Mixed Cash invoice | PASS | 200/5/195 and VAT extraction automated |
| 22 | Maximum Single Order | PASS | 999.99 and 1000 allowed; 1000.01 blocked |
| 23 | Pending customer cannot invoice | PASS | Laravel eligibility guard automated |
| 24 | Suspended customer | PASS | Historical order retained, new order blocked, reactivation allows order |
| 25 | Duplicate warning | PASS | Shop/phone/TRN/license warning-only responses and no mutation automated |
| 26 | Repeated phone numbers | PASS | Repeated contact values submit successfully |
| 27 | Maps/location | PARTIAL | Exact API round trip and invalid bounds automated; human must assess physical current-location/GPS UX |
| 28 | Customer detail tabs | PARTIAL | Sales/Returns/Documents scoping automated and tabs physically rendered; Payments is placeholder-only |
| 29 | Private document security | PASS | Owner 200, other salesman 403, unauthenticated 401, private path/no public URL automated |
| 30 | Cash invoice details | PASS | Stored invoice and monetary snapshots automated |
| 31 | Cash PDF | PASS | Approved Blade render path asserts CASH and exact totals; final visual print inspection remains on human checklist |
| 32 | On Account PDF | PASS | Approved Blade render path asserts ON ACCOUNT, zero discount and totals |
| 33 | Mixed Cash PDF | PASS | Both SKUs, Clearance marker, line snapshots and 195 total automated |
| 34 | Historical pricing snapshot | PASS | Persisted snapshot value equivalence after settings mutation automated |
| 35 | Flutter runtime | PARTIAL | Customers, New Customer and Customer Details passed on SM X135G with clean logs; human must complete Cart/Checkout/Order Details, keyboard, camera and GPS ergonomics |

Results: 28 PASS, 7 PARTIAL, 0 MANUAL REQUIRED-only, 0 FAIL. Customer/Pricing: 19 tests / 129 assertions passed. Returns/RMA: 16 / 106 passed. Full Laravel: 70 passed and one excluded pre-existing `PriceImportWorkflowTest` empty-fake-PDF failure. Flutter: no analyzer issues; 20 tests passed. Three defects were fixed: VAT-registered submission now requires TRN, onboarding Stepper is responsive without the 800 px overflow, and invoice line totals no longer subtract the Cash discount twice.

## Opening RMA regression — 2026-08-11

- Normal, existing-RMA and full-available-quantity reclassification passed.
- Insufficient, zero, negative and foreign-salesman stock are rejected with no partial movement.
- Duplicate client UUID is idempotent; exactly two balanced audit rows remain.
- Barcode resolution returns fresh balances; unknown and zero-sellable products are blocked.
- Physical total is invariant and no synthetic Customer Return/Item is created.
- Focused Laravel: 6 tests / 37 assertions. Returns/RMA: 22 / 144. Flutter: 21 passed with no analyzer issues.
# Import Center stabilization — 2026-08-16

Laravel Import Center focused coverage passed (8 tests / 37 assertions), PriceImportWorkflow passed (3 / 10), and the full isolated Laravel suite passed (113 / 647). Coverage includes issue decisions, valid-row partial import, atomic Main/Clearance replacement, Price Update, failure rollback, replay safety, centralized Shipment/Van Stock parsing, and legacy uploader redirects.

Async Import Center coverage: the representative 79,444,200-byte workbook completed queued analysis in 36 seconds with persisted `needs_review` results. Request/session/job idempotency, reload during analysis, failure UX, and existing activation safety passed. Final full Laravel suite: 115 tests / 661 assertions.
