PortaPro prices things through two separate tracks, and they don't share a hierarchy. Knowing which track applies tells you exactly why a price showed up where it did.
Track A — Recurring cycle invoices
Each Rate Card row bills its own declared service rate directly when a Cycle Invoice generates. There's no resolver, no fallback, and no other layer involved — the rate you set on the row is the rate the customer is billed for that row, every cycle.
Track B — Job and quote line items
One-off jobs, quotes, and manual invoices resolve the unit price for each line item using a three-layer hierarchy. The most specific rate wins.
Layer 1: Site Additional Charge. If the site has an Additional Charge whose description matches the item you're adding, that rate wins. This is a site-level override, but it's specifically the site's Additional Charge — not a recurring Rate Card row. Recurring rows never feed into this hierarchy.
Layer 2: Customer default rate. If no matching Additional Charge applies, the system checks the customer's Customer Default Rates in Section 2 of their Rate Card. If a rate is set for this product or service, that rate wins.
Layer 3: Catalog price. If neither of the above applies, the system uses the equipment item's default catalog price at its default billing period. This is the least specific layer — it's what you'd quote a stranger off the street.
If no price exists at any layer, the line item is created with a $0 unit price and a "No rate set" badge so you catch it before sending.
Each invoice line item shows a small source badge next to the unit price: "Site rate," "Customer rate," "Catalog rate," or "No rate set." If you manually override the unit price on a line item, the badge changes to "Custom" so it's clear you've deviated from the system's resolved value. Reverting to the resolved value restores the original badge.
Track B's hierarchy applies in the invoice wizard, the job wizard, and the quote wizard — wherever you add a product or service to a line item for a customer. The Cycle Invoice (Track A) never runs this resolver; it bills the Rate Card row's own rate because it's billing the contract, not building line items one by one.
If you ever wonder why a particular price showed up on a one-off job or quote, the source badge is the answer. Click into the line and the badge tells you exactly which layer of Track B's hierarchy was used. If the price is on a Cycle Invoice instead, it always came straight from the Rate Card row — Track A doesn't have layers to check.
