PetDentX Docs

Supplier

The complete A-to-Z workflow for supplier staff — catalog, inventory, quotations, fulfilling orders, and billing.

Before this page, make sure you've read Getting Started — creating your account, signing in, and setting up staff/roles/branches works the same for every workspace type. This page covers everything specific to running a Supplier.

Overview

A Supplier workspace maintains a product catalog and fulfills procurement requests from connected Clinic (and other) branches. Two independent paths lead to a sale:

Catalog

Products

/products — both creating and editing happen in a dialog on the list page itself (there's no separate /products/new route).

New Product: Name* and Price* are required; Code/Charge (this is the SKU field — that's its literal on-screen label), Unit (Each, Box, Pack, Bottle, Tube, Bag, Pair, Set, Kg, G, L, Ml), Category (only categories typed Product appear here — create one under Categories first if you need it), Brand (type to search existing brands, or type a new name and click "Create" to add it inline — there's no separate brand management page), Cost, Low Stock Alert (the reorder threshold), and Note.

Note: a product's status (Active/Discontinued/Out of Stock) can't be changed from this dialog — new products are always Active. The only way to change status is through the XLSX/CSV import below.

Categories

/categories — categories are typed Product or Service; filter chips (All/Service/Product) show live counts. New Category: Name*, Type (defaults Service — set it to Product for product categories), an optional Slug (auto-generated if left blank), and a Description.

Import / Export

Both Products and Categories support bulk Import (CSV/XLSX) and Export (CSV/XLSX) from their list pages.

  • Product export columns: name, sku, category, cost, unitPrice, unit, currency, status, description, notes.
  • Product import validates: name required; unitPrice required (≥ 0); currency one of USD/KHR/THB/VND/SGD/EUR (defaults USD); unit one of Each/Box/Pack/Vial/Kit/Bottle/Pair/Set/Roll/ Litre/Kg/Other (defaults Each); status one of Active/Discontinued/Out of Stock (defaults Active); category matched by name against your existing categories. A row is skipped (not created or updated) if a product with the exact same name already exists.
  • Category import validates: name required, type must be Service or Product; duplicates (same name + type) are skipped.

Inventory

/inventory has two tabs — Stock Levels and Movements — plus stat tiles for Total Products, Low Stock, Out of Stock, Total Quantity, and a "Brands Stock" summary.

Stock is tracked per product per branch. On the Stock Levels tab, each row is color-coded: red if you're out of stock, amber ("low stock") if on-hand is at or below your Low Stock Alert threshold, green otherwise — click "⚠ Low Stock" to filter down to just the amber/red rows. Each row also has quick Stock In (+) / Stock Out (−) buttons for a fast one-off adjustment.

Adjusting stock manually

The Adjust Stock button opens a dialog: Product* (only Active products are selectable), Movement Type, Quantity* (always entered as a positive number — the type determines whether it adds or subtracts), Reference, and Notes.

Note: of the movement types offered in this dialog, only Adjustment In, Adjustment Out, and Return actually work — the others aren't real movement types the system recognizes and will fail if selected. Sale, Purchase, Damage, and Initial movements are never created manually; they're generated automatically by the system (see below).

Every stock change re-checks your Low Stock Alert threshold and fires a notification if you've crossed it.

Where stock moves automatically: a Sale movement happens when you create a Sale Invoice with product lines, or when a quotation is converted to an invoice. A Purchase movement happens on the ordering clinic's side when their Purchase Order is marked Delivered — see below.

Quoting

/quotations — issue a price quote to any connected branch, with line items, discount, and an expiry date.

New Quotation: Issued To* (any connected branch), optional Valid Until date, Currency (USD/KHR), Tax %, Discount (none, fixed amount, or percentage), Note, and Items — add rows from your Products or Services catalog, each with Qty and an editable Unit Price (auto-filled from the catalog).

Note: clicking Create Quotation sends it immediately — there's no separate "save as draft then send" step in the current flow.

What the recipient can do

Once sent, the receiving branch sees Accept or Reject buttons on the quotation. If accepted, you (the issuer) get a Convert to Invoice button.

Converting to an invoice

Converting checks your stock first — if any product line requests more than you have on hand, the whole conversion is rejected with an "insufficient stock" message (unlike a plain Sale Invoice, where an oversell only warns, see below). Once converted:

  • A Draft B2B Invoice is created with the same line items.
  • For every product line, stock is deducted from your branch and a Sale movement is recorded.
  • The quotation becomes Converted and can no longer be edited.

The resulting invoice still needs to be opened and Sent from Sale Invoices — converting doesn't deliver it to the client by itself.

Quotation statuses: Draft, Sent, Accepted, Rejected, Expired, Converted. (Expired exists as a status but nothing currently sets it automatically — a quotation won't flip to Expired just because its Valid Until date passes.)

Fulfilling Orders

/sale-orders is your view of Purchase Orders that clinics have sent you.

Status flow: Draft → Submitted → Acknowledged → Processing → Shipped → Delivered, or Cancelled. As the supplier, once an order is Submitted, you move it forward yourself:

  1. Acknowledge (Submitted → Acknowledged)
  2. Start Processing (Acknowledged → Processing)
  3. Mark Shipped (Processing → Shipped)

Note: the final step — confirming delivery — belongs to the ordering clinic, not you. Once you mark an order Shipped, you wait for the clinic to click "Confirm Delivery" on their side; there's no delivery-confirmation button on your Sale Orders page. Cancelling an order is also only available to the clinic, while it's still Draft or Submitted.

What happens when an order is marked Delivered

This step is automatic and happens the moment the clinic confirms delivery:

  • A B2B Invoice is created (as a Draft) billing the clinic for the order, with the same line items and totals.
  • For every line item linked to one of your products, a Purchase stock movement is recorded — but on the clinic's inventory, adding the received quantity to their stock.
  • Both you and the clinic get a notification.

Note: your own inventory is not automatically reduced when an order ships or is delivered — if you want your stock numbers to reflect what went out, adjust it yourself (Adjust Stock → Adjustment Out), separately from this workflow.

The auto-created invoice appears in your Sale Invoices as a Draft — open it and click Send to deliver it to the client, same as any other invoice.

Billing

/sale-invoices — invoices you've issued, whether created manually, converted from a quotation, or auto-generated from a delivered purchase order.

Creating an invoice manually (/sale-invoices/new)

Choose Client Type: Internal (pick any connected branch) or External (free-text Client Name, Phone, Address — for a client not on the platform). Then Due Date, Currency (USD/EUR/GBP/KHR/THB), Tax %, Discount, Notes, and line items from your Products/Services catalog (products show live stock right in the picker).

If a line oversells a product's stock, a Stock Warning dialog lists the shortfall and asks you to confirm before creating the invoice anyway.

Note: stock is deducted the moment the invoice is created, not when you Send it — keep that in mind if you create a draft invoice and decide not to send it right away; the stock has already moved.

Managing an invoice

Statuses: Draft, Sent, Overdue, Paid, Cancelled.

  • Send (Draft only) — delivers it to the client and notifies them.
  • Print — a bilingual (Khmer/English) invoice with line items, totals (including a KHR-converted total), and signature lines.

Note: a couple of things aren't fully wired up yet as of this manual: the Cancel button shown on a sale invoice currently doesn't work (the action isn't implemented on the server, so clicking it will just show an error) — treat cancellation as not yet available. Also, marking an invoice Paid is something only your client can do from their side (Purchase Invoices) — there's currently no "record payment" action on your side. And Overdue doesn't get set automatically when a due date passes; it's a status that exists but nothing flips it yet.

Reports

The Reports section (sidebar) covers Income, Invoice, Purchase Order, Product Performance, Stock, Client, and Quotation reports — each with a date-range filter, stat cards, a chart, a detail table, and CSV/XLSX export.

On this page