---
name: strother-pricing-engine
description: >
  Authoritative pricing rules for the Strother Fabrication estimating app. ALWAYS load this skill
  before writing, editing, or reviewing ANY code that touches pricing formulas, tax regimes,
  overhead, margin, grand totals, sell prices, or proposal line amounts. Also load when answering
  questions about how pricing works, which formula applies to a scope, or how tax is calculated.
  Do not derive pricing logic from model names, column names, or comments in the codebase —
  this skill is the single source of truth and overrides all of those.
---

# Strother Pricing Engine — Authoritative Rules

## 1. The Two Scope Formulas

Every scope has an `estimate_type` column. That column determines which formula applies.
There are exactly two formulas. No others exist.

### Formula A — `fab_install` (Fabrication & Install)

```
Grand Total = (Total Cost × (1 + overhead_rate)) ÷ (1 − margin_rate)
```

- `Total Cost` = Material Total + Equipment Total + Labor Total
- Overhead and margin are applied to the **entire Total Cost as one block**
- Equipment is part of Total Cost — it is NOT separated out
- Used for: standard railing jobs, most scopes

### Formula B — `install_focus`

```
Material Subtotal = Material Total × (1 + material_overhead_rate)
Labor+Equip Subtotal = (Labor Total + Equipment Total) × (1 + overhead_rate)
Combined = Material Subtotal + Labor+Equip Subtotal
Grand Total = Combined ÷ (1 − margin_rate)
```

- Material gets its own lower overhead rate (`material_overhead_rate` column on `scopes`)
- Labor **and Equipment** share the standard overhead rate — Equipment joins the Labor block
- Margin is applied once to the combined result
- Used for: Sleekfence, install-only scopes where material is a pass-through

**Critical:** `install_focus` Equipment goes into the Labor+Equip block, NOT treated separately.
The Grand Place greening wall is `fab_install`, NOT `install_focus` — do not reclassify it.

## 2. Tax

```
Tax Amount = Grand Total × tax_rate
Customer-Facing Total = Grand Total + Tax Amount
```

- Tax is **always added on top** of the margin-divided Grand Total
- Tax is NEVER included inside the Cost or Grand Total before margin is applied
- Manual sell prices are **tax-inclusive** (N4 ruling): if Tyler sets a manual price, that
  price already contains tax — do not add tax again on top of it

## 3. Manual Sell Price

- The `manual_sell_price` column on `scopes` is the **price of record** when set
- When `manual_sell_price` is not null: it overrides the formula-derived Grand Total entirely
- Pricing snapshots are architecturally required: store the full formula inputs + outputs
  at the moment a proposal is generated — the snapshot is what the customer sees, not a
  recalculation at PDF time

## 4. Kansas Tax Regimes

Four regimes exist. The `tax_regime` column on `jobs_estimating` holds one of these values:

| Regime | Rule | Who pays sales tax |
|---|---|---|
| `mo_fab_only` | Missouri Fabricator retail-sale rule | Customer pays tax on full sale |
| `fab_install` | Kansas Contractor rule | Strother pays tax on purchased materials (F3b) |
| `ks_remodel` | Kansas Remodel rule | Complex — see notes below |
| `tax_exempt` | No tax | No tax collected or paid |

### KS Regime Split (critical — not a contradiction)
- `fab_only` jobs → Fabricator retail-sale rule
- `fab_plus_install` jobs → Contractor rule
- These are TWO DIFFERENT REGIMES, not a contradiction in the spec

### Open Tyler-confirm items (do not implement until resolved)
- F3b purchasing tax treatment: exact mechanics of how Strother's materials-purchase tax
  appears on the estimate
- Residential vs. commercial remodel classification method for `ks_remodel`

## 5. Statutory Proposal Wording

When tax is included in a proposal, the disclosure line must read exactly:

> ALL APPLICABLE SALES TAXES ARE INCLUDED

Do not paraphrase this. Do not add or remove words.

## 6. Per-Scope Rate Overrides

- `overhead_rate` on `scopes` overrides the system default for that scope
- `margin_rate` on `scopes` overrides the system default for that scope
- `material_overhead_rate` on `scopes` is only used by `install_focus` formula
- System defaults live in `system_settings` table (key/value pairs)
- When a scope has an override, display it visually distinct from the default in the UI

## 7. Default Rates (from system_settings)

| Setting key | Default value |
|---|---|
| `default_overhead_rate` | 0.20 (20%) |
| `default_margin_rate` | 0.30 (30%) |
| `default_labor_rate` | 70.00 ($/hr) |
| `default_mileage_rate` | 0.655 ($/mi) |
| `default_galv_rate` | 0.70 ($/lb) |
| `default_tax_rate` | 0.09 (9% MO) |

These are stored as decimals (0.20, not 20). Rates on the `scopes` table are also decimal(5,4).

## 8. Galvanizing Calculator

```
Total Weight (lbs) = Weight per foot (lb/ft) × Total linear feet
Galv Cost = Total Weight × galv_rate
```

- Galv cost is a line item in `scope_materials`, vendor = AZZ
- Auto-populated from the galvanizing calculator — not manually entered
- Default rate = $0.70/lb (from system_settings, overridable)

## 9. Pricing Snapshot Requirements

When a proposal is generated, record:
- `overhead_rate` used per scope
- `margin_rate` used per scope
- `tax_rate` used
- `tax_regime`
- `material_total`, `equipment_total`, `labor_total`
- `grand_total` (formula-derived)
- `manual_sell_price` (if set)
- `customer_facing_total` (grand_total + tax, or manual_sell_price)
- Formula type (`estimate_type`)

Never recalculate a sent proposal from current scope data — always read the snapshot.

## 10. T7 Equipment Tax (UNRESOLVED)

Three conflicting postures exist across documents. Do NOT implement equipment tax logic
until Tyler has issued a ruling. Flag any code that assumes a position on this as a
blocker and surface it for resolution.

## 11. What This Skill Overrides

If you see any of the following in the codebase and they conflict with this skill, flag
it as a documentation-state problem and do NOT silently follow the stale version:

- Comments in migration headers
- Field-level docblocks in models
- Anything in README or inline code comments

The authority hierarchy is: this skill > AGENTS.md > handoff documents > migration headers.
