Termco
Termco

Two Spellings, Two Prices

25 August 2026

It's Thursday afternoon and your billing clerk is forty tickets into a stack of sixty. She types "lake" into the customer field and the dropdown offers two choices: Lakeside Construction Inc and Lakeside Const. Same company. Same yard, same jobs, same PM signing the checks. She picks the top one because she has twenty tickets to go, and the top one is the one she picked yesterday.

Only one of those records got January's rate update.

That's the whole failure. Slow down on it, because nothing about it looks like an error. The ticket is real. The tonnage is right. The clerk did her job. The system priced the load exactly as its record instructed. And the invoice is wrong.

Where the second record comes from

Nobody sets out to build a duplicate customer. The second record gets created in a hurry, and usually for a defensible reason.

A new job starts on a Monday and the paperwork lands on Wednesday, so someone creates "Lakeside, Rt 9" to get the week's loads billed. A driver's slip abbreviates, a search for "Lakeside Const" doesn't surface "Lakeside Construction Inc," and the clerk reasonably concludes it isn't there and adds it. The company gets bought and half the office starts typing the new name. The customer's own PO spells their name a third way.

In each of those moments, creating a record takes thirty seconds, while finding the right existing one takes judgment, a phone call, or both. Guess which one happens at 4:40 on a billing day.

So the customer list grows at the speed of billing pressure, not at the speed of new contracts. If your operation is more than a few years old, the pairs are almost certainly sitting in yours already. There's a ten-minute way to check, at the end of this piece.

The record is where the deal lives

A customer record holds far more than a name. It's the container for everything you negotiated: the rate, the unit it's priced in, the surcharge that applies, payment terms, whether a PO number is required before a ticket can bill. When one customer exists as two records, the deal exists in two copies. And copies drift.

Say Lakeside negotiated $8.25 per ton on 3/4 minus back in January, up from $7.60. Whoever entered the increase updated Lakeside Construction Inc, because that's the record the contract folder points at. The twin kept $7.60. Through spring paving season, 2,600 tons of Lakeside's work got keyed to the twin. That's 65 cents a ton, about $1,690, gone in one season, with every ticket present, legible, and priced exactly as its record said to. No credit memo will ever surface it, because no customer calls to report being billed at last year's price.

Volume terms fork too, in the other direction. Suppose the contract drops the rate to $7.90 once Lakeside crosses 5,000 tons in a quarter. Their real volume is 5,800 tons, split 3,200 and 2,600 between the two records. Neither copy crosses the threshold, so every ton past 5,000 bills at the full rate. Lakeside's PM catches that at the quarterly true-up, because catching it is his job, and now you're cutting a credit and explaining why your own system didn't know its own customer.

flowchart TD
  A["Contract: rate drops to $7.90/ton past 5,000 tons per quarter"] --> B["Real Lakeside volume: 5,800 tons"]
  B --> C["Lakeside Construction Inc: 3,200 tons"]
  B --> D["Lakeside Const: 2,600 tons"]
  C --> E["Neither record crosses 5,000"]
  D --> E
  E --> F["800 tons bill $0.35 high, credit memo at true-up"]

Why the audit doesn't catch it

Everything downstream of the split checks out. Each invoice adds up. Each line traces to a real ticket. Spot-check ten invoices a month and all ten pass, because internal consistency was never the problem. The problem is a question none of your reports ask: is this customer whole?

The split leaks into the back office in quieter ways too. At month end, someone wants to know what Lakeside did this quarter, and the honest answer takes two reports and a merge in someone's head. The aging report shows two mid-sized balances instead of one large one, so a customer drifting past their credit limit doesn't look like it. And on Lakeside's side, AP has one vendor record for you and is receiving invoices under two account references, which is a fine way to get short-paid for reasons neither of you can reconstruct.

Now the part you might argue with: whoever can create a customer record in your system holds pricing authority. Not formally. But the record they create carries a rate, or inherits a default, and that number becomes an invoice. Most operations extend this authority to anyone in the office who can reach the dropdown, with no review, forever. You'd never let a clerk hand-write a rate onto a contract. Creating "Lakeside, Rt 9" at 4:40 on a Thursday is the same act with worse handwriting.

The pushback is fair: tickets have to bill this week, and a clerk who can't create a record can't clear the stack. But "invoice today against a made-up record" versus "wait for someone to bless a new customer" is a false choice. The right move is to hold the ticket, not to fork the customer.

One record, many spellings

The fix is reference data with an owner. One canonical record per customer, and every known variant, abbreviation, and job-site nickname attached to it as an alias instead of living as its own record. Then the dropdown stops offering wrong answers: "Lakeside Const," "Lake Side," and "Lakeside, Rt 9" all resolve to the record that carries the contract terms. A ticket naming a customer nothing recognizes doesn't spawn a fresh record. It gets flagged and parked until a person decides whether it's a genuinely new customer or a fourth spelling of an old one. New customers get created on purpose, by someone whose job includes knowing what the deal is.

Keeping that list clean is the reference data piece of what Termco does, and it's the least glamorous piece, which is exactly why it leaks: nobody's quarterly goals mention the customer list. But every billing rule you structure attaches to a record, and a rule attached to half a customer is half a rule.

You can size your own exposure this afternoon. Export the customer list, sort it, and read adjacent rows. For every near-duplicate pair, pull the rate on each record and compare. Matching rates mean you got lucky. Different rates mean one of those numbers is on invoices right now, and it isn't the one somebody negotiated.

If you'd rather start from the paper, send 10-20 sample tickets to hi@termco.ai. Tickets carry the customer names your operation actually writes, which is where the spellings multiply, and we'll send back what we find within 48 hours.