Every service business that writes its own software eventually hardcodes a price. It is the path of least resistance. There is one client, one rate, and putting the number in a function takes ten seconds while building a data model takes a day.

The bill arrives later, and it arrives as a category of bug that is unusually difficult to detect: software that charges a number the contract does not say.

How it goes wrong

The first client signs at a standard rate. The number goes in the code. The second client negotiates a different rate, so a condition appears. The third gets a discount on one line only, so the condition acquires a branch.

Eighteen months in, the answer to "what do we charge this client for a spring opening" requires reading source code, and the answer to "what did we charge them last year" cannot be reconstructed at all.

Then a rate changes. Someone updates the constant. Every historical reprint silently reprices, and reports that used to reconcile no longer do.

The rule

No dollar figure lives in code. Every rate is read from the agreement the client actually signed.

That includes the numbers that feel like configuration rather than pricing. The materials markup percentage is the usual casualty. It feels like a company-wide setting until a client negotiates a different one, at which point it turns out to be a per-agreement term that has been living in a function.

In MapleConcierge the markup is stored on the agreement, with an optional override on individual lines, and the code contains no default. If no markup is configured, billing refuses rather than guessing.

What the rate table holds

Each agreement carries its lines, and each line carries what the contract says about it. A stable service code. The current-term rate and the renewal rate, both stored, because a renewal that shifts pricing should not require rewriting history. The unit, whether per year, per month, per event, per hour or a percentage. The trigger that causes it to bill. Its seasonal window. Any minimum billable period. Whether it is taxable. Whether it belongs to the core fee schedule or is optional additional work.

That last distinction earns its keep at reconciliation time. Optional items have no annual value until the event happens, so they must be excluded from an annual total and included in an actual invoice. Conflating them makes the annual figure meaningless.

Renewal pricing without a renegotiation

Storing both the current and renewal rate on each line solves a problem most systems handle badly. Many agreements provide that an introductory rate applies for a first term and a standard rate applies thereafter, unless renegotiated.

With both rates stored and an anniversary date on the agreement, the correct rate for any given service date is a lookup rather than a manual exercise. Work performed before the anniversary prices at the first-term rate; work after it prices at the standard rate. No one has to remember to change anything on the day, and no one has to reconstruct which rate applied to a job six months ago.

The test that proves it works

There is a specific check worth building: take the signed fee schedule, load it as data, and assert that the software reproduces the contract's own stated totals exactly.

If the agreement says the annual programme comes to a particular figure before tax and another figure after, the system should produce both, to the cent, from the stored lines. If it does not, either the data is wrong or the engine is, and you have found it before a client did.