The register of everyone you buy from, the prices you have agreed with them, and the statement check that finds spending nobody wrote down.
The register
Suppliers are master data. Every purchase order, goods receipt, invoice and cash purchase points back at a row here, which is why the list is deliberately boring and deliberately guarded: reading it needs view_procurement or manage_suppliers, and creating or editing one needs manage_suppliers.
A supplier carries a short code you choose (KENBREW), a name (Kenya Breweries Ltd), and then whatever else you know: KRA PIN, contact name, phone, email, an address line, and payment terms in days. Only the code and name are required. The rest can arrive later, though the KRA PIN is worth capturing early because it is what your accountant will ask for at filing time.
The code must be unique within your company. Reuse one and the save is refused with Supplier code "KENBREW" already exists, which is a better outcome than two rows quietly competing for the same deliveries.
Search covers name, code and KRA PIN at once, so "KENBREW", "Kenya Brew" and the PIN all find the same supplier. Deactivated suppliers are hidden by default; tick Include inactive to search them too. The empty state says as much when a search finds nothing, because "no results" and "no results among the active ones" are different problems.
Deactivating rather than deleting
There is no delete. A supplier you have stopped using is deactivated, which takes them out of the pickers on new orders while every document they already appear on keeps its history. A purchase order from March that names a supplier who no longer trades still has to read correctly in March.
Price lists
Open a supplier and the Price list panel holds what you have agreed to pay them, item by item. Each line records:
- the item, and optionally the supplier's own SKU for it, which is what appears on their paperwork rather than yours
- the pack size you buy in, and the unit price excluding VAT
- the VAT rate
- a minimum order quantity, where they impose one
- the date the price takes effect, and optionally the date it stops
Prices are never overwritten. Adding a new price for an item supersedes the old one from its effective date, and the earlier row stays. That is the whole point: an order raised last week was raised against last week's agreed price, and if the price list forgot, nobody could explain the order six months later. The uniqueness rule follows from it, one price per supplier, item and effective date.
Prices feed the three-way match. When a supplier invoice arrives, the price they billed is checked against the price you agreed, and a gap outside tolerance is flagged for a person to decide. See Invoice Queue for what happens next.
Getting a list in
Two importers sit behind the Import button, one for suppliers and one for price lists, and both work the same way: download the template, fill it in, validate, then commit.
Validation is a separate step that writes nothing at all. Suppliers are referenced by every document written after them, so a half-imported supplier list is materially worse than a half-imported day of sales; the dry run exists so you find the twelve bad rows before anything lands. The commit runs in a single transaction, and the whole file is matched on the supplier code, so re-importing a corrected file updates the rows you already have rather than duplicating them.
The importer also warns about near-duplicate names. Two rows with different codes and the same name are usually one supplier entered twice, and a warning at import time is far cheaper than discovering it while reconciling their statement.
The Export button downloads the list as it appears on screen, filters and all, with columns derived from the table itself so a column added to the screen appears in the file without anybody remembering to add it.
The statement check
Statement check answers one question: what did we pay this supplier that never made it into Bohari?
Upload the statement, and the checker parses its outgoing transactions, pulls every purchase your company recorded over the statement's own date range (padded by three days at each end so a payment dated a day late still matches), and classifies each side. What comes back is a reconciliation: matched payments, and the ones with nothing behind them. That second list is the interesting one, because unrecorded spend is the shape most leakage takes in a venue that also buys with cash.
Two things about it are worth stating plainly. The date range comes from the file rather than from you, since the file already says what period it covers. And nothing is stored. The statement is read, classified and forgotten; the analysis on screen is the whole product of the exercise. Keeping tenants' bank statements would be a liability the platform has no need to carry.
If the file has no outgoing transactions the checker refuses it rather than reporting a clean bill of health: No outgoing transactions in the file, nothing to reconcile.
Who does what
Buying and paying are different jobs, and the permissions follow that. A Procurement Officer holds manage_suppliers and keeps the register and the agreed prices current. Finance approves the invoices that arrive against those prices and records the settlements. Nobody needs both to do their own work, and keeping them apart is what makes an agreed price mean something. See Roles & Permissions.
FAQ
A supplier changed their prices. Do I edit the old line? No, add a new price with the date it takes effect. The old one stays, and every order raised before that date still explains itself. Editing history is how a price rise becomes invisible.
Can I delete a supplier we added by mistake? Deactivate them. If they were created moments ago and appear on nothing, deactivating costs you nothing anyway, and it keeps the audit trail whole for the cases where the mistake is discovered much later.
We buy the same item from three suppliers. Is that a problem? Not at all. Each supplier has their own price list, and their own pack size and SKU for the same item. The item is the thing on your shelf; how each supplier packages and prices it belongs to them.
Why does the price list ask for a price excluding VAT? Because the VAT rate is stored beside it. Holding the two apart means the match can check the net price you agreed against the net price they billed without one of them quietly carrying tax and the other not.
The statement check says a payment is unrecorded, but I know we received those goods. Then the goods arrived without paperwork in Bohari, which is exactly what the report is for. Find the delivery and enter it, either as a receipt against its purchase order or as a cash purchase if it was bought outright. See Cash Purchases.