G Gaia

Switch factory

CYTO-11 — Balakong Jaya CTSB CYTO-29 CTSB CYTOWELL-54 — Taming Jaya PIC/S CTWSB CYTOCNGZ-602 — Guangzhou CTCNGZ

Only factories you are granted appear here (Filament tenant menu).

Leo Lim

leo@navi.my · Owner / Admin

Profile settings Change password

Theme

Sign out
RetailSellR&DMakeBuyStockPlanItemsGMPAdminInsights
← Quotes / New

New quote

will post as Q-2026-035 · Q-{yyyy}-{seq} series (admin-settings numbering)

1 · Customer & request

customer_id nullable for walk-ins — converts to a record on acceptance. + New customer opens Customers.

engine flags when MO-schedule lead time (~3 weeks) exceeds it — fits

foreign currency snapshots quotes.exchange_rate; floor compare always in base MYR.

2 · Source & product

standard product + packaging → machine; anything custom routes to the R&D queue.

rolled-up cost 3.10 MYR live from BOM + operations · floor 5.00 · list 8.00 · category tier margin bands applied · MOQ 1,000 pcs

3 · Tier lines

machine-priced by qty break — editable within band
Qty tier Unit price MYR Margin % Tax Line total MYR

All tiers ≥ floor 5.00 — the machine never quotes below floor

Margin column is owner role only — hidden from sales. Valid 30 days from send → valid_until = sent_at + 30; nightly job flips sent → expired.

4 · Shipping & notes

The shipping trio is carried onto the one-click SO on acceptance.

Save draft Cancel
On send: sets sent_at → valid until 2026-08-06 · status Draft → Sent · creates the CRM deal → Quoted. Accepted later → one-click SO in the customer's series (lines, prices & shipping carried over).

Project Gaia — static mockup in Filament v3 idiom. No backend. Q-2026-035 is the Draft row in quotes.html (Hafiz Trading, Double Root, 1k/5k/10k @ 8.00/7.20/6.60) prefilled from the auto-quote machine result; costs, floors and margin bands echo price-lists.html / item-detail.html.

Save & send quote

Q-2026-035
Q-2026-035.pdf · 2 pages

Sending sets sent_at → valid until 2026-08-06; CRM deal → Quoted.

New quote — field manifest

Filament QuoteResource CreateRecord page: Customer & request section + Source toggle + TierLinesRepeater (quote_lines) + Shipping/Notes + Save & send Action modal.

FieldFilament componentTypeSourceFK target
PageQuoteResource CreateRecordformcreates: quotes + quote_lines; next number from quotes.quote_no — Q-{yyyy}-{seq} series (admin-settings numbering)
CustomerSelect + inline CreateActionFK nullablestored: quotes.customer_id — nullable for walk-ins; converts to a customers record on acceptancecustomers.id
Customer refTextInputstring, nullablestored: quotes.customer_ref — printed on the quote PDF
Requested delivery dateDatePickerdate, nullablestored: quotes.requested_delivery_date — engine flags when MO-schedule lead time (~3 wk) exceeds it
Currency / FXSelect + snapshotstring + decimalstored: quotes.currency (default base MYR) + quotes.exchange_rate snapshotted at quote time; floor compare always in base MYR
SourceToggleButtonsenumstored: quotes.source — auto (machine) | rnd (routed through R&D); custom product forces rnd
ProductSelectFK — one of twostored: quote_lines.variant_id (auto) OR quote_lines.formulation_version_id (rnd) — exactly one set per linevariants.id / formulation_versions.id
Tier linesRepeater (qty_tier, unit_price)rowsstored: quote_lines — one row per tier (quote_id, qty_tier, unit_price)quotes.id
Line: TaxSelect per tier lineFKstored: quote_lines.tax_rate_id — default '5% - Sales Tax', same tax_rates table as SOtax_rates.id
Margin %TextEntry (owner role only)derivedquote_lines.margin_pct — computed from cost snapshotted at quote time; hidden from sales role
Valid untilTextEntry::date() (derived)datestored: quotes.valid_until = sent_at + 30 days; nightly job flips sent → expired past it
CRM dealSelect::relationshipFK, nullablestored: quotes.deal_id — created/updated on send, moves to Quoted; accepted → Wondeals.id
Shipping feeTextInput group (trio)string / money / FKstored: quotes.shipping_fee_description / shipping_fee_amount / shipping_fee_tax_rate_id — carried onto the one-click SO on acceptancetax_rates.id
NotesRichEditorrich text, nullablestored: quotes.notes — customer-facing, on the quote PDF
Save & sendAction (form modal)actionsets quotes.sent_at → valid_until; status Draft → Sent; creates/updates the CRM deal → Quoted; queues the quote PDF emaildeals.id

Engine notes

  • The machine: price = max(floor, rolled-up cost × tier margin band for the product's category). Floor comes from the shared variant_prices table (Double Root floor 5.00, list 8.00) — the machine never quotes below floor. Floor compare always happens in base MYR after the FX snapshot.
  • 90/10 auto-vs-R&D split: standard variant + standard packaging → instant tiers (source auto); custom formula or packaging → a quote_requests row routed to R&D, and "Draft quote from estimate" pre-fills this same form (source rnd) when the formulation cost lands.
  • Accepted → one-click SO: lines, prices, tax and the shipping fee are copied to a sales order in the customer's series; the CRM deal flips to Won.
  • Expiry: nightly job flips sent → expired past valid_until (2026-08-06); an expired quote is re-quoted at current cost, never resent stale.
  • Roles: sales sees prices only; owner also sees the margin_pct column (Filament column visibility by policy).