Why the model matters more than the screens
Screens are easy to change. The data model underneath them decides what the system can know. If the model has no place for a fact, staff put it somewhere it does not belong: a note on the order, a custom field that means something only to the person who added it, a file on a shared drive. Every report built afterwards has to know where each workaround is.
Flooring is harder on a data model than most product businesses. Goods are sold by area, cut from rolls, bought from vendors for a specific customer and shipped to a job. A model designed for boxes on a shelf has no place for a partly used roll, and no way to say that a purchase order was placed for one customer's order.
That is why we design the model before moving any data. Don't copy your old database: design the data model first explains the method, and what an ontology is, explained for business owners covers the kind of description we start from.
Products and inventory pieces
The most important separation in flooring is between what is sold and what is shipped. In the wholesaler's model, a product is a style and color in a vendor's line. An inventory piece is a specific roll or cut of that product in a warehouse. They are separate things with a defined link.
The difference matters every day:
- A customer orders a product. The warehouse ships one or more pieces of it.
- One product can have many pieces, each with its own size and location.
- Cutting a roll for an order leaves a smaller piece of the same product, which is stock that can still be sold.
- A report on sales belongs to the product. A question about what can ship today belongs to the pieces.
If an old system blurs the two, a field-to-field copy blurs them in the new system as well, and the blur shows up as stock counts nobody trusts.
CommerceServer keeps the two apart. Staff can hold specific measured pieces for an order line, such as carpet roll pieces identified by warehouse tag, and the packing list is built from exactly the pieces held. The product view shows how much is in stock, on order, in transit and allocated to orders. A quote does not reserve stock, so a quote that is never accepted does not tie up inventory.

Vendors, vendor programs and pricing
Every product belongs to a vendor's line, and the vendor's part number is how the vendor knows it. That link earns its place during a migration. When the wholesaler's import was compared with the old data, 43 exceptions had to be traced back to source documents. Five of them were products, and each was traced through vendor part numbers.
Vendor programs are where many flooring systems collect workarounds. Suppose, as an example, a vendor offers a program on one product line: a set cost, a rebate or a display requirement. If the program is typed onto each style, every new style needs the same entry and some get missed. In a model, the program is a rule attached to the product line, and every style under that line inherits it, including styles added later. Business rules belong in the data model walks through this example.
Pricing needs its own structure, because a flooring distributor sells the same product at different prices to different customers and in different units. CommerceServer prices by customer type, supports quantity price breaks and calculates area pricing from the line's dimensions in square feet or square yards. A price that a rep types in by hand is marked as an override, and it is saved as that customer's price only when the rep chooses to save it. Vendor cost is recorded on the purchase order lines, so cost and sell price come from records rather than from memory.
Customers, jobs, quotes, orders and purchase orders
The wholesaler's model names customers, products, vendors, orders, purchase orders and invoices, and states the links between them, such as which purchase order filled which sales order. That one link answers questions that otherwise take a phone call: is this customer's flooring ordered, when is it due, and what is it costing us.
Many flooring orders are for a job: a house, a store, a contractor's project. A model for a flooring distributor typically gives the job its own place, so a contractor's separate projects do not merge into one account history. On a CommerceServer purchase order, the header carries the sidemark, the job or end-customer name that travels with the vendor's shipment, along with the ship-to warehouse and the expected ship date.
Here is how the records link in CommerceServer, from the first quote to the vendor:
- A quote becomes the sales order. They are the same record, so nothing is retyped, and conversion records the customer's PO number and terms.
- From an order line, staff create a purchase order to the vendor, or add the line to an existing draft. The order and the purchase order are linked both ways.
- When the purchase order is placed, the incoming pieces are held for that order line automatically, and staff can change the hold. A purchase order placed to restock the warehouse is held for no one.
- When the vendor ships, staff record the shipment and the same pieces move to in transit. When they arrive, staff receive them into a warehouse.
How a negotiated quote becomes an order in CommerceServer follows one order through these steps.

Where 15 years of ad hoc fields ended up
A heavily customized system holds its history in custom fields and scripts. When we moved the wholesaler, a custom field that existed because Zoho had nowhere better to put something became a proper field or relationship with one meaning. A script that enforced a business rule became a rule stated in the model.
The table shows the pattern with typical flooring examples. They illustrate the kind of change, not a list taken from the wholesaler's system.
| Typical workaround | Where it belongs in the model |
|---|---|
| Roll length typed into a note on the order | A measured inventory piece held for the order line |
| A checkbox meaning "special order" | A purchase order linked to the order line |
| The job name added to the customer's name | A job under the customer, carried to the vendor as the sidemark |
| A vendor program typed onto each style | A rule on the product line |
| A price typed over on every order | A customer price type, or a marked override |
Once the workarounds are gone, the business can ask for what it needs directly. The wholesaler now runs its own custom workflow, custom business rules and custom reporting, all supported in CommerceServer. It never had that in 15 years on Zoho. Every feature and report it asked for was built, plus a B2B portal for its customers.
Old data still has to be cleaned on the way in. Cleaning up bad data before it costs you covers duplicates, missing dates and products filed under the wrong item, and what 15 years of order history can tell you covers what the cleaned history is worth.
How one model serves reports, the portal and AI
With one model, each fact has one place, and everything that needs it reads it from there.
Reports. Sales by product line, open purchase orders by vendor and stock by warehouse all come from the same records staff work in. There is no separate copy to reconcile.
The customer portal. The wholesaler's customers log in, check inventory and submit purchase orders themselves. Because the portal runs on the same CommerceServer data the staff use, the stock a customer sees is the stock in the system. A B2B ordering portal for distributors describes what a portal needs from the data underneath it.
AI. When someone asks how much of a style is available, an AI agent can read in stock, on order and allocated from the model instead of guessing from order notes. Ask business data questions in plain English explains how that works.
New files. Vendor price lists, order documents and old exports arrive in many layouts, and each one is mapped into the same model. When a file arrives in a layout the agents have not seen, Buffaly writes a new reader for it and uses it in the same session. We consider this key to how Buffaly works. Buffaly Builds Its Own Tools describes the behavior.
The method carries forward too. What we learned moving the wholesaler became the tools for its sister company's migration: the import method and the checks run before and after each load. Why your data import should be rerunnable explains those checks, and how a flooring wholesaler left 15 years of Zoho patches in one month tells the full story.
Check your own model
You can test your current system against this structure in an afternoon:
- Pick a product and ask how many separate rolls or cuts of it you hold, and where. If the answer comes from a note or a person, products and pieces are not separate.
- Pick an open special order and find the purchase order that fills it. If that takes a search or a phone call, the link is missing.
- Look at a contractor customer and see whether you can tell their jobs apart.
- Find your vendor programs. If each one lives on individual styles, new styles are at risk of missing it.
- List your custom fields and write down the business need each one serves. Each need belongs somewhere in the model.
Show us how your products and stock are set up
If your system cannot tell a product from the roll that ships, or a special order from the purchase order that fills it, we can design the model with you and move your history into it. CommerceServer is built, run and continually improved by one accountable team, with the improvement capacity agreed for each engagement. Tell us about your current system, or read how full service works.