Vendor Management mini-PWA (vendors-v3) — CiC Walkthrough URL: https://srv1111289.hstgr.cloud/finance/vendors/ Generated: 2026-06-03 You are testing the Vendor Management mini-PWA in a real browser session. Follow each step exactly. Report findings in the format: ✅ OK / ⚠️ Unexpected / ❌ Failed — with a brief note per item. List all ⚠️ and ❌ at the end under "Issues Found". ROLES & ACCESS ============== harish, pramod → admin (full access; seeded by default) mukesh, shambhu → NO access (should see Access Restricted) ═══════════════════════════════════════════════════════════════════ PART A — AUTH GATE + USER PILL ═══════════════════════════════════════════════════════════════════ A1. Open in fresh incognito tab: https://srv1111289.hstgr.cloud/finance/vendors/ Without any session it MUST redirect to /hub/. ✓ Expected: /hub/ login page shown. A2. Log in at /hub/ as MUKESH (PIN 1111). Then navigate manually to /finance/vendors/. ✓ Expected: full-screen "🔒 Access Restricted" message saying "Vendor Management is restricted. Ask Harish or Pramod to grant access via Admin → Access". A "← Back to Hub" button. A3. Log out, log in as HARISH (PIN 0000), open the Vendor Management tile (🏢) from the Hub home. ✓ Expected: list screen loads with three tiles (Total, Vendors, Family) all showing numbers (not "—"). Header shows the "Vendor Management" title and a user pill "👤 Harish Kumar Lal" on the right. A4. Switch screens: tap "+ Add" bottom-nav button. Verify the user pill "👤 Harish Kumar Lal" is also present in this header. Tap any vendor row to open the Detail screen. Verify the user pill appears on the Detail header too. Tap ✏️ Edit and verify the Form header also shows the pill. ✓ Expected: user pill on ALL 3 headers (list, detail, form). ═══════════════════════════════════════════════════════════════════ PART B — LIST + SEARCH + TYPE FILTER ═══════════════════════════════════════════════════════════════════ B1. On the list screen, observe the count tiles. Note the numbers for: Total, Vendors, Family. ✓ Expected: all three are positive integers (>=2 at minimum). B2. In the search box at top, type: mukesh Wait 1 second for debounce. Observe: - The "list-sub" header text under the title updates to show the row count + the search term. - At least one vendor row matching "mukesh" appears. B3. Clear the search box. Tap the "Family" type chip. ✓ Expected: only rows with "Family" badge show. Header sub shows "X of Y · Family". B4. Tap "All" chip to clear the type filter. Tap "Vendors" chip. ✓ Expected: only blue "Vendor" badged rows show. B5. Type in search box: AABCS (a GST-prefix string — see test data file). - If a vendor was added with that GSTIN, it should match. - If none added yet, you'll see "No vendors match your filter". ✓ Verify the message corresponds to the data state. B6. Type in search box: 9876543210 (a phone number — see test data file). ✓ Expected: matches the vendor with that phone if added. B7. Try a no-match search: zzzzz_does_not_exist ✓ Expected: empty state with "🔎 No vendors match your filter". ═══════════════════════════════════════════════════════════════════ PART C — ADD NEW VENDOR (use sample data #1 from test data file) ═══════════════════════════════════════════════════════════════════ C1. Tap "+ Add" bottom-nav button. ✓ Expected: blank form. Title says "Add Vendor". 11 fields visible. Only "Party / Company name" has the red * required. C2. Tap "Save" with empty name. ✓ Expected: error toast "Name is required". C3. Fill the form using sample data #1 from the test file: Name: Spice Garden Caterers Type: Vendor Proprietor: Rajesh Kumar UPI name: RAJESH KUMAR Phone: 9876510001 Email: contact@spicegarden.in GST: 29ABCDE1234F1Z5 PAN: ABCDE1234F Contact: Rajesh Address: 12, Linking Road, Bandra West, Mumbai 400050 Aliases: Spice Garden, SG Caterers, Rajesh Garden Tap Save. ✓ Expected: green toast "Vendor added ✓". Returns to list. C4. In list, search: spice ✓ Expected: "Spice Garden Caterers" appears with vendor badge, proprietor "Rajesh Kumar" visible in meta, phone "📞 9876510001", GST "GST: 29ABCDE1234F1Z5". C5. Search: 29ABCDE1234F1Z5 (search by GST) ✓ Expected: same vendor matches. C6. Search: rajesh kumar (proprietor) ✓ Expected: matches. C7. Search: SG Caterers (alias) ✓ Expected: matches. ═══════════════════════════════════════════════════════════════════ PART D — DETAIL TABS ═══════════════════════════════════════════════════════════════════ D1. Tap the "Spice Garden Caterers" row → Detail screen opens. ✓ Expected: Title = "Spice Garden Caterers". Sub = "Vendor". Info tab is selected by default. Info card shows all the data you entered. D2. Tap the "Account Ledger" chip. ✓ Expected: 3 tiles (Total paid · Total received · Net balance) showing ₹0.00 each. List shows "No transactions yet". D3. Tap the "Catalog" chip. ✓ Expected: "No products linked yet" empty state with a "🔗 Link a product / service" button at the top. D4. Tap "🔗 Link a product / service". ✓ Expected: bottom-sheet modal opens. Search box at top, list of catalog items (e.g. "Octonum Stall · event · nos · ₹X"). Below: "Can't find it in the catalog? + Add new product / service to catalog". D5. In modal search box type: paneer ✓ Expected: results filter to paneer-related items. D6. Tap any result. ✓ Expected: toast "Linked ✓", modal closes, the catalog list now shows that item with its category/unit and any default price. D7. Tap the linked catalog item row. ✓ Expected: edit modal opens with price + notes fields and an "Unlink" button at left. D8. Type in price: 250, notes: "Per kilo · A-grade only" Save. ✓ Expected: row updates with ₹250 and notes visible. D9. Tap row again. Tap "Unlink". Confirm. ✓ Expected: toast "Unlinked", row gone. D10. Switch to Supplies tab (the new chip). ✓ Expected: 5 date chips at top (All/Today/Week/Month/Quarter). 3 tiles (Lines/Total qty/Total ₹). Empty state because no line-item transfers exist yet for this brand-new vendor. D11. Switch to Rate Card tab. ✓ Expected: "No rate cards set up yet" with "+ Add rate card" button. D12. Switch to Prices tab. ✓ Expected: "No price comparison data yet · Needs at least one line item with a unit price." ═══════════════════════════════════════════════════════════════════ PART E — RATE CARD CRUD ═══════════════════════════════════════════════════════════════════ E1. On Spice Garden's Rate Card tab, tap "+ Add rate card". ✓ Expected: bottom-sheet modal opens. Title "Add rate card". Catalog search at top + agreed-price field + unit + valid-from + valid-to + contract reference + notes. E2. Tap Save with no product selected. ✓ Expected: error toast "Pick a product first". E3. In modal search type: octonum Pick "Octonum Stall" from the results. ✓ Expected: "Selected: Octonum Stall (CAT-001)" indicator below the search. Unit auto-fills to "nos". E4. Fill remaining fields (sample data #11 from test file): Agreed price: 1400 Unit: nos (auto-filled) Valid from: 2026-01-01 Valid to: 2026-12-31 Contract: Contract-2026-Q1 Notes: "Tier-1 negotiated rate; freight included" Tap Save. ✓ Expected: green toast "Rate card added ✓". Modal closes. List shows 1 rate card row with the product name, "current" green badge, "01 Jan 2026 → 31 Dec 2026", "📄 Contract-2026-Q1", and "₹ 1,400.00 / nos" on the right. E5. Tap the rate card row. ✓ Expected: edit modal opens. Search box is disabled (shows the selected product, locked). Deactivate button visible at left. E6. Change "Agreed price" to 1350. Save. ✓ Expected: row updates with ₹1,350. E7. Open it again, tap "Deactivate". Confirm. ✓ Expected: toast "Deactivated". Row disappears from the active list. (Soft-delete; still in DB for history.) E8. Add another rate card with PAST valid_to: Product: Octonum Stall Price: 1200 Valid from: 2025-01-01 Valid to: 2025-12-31 (in the past) ✓ Expected: rate card shows red "expired" badge. E9. Add a third rate card with FUTURE valid_from: Product: Octonum Stall Price: 1500 Valid from: 2027-01-01 (future) ✓ Expected: rate card shows blue "future" badge. E10. Note: multiple active rate cards for the same product are allowed (tiered pricing). All three should be visible in the list. ═══════════════════════════════════════════════════════════════════ PART F — END-TO-END: CAPTURE LINE ITEMS (Custodian) → SEE IT HERE ═══════════════════════════════════════════════════════════════════ F1. Open /finance/custodian/ in a new tab. You should still be logged in as Harish. F2. Bottom nav → Transfer. Set: Role: I'm Giving Funds Category: Party ✓ Expected: a "Line items (optional · what was supplied)" section appears below the Amount field, with a "+ Add line" button. F3. Search payee: spice ✓ Expected: "Spice Garden Caterers" appears in dropdown. Pick it. F4. Amount: 4200 · Mode: UPI · UPI Ref: TESTREF-001 · Date: today. F5. In Line items, tap "+ Add line". First line: Type "octonum" in Product/Service field. Pick "Octonum Stall" from the dropdown. ✓ Expected: row pre-fills with qty=1, unit=nos, default cost (e.g. 1500), total auto-computed. F6. Edit qty=2, unit_price=1400. Total auto-recomputes to 2800. ✓ Expected: sum line under list updates: "Lines total: ₹2,800 · Transaction amount: ₹4,200 · ⚠ diff ₹1,400 (amount higher)" in red. F7. Tap "+ Add line". Second line: type "chair" in the search. Pick "Stall Chair & Tables (2 each)" or similar. Set qty=1, unit_price=1400. Total auto = 1400. ✓ Expected: sum line now "Lines total: ₹4,200 · ✓ matches" in green. F8. Tap "Record Transfer". ✓ Expected: success toast. F9. Switch back to Vendors PWA tab. Reload. Open Spice Garden Caterers → Supplies tab. ✓ Expected: 2 supply rows show: - Octonum Stall · 2 nos · @ ₹1400 · UPI · ₹2800 · today - Stall Chair & Tables · 1 set · @ ₹1400 · UPI · ₹1400 · today 3 tiles update: Lines=2, Total qty=3, Total ₹=₹4,200. F10. Switch to Catalog tab. ✓ Expected: BOTH products now appear automatically (auto-linked by the Phase 3b trigger), with last_known_price visible. F11. Switch to Prices tab. ✓ Expected: 2 rows. For "Octonum Stall": - Latest = ₹1400 - Avg = ₹1400 - Range = ₹1400–1400 - Delta: "vs rate card ₹X → -₹? (-?%)" (depending on E6's active rate card) For "Stall Chair & Tables": - Same 3 cells - "No rate card set for this product" ═══════════════════════════════════════════════════════════════════ PART G — SOFT DELETE ═══════════════════════════════════════════════════════════════════ G1. Open Spice Garden Caterers → Edit → scroll to bottom. ✓ Expected: red "🗑️ Soft-delete vendor" button visible. G2. Tap it. Confirm. ✓ Expected: toast "Vendor deactivated". Returns to list. The vendor is gone from the active list. G3. Search: spice ✓ Expected: no rows match (because we filter is_active=true). G4. Open Custodian → Transfer → Party. Search: spice. ✓ Expected: STILL gone from search (cross-PWA — Custodian also respects is_active). G5. (Restoration is not via UI in v3 — admin would do this via DB. This is intentional: soft-delete is meant to be reversible only by admin SQL.) ═══════════════════════════════════════════════════════════════════ PART H — DATA INTEGRITY CHECKS ═══════════════════════════════════════════════════════════════════ H1. Re-open Custodian → Transfer → Party. Try searching for an existing real vendor (e.g. "narang" or any party name). Add a transfer with NO line items. Record it. ✓ Expected: success. Backward-compat — transactions without line items work as before. H2. Open that vendor in Vendor PWA → Supplies tab. ✓ Expected: the no-line transfer does NOT appear (Supplies only shows lines, not transactions). Account Ledger DOES show it. H3. Open Vendor PWA → some vendor → Rate Card tab. Try the Add modal. Search the modal for a product name that DOES NOT exist in sales.catalog (e.g. "xyz nonexistent"). ✓ Expected: "No catalog matches. Add it via the Catalog tab first." There is NO inline quick-add here (intentional — rate cards are deliberate). The Save button does nothing if no product is selected (Part E2 already covered this). ═══════════════════════════════════════════════════════════════════ PART I — UI POLISH ═══════════════════════════════════════════════════════════════════ I1. On a Detail screen with many rate cards, scroll. Verify the last row is fully visible — NOT clipped by the bottom nav. I2. On the list with all vendors visible, scroll to the bottom. ✓ Expected: last vendor row visible above the bottom nav. I3. Open any vendor → switch tab rapidly: Info → Ledger → Catalog → Supplies → Rate Card → Prices → back to Info. ✓ Expected: each tab loads cleanly. No leftover content from previous tab. Active chip moves correctly. I4. Back arrow in Detail screen header. ✓ Expected: returns to List preserving any active search / type filter. I5. Force reload (Ctrl+Shift+R). If a previous version was cached, a green "✓ App updated" banner should briefly appear at the bottom. ═══════════════════════════════════════════════════════════════════ REPORT FORMAT ═══════════════════════════════════════════════════════════════════ For each step A1–I5 report: [Step] ✅/⚠️/❌ — one-line note. List all ⚠️ and ❌ separately at the end under "Issues Found". EXPECTED TOTAL CHECKPOINTS: ~50.