RFQs — Id
What it is
One RFQ: its line items, the suppliers you can send it to, the prices those suppliers came back with, and everything that has happened to it. This is where an RFQ becomes a quotation.
The header shows the RFQ number, the vessel, the port (or Multi-port: and the list, when the RFQ targets several), the required-by date, and who sent it. ✎ Edit Record next to that opens the RFQ's own edit form.
Four tabs: Items (with a count), Suppliers, Comparison, Activity.
Who can open it
Any signed-in staff account that is active. Two gates, both in proxy.ts: account status, then
the sales.rfqs feature grant while FEATURE_GRANULAR_RBAC is on. The owner bypasses the second
unconditionally.
🔴 Opening the page is not the same as being able to use every button on it. Sending an RFQ to suppliers — Forward and Send Split on the Suppliers tab — calls an API that requires admin capability or above, which in practice means the owner account only. Staff mapped to sales, operations or accounts all hold operator capability and get "Forbidden: insufficient role". The buttons are shown to everyone regardless. This is recorded in the inventory: A2Z-F020 is PARTIALLY IMPLEMENTED — "button shown to all but API is admin-only → 403".
Before you start
Two actions on this page change data in ways that are not obvious, and neither asks twice:
- 🔴 "Re-parse with AI" deletes every line item on the RFQ and replaces them with what the parser reads out of the source text. Any hand-corrected description, quantity, unit, IMPA or HSN code is gone. Use it on an RFQ nobody has edited, not to "top up" one you have been working on.
- 🔴 "Build Quote →" can create a customer record. If the RFQ has no client attached and none
can be matched by the sender's email, it creates a new
clientsrow — named from the RFQ, or from the sender's name, or literally "Walk-in Customer" — on the Spot markup tier, and attaches the quote to it. Check the Client shown in the header first; a wrong or missing one is cheaper to fix now than after a customer record exists.
Also worth knowing: the Suppliers tab is behind a feature flag (supplier_engine). When it is
off the tab reads "Supplier engine is not enabled. Contact your administrator to enable it."
Every control on the page
Header:
| Control | What it does |
|---|---|
| Build Quote → | Builds a quotation from your price list by fuzzy-matching each item's description. A match of 45% or better is priced automatically; everything else is marked "Price TBD". It then takes you to the new quote's edit screen. Disabled once the RFQ is already Quoted, where it reads ✓ Quoted. |
| ✎ Edit Record | The RFQ's own edit form — vessel, dates, client, header fields. |
| ⋯ (overflow menu) | Nine entries, listed below. |
The overflow menu:
| Entry | What it does |
|---|---|
| Build quote with AI | Prices the quote with AI instead of the price list — cheapest supplier plus the customer's markup tier. |
| Export Split Excel | Downloads a multi-sheet workbook, one sheet per category, for sending to suppliers by hand. |
| Import Supplier Quote (Paste) | Paste a supplier's price list as text. |
| Import Supplier Quote (Excel) | Upload a supplier's workbook. |
| Import Supplier Quote (AI) | Let AI read a supplier's reply. |
| ✎ Edit Items | Toggles the items table into edit mode, and back with ✓ Done Editing. |
| Sync to Directory | Backfills what this RFQ knows into the directory records — vessel, client, contact. |
| Re-parse with AI | 🔴 Destructive. See "Before you start". |
Items tab:
- A pricing tier banner naming the customer's tier and markup percentage, and restating the 45% match rule.
- The items table — description, quantity, unit, category, IMPA and HSN. Editable only after ✎ Edit Items. It carries its own re-detect categories action, which asks first and then rewrites the category on every line.
- Items by Category — AI-powered discovery. Items grouped by category, each group with a 🔎 Find Suppliers button. Results come back in two columns: Existing Matches (suppliers you already have, with a match percentage) and Newly Discovered (found on the web, linked to their site). Finding suppliers here does not send anything.
- 📅 Buyer Data — Planned Date and Required By. Marked Read-only; change them from ✎ Edit Record or from the RFQ list.
- 🛰️ Marketplace Source — only for RFQs from a marketplace. Order No, Title, Type and Enquiry Sent. The Order No is what a quote must be submitted back against, so do not clear it.
- 📄 Captured CRM Metadata — what a portal submission carried: vessel ETA, captain's name, WhatsApp and Inmarsat, company, contact person, telephone, website, registered address.
- Attachments and Client Notes — the customer's own files and message, when there are any.
- Buyer Remark (read-only, the customer's) and Supplier Remark (yours, free text). Supplier Remark saves when you click out of the box and shows Saving… / ✓ Saved.
- 🔒 Internal Notes — Team Only. Auto-saves as you type. Not visible to the customer.
Suppliers tab (only with the supplier_engine flag on):
- Suppliers split into recommended — ranked against this RFQ's items and port — and the rest.
- Discovery, to find suppliers you do not yet have, with pick and dismiss.
- Forward: tick items, tick suppliers, send. ⚠️ Owner-only in practice, see "Who can open it".
- Send Split: sends each supplier only the items in their categories. It opens a 📨 Split RFQ Preview first, showing exactly what each supplier will receive, with Cancel and ✅ Confirm & Send to N Suppliers. A supplier with no matching category is reported as "no items in their categories" and is not sent to. ⚠️ Same owner-only restriction.
Comparison tab — the supplier bid matrix, once supplier prices exist. Until then it reads "No supplier quotes received yet." Pick a price per line, then build the quote from those selections. On a multi-port RFQ you build one quote per port, and ports already generated are marked; on a single-port RFQ it takes you straight to the new quote's edit screen.
Activity tab — the timeline of what happened to this RFQ, and the audit trail beneath it.
What it writes
| Action | What it writes |
|---|---|
| Build Quote → | Creates a quotations row (status draft, number allocated for the entity) and its quote_items; sets the RFQ's status to quoted; may create a clients row — see "Before you start". Then redirects to /quotations/[id]/edit. |
| Build quote with AI | POST /api/ai/build-quote-from-rfq. |
| Comparison → build from selections | POST /api/rfqs/[id]/build-quote-from-selection, one call per port on a multi-port RFQ. |
| ✎ Edit Items changes | Updates rfq_items per field; removing a line deletes it. |
| Re-detect categories | Updates category on every rfq_items row. |
| Re-parse with AI | POST /api/ai/parse-rfq, then deletes all rfq_items for this RFQ and inserts the parsed set. Also updates vessel and port on rfq_submissions when the parser found them. |
| Supplier Remark | PATCH /api/rfqs/[id]/inline. |
| Internal Notes | Updates internal_notes on rfq_submissions. |
| Forward / Send Split | POST /api/rfqs/forward — creates supplier_rfqs and their items, emails each supplier a generated workbook, and sends a WhatsApp notification where one is configured. |
| Sync to Directory | Backfills directory records from this RFQ and re-reads the RFQ. |
| Find Suppliers / Discovery | POST /api/discovery; picking one saves it, dismissing one records the rejection. |
When it goes wrong
"Forbidden: insufficient role" when forwarding to suppliers. Expected for every account except the owner. Ask the owner to send it, or use Export Split Excel and email the suppliers yourself.
The Suppliers tab says the supplier engine is not enabled. The supplier_engine feature flag
is off. An administrator turns it on; nothing on this page can.
Build Quote → produced a quote against a customer you do not recognise. It creates one when it cannot match the RFQ to an existing customer. Fix the client on the quotation, and delete the customer record it invented if it is a duplicate.
Your item edits disappeared. Check whether Re-parse with AI was run — it replaces the whole item list.
"Send Split" reports a supplier got nothing. That supplier's categories do not overlap the RFQ's items. Either widen their categories or use plain Forward with the items ticked by hand.
Dispatch reports emails not sent. The result names the reason per supplier — no email address on file, or SMTP not configured. The supplier RFQ records are still created.
The Comparison tab is empty. No supplier prices have been imported yet. Use one of the three Import Supplier Quote entries in the overflow menu.
Related screens
- RFQs — the terminal this RFQ came from.
- RFQs — Id Edit — the RFQ's own header edit form.
- RFQs — Id Comparison — the comparison view on its own route.
- Quotations — Id Edit — where Build Quote takes you.