Overview
Quotery is a multi-tenant B2B SaaS that turns incoming purchase requests - PDFs, Excel sheets, CSV line-item lists - into matched, priced, auditable quotes in minutes. Built for distributors, contractors, and service shops that move fast, it pairs a three-call OpenAI orchestration with a deterministic code-based product matcher so exact hits never burn LLM tokens. From draft quote to posted delivery note, the full quote-to-cash path lives in one platform.
The Challenge
B2B sales teams spend hours retyping customer purchase requests into quoting software, matching free-text product descriptions against catalogs that use multiple code conventions (supplier, internal, import, export), and rekeying the same data into fulfillment and inventory tools. Off-the-shelf ERPs are heavy and slow to configure; ad-hoc spreadsheets lose traceability the moment a stock adjustment happens.
The Solution
We built Quotery as a tenant-scoped Django 5 + DRF backend with a React 19 SPA and a Render-deployed marketing site. Every business model inherits a UUID-keyed soft-delete base class, every query is auto-filtered by tenant, and every service-layer mutation invalidates a precise set of Redis cache groups (dashboard, product-usage, quotes-map) with a qf:v1:<group>:<scope>:<hash> key pattern that soft-fails on Redis outage. AI quote import runs three sequential OpenAI calls inside an atomic transaction: structure extraction from PDF (pypdf), XLSX (openpyxl), CSV, or plaintext; deterministic match against four product-code fields plus an LLM pick-or-reject batched across unmatched lines with a hallucination guard; and a 1-3 sentence locale-aware summary. Quotes flow through a formal state machine (draft -> sent -> closed -> partially_delivered -> delivered) that drives an append-only stock ledger across multiple locations, with over-reservation allowed so sales can commit before a receipt posts. Delivery notes, return notes, and stock receipts share one draft-to-posted flow. PDFs render via WeasyPrint, auth is Google OAuth via django-allauth with session-based JWT in HttpOnly cookies, RBAC uses a custom permission catalog, and every mutation lands in an immutable audit log. An embedded assistant answers questions about quotes, clients, and stock right where the user asked.