> ## Documentation Index
> Fetch the complete documentation index at: https://docs.planeconnection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Maintenance Billing Reference

> Labor rates, parts markup tiers, estimate statuses, billing types, and the estimate-to-invoice lifecycle.

PlaneConnection's maintenance billing system calculates work order costs from
configurable labor rates and parts markup rules, generates formal estimates,
and tracks those estimates through approval and invoicing. This page is the
technical reference for all billing configuration and lifecycle rules.

<Info>
  Billing configuration is managed in **Maintenance > Billing Settings**.
  For step-by-step setup instructions, see the billing settings how-to guide.
  For the API reference, see [Maintenance API Endpoints](/en/reference/api/maintenance-endpoints).
</Info>

## Labor Rate Structure

Labor rates are defined per workspace and determine how technician time is
priced on billing estimates. Each rate has a base hourly rate plus optional
multipliers for overtime and AOG (Aircraft on Ground) situations.

### Mechanic Types

| Mechanic Type | API Value     | Description                                                                                   |
| ------------- | ------------- | --------------------------------------------------------------------------------------------- |
| A\&P Mechanic | `ap`          | Airframe and Powerplant certificate holder. Standard maintenance labor.                       |
| IA Inspector  | `ia`          | Inspection Authorization holder. Higher rate reflecting inspection authority per 14 CFR 43.7. |
| Avionics      | `avionics`    | Avionics technician. Specialized rate for electronic and instrument work.                     |
| Sheet Metal   | `sheet_metal` | Structural repair specialist. Rate for airframe structural work.                              |
| General       | `general`     | General labor (cleaning, ground handling, non-certificated tasks).                            |

### Rate Multipliers

Each labor rate includes two optional multipliers applied to the base hourly rate:

| Multiplier   | Default | Description                                                                                                            |
| ------------ | :-----: | ---------------------------------------------------------------------------------------------------------------------- |
| **Overtime** |   1.5x  | Applied to labor hours worked outside normal business hours.                                                           |
| **AOG**      |   1.5x  | Applied when the work order priority is `aog` (Aircraft on Ground). Reflects the urgency premium for grounding events. |

**Effective cost calculation:**

```
standard_cost   = hours x hourly_rate
overtime_cost   = hours x hourly_rate x overtime_multiplier
aog_cost        = hours x hourly_rate x aog_multiplier
```

### Rate Configuration Fields

| Field                 | Type    | Required | Description                                                                            |
| --------------------- | ------- | :------: | -------------------------------------------------------------------------------------- |
| `rate_name`           | String  |    Yes   | Display name for the rate (e.g., "Standard A\&P Rate").                                |
| `mechanic_type`       | Enum    |    Yes   | One of: `ap`, `ia`, `avionics`, `sheet_metal`, `general`.                              |
| `hourly_rate`         | Number  |    Yes   | Base hourly rate in USD. Must be greater than zero.                                    |
| `overtime_multiplier` | Number  |    No    | Multiplier for overtime hours. Defaults to 1.5.                                        |
| `aog_multiplier`      | Number  |    No    | Multiplier for AOG priority work orders. Defaults to 1.5.                              |
| `effective_date`      | Date    |    Yes   | Date from which this rate applies. Allows rate versioning.                             |
| `expires_at`          | Date    |    No    | Optional expiration date. Null means the rate is active indefinitely.                  |
| `is_default`          | Boolean |    No    | If true, this rate is used when no specific rate is assigned to an estimate line item. |

<Note>
  Only one rate per workspace should be marked as the default (`is_default = true`). When generating
  an estimate, the system uses the most recent default rate if no rate is explicitly assigned. If no
  default rate exists, a system fallback rate is applied.
</Note>

## Parts Markup Tiers

Parts markup rules define the profit margin applied to parts costs on billing
estimates. Rules are configured as tiered cost ranges, allowing different
markup percentages for different part price points.

### How Markup Tiers Work

When an estimate is generated, each parts line item's unit cost is evaluated
against the markup rules in sort order. The first rule whose cost range
matches the unit cost determines the markup percentage.

**Example tier structure:**

Markup tiers are fully configurable. A typical setup uses tiered cost
ranges with higher markup percentages on lower-cost parts and lower
percentages on major components. You can create as many tiers as needed
to match your shop's pricing strategy.

### Markup Rule Fields

| Field            | Type    | Required | Description                                                                          |
| ---------------- | ------- | :------: | ------------------------------------------------------------------------------------ |
| `rule_name`      | String  |    Yes   | Display name for the rule (e.g., "Small Parts 100%").                                |
| `rule_type`      | String  |    Yes   | `parts_markup` for parts tiers, `shop_supplies` for shop supply charges.             |
| `cost_floor`     | Number  |    No    | Minimum unit cost for this tier (inclusive). Null means no lower bound.              |
| `cost_ceiling`   | Number  |    No    | Maximum unit cost for this tier (exclusive). Null means no upper bound.              |
| `markup_percent` | Number  |    Yes   | Percentage markup applied to unit cost.                                              |
| `basis_type`     | String  |    No    | For shop supply rules: `labor_total` (percentage of labor) or `flat` (fixed amount). |
| `flat_amount`    | Number  |    No    | For flat-rate shop supply rules: the fixed dollar amount.                            |
| `sort_order`     | Number  |    Yes   | Evaluation order. Lower numbers are evaluated first.                                 |
| `is_active`      | Boolean |    Yes   | Only active rules are applied during estimate generation.                            |

## Shop Supply Rules

In addition to parts markup, operators can configure shop supply charges
that cover consumables (safety wire, sealant, hardware, rags, etc.) not
individually tracked as inventory items.

Shop supply rules support two basis types:

| Basis Type    | Calculation                      | Example                                 |
| ------------- | -------------------------------- | --------------------------------------- |
| `labor_total` | Percentage of total labor cost   | 5% of $2,000 labor = $100 shop supplies |
| `flat`        | Fixed dollar amount per estimate | \$75 flat shop supply charge            |

## Billing Types

Each estimate is assigned a billing type that determines how the final
invoice is calculated:

| Billing Type           | API Value            | Description                                                                                                                           |
| ---------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Time and Materials** | `time_and_materials` | Customer pays actual labor hours at the applicable rate plus actual parts cost with markup. The standard billing method.              |
| **Flat Rate**          | `flat_rate`          | Customer pays a fixed price regardless of actual hours or parts consumed. Used for standard inspections or published service pricing. |
| **Hybrid**             | `hybrid`             | Combination of flat-rate labor and time-and-materials parts, or vice versa.                                                           |
| **Not to Exceed**      | `not_to_exceed`      | Time and materials billing with a maximum cap (NTE amount). Customer pays actual costs up to the NTE ceiling.                         |

### NTE (Not to Exceed) Amounts

When billing type is `not_to_exceed`, the estimate includes an `nte_amount`
field representing the maximum the customer will be invoiced. If actual costs
exceed the NTE amount, the operator absorbs the difference.

## Estimate Statuses

Billing estimates follow a lifecycle from creation through customer approval
to final invoicing.

| Status                                 | API Value  | Description                                                                  |
| -------------------------------------- | ---------- | ---------------------------------------------------------------------------- |
| <Badge color="gray">Draft</Badge>      | `draft`    | Estimate created and under internal review. Not yet visible to the customer. |
| <Badge color="blue">Sent</Badge>       | `sent`     | Estimate has been sent to the customer for review and approval.              |
| <Badge color="green">Approved</Badge>  | `approved` | Customer has approved the estimate. Work may proceed or continue.            |
| <Badge color="red">Rejected</Badge>    | `rejected` | Customer has declined the estimate. Work scope may need revision.            |
| <Badge color="purple">Invoiced</Badge> | `invoiced` | Estimate has been converted to an invoice. Final billing record.             |

### Estimate Lifecycle

```mermaid theme={}
stateDiagram-v2
    [*] --> Draft : Estimate generated
    Draft --> Sent : Send to customer
    Draft --> Draft : Revise
    Sent --> Approved : Customer approves
    Sent --> Rejected : Customer declines
    Sent --> Draft : Recalled for revision
    Approved --> Invoiced : Convert to invoice
    Rejected --> Draft : Revise and resend
    Invoiced --> [*]
```

## Estimate Generation

When a billing estimate is generated for a work order, the system performs
the following calculation:

<Steps>
  ### Collect work order items

  The system queries all items attached to the work order, classifying each as
  either a labor task (has `estimated_hours`) or a parts item (has `quantity`
  and `unit_cost`).

  ### Calculate labor costs

  For each labor item:

  * Look up the applicable labor rate (default rate for the workspace if none specified)
  * Multiply estimated hours by the hourly rate
  * Sum all labor line items into `labor_total`

  ### Calculate parts costs with markup

  For each parts item:

  * Evaluate the unit cost against active markup rules (in sort order)
  * Apply the matching tier's markup percentage to compute the unit price
  * Multiply unit price by quantity for the line total
  * Sum base parts costs into `parts_total`
  * Sum markup amounts into `parts_markup_total`

  ### Calculate shop supplies

  Evaluate shop supply rules against the labor total or as flat amounts.
  Sum into `shop_supplies_total`.

  ### Compute totals

  ```
  subtotal     = labor_total + parts_total + parts_markup_total + shop_supplies_total
  tax_amount   = subtotal x tax_rate  (if applicable)
  total_amount = subtotal + tax_amount
  ```
</Steps>

## Estimate Fields

| Field                    | Type   | Description                                                           |
| ------------------------ | ------ | --------------------------------------------------------------------- |
| `estimate_number`        | String | Auto-generated identifier (format: `EST-{unique_id}`).                |
| `work_order_id`          | String | Reference to the associated work order.                               |
| `billing_type`           | Enum   | One of: `time_and_materials`, `flat_rate`, `hybrid`, `not_to_exceed`. |
| `nte_amount`             | Number | Maximum billable amount (NTE billing type only).                      |
| `labor_total`            | Number | Sum of all labor line item costs.                                     |
| `parts_total`            | Number | Sum of all parts line item base costs (before markup).                |
| `parts_markup_total`     | Number | Total markup applied to parts.                                        |
| `shop_supplies_total`    | Number | Total shop supply charges.                                            |
| `outside_services_total` | Number | Costs for outsourced work (vendor invoices).                          |
| `subtotal`               | Number | Sum of all cost categories before tax.                                |
| `tax_rate`               | Number | Applicable tax rate (decimal, e.g., 0.08 for 8%).                     |
| `tax_amount`             | Number | Calculated tax amount.                                                |
| `total_amount`           | Number | Final estimate total including tax.                                   |
| `customer_name`          | String | Customer or aircraft owner name for the estimate.                     |
| `customer_email`         | String | Customer contact email for estimate delivery.                         |
| `payment_terms`          | String | Payment terms (e.g., "Net 30", "Due on receipt").                     |
| `notes`                  | Text   | Internal or customer-facing notes.                                    |
| `status`                 | Enum   | Current estimate status (see Estimate Statuses above).                |

## Billing Events

Every significant action on an estimate is recorded as a billing event for
audit trail purposes:

| Event Type          | Description                                   |
| ------------------- | --------------------------------------------- |
| `estimate_created`  | New estimate generated from work order data.  |
| `estimate_sent`     | Estimate sent to customer.                    |
| `estimate_approved` | Customer approved the estimate.               |
| `estimate_rejected` | Customer rejected the estimate.               |
| `estimate_revised`  | Estimate was modified after initial creation. |
| `invoice_created`   | Estimate converted to a final invoice.        |
| `payment_received`  | Payment recorded against the invoice.         |

## Related

<CardGroup cols={2}>
  <Card title="Work Order Statuses" icon="list-check" href="/en/reference/work-order-statuses">
    Lifecycle of work orders that billing estimates are attached to.
  </Card>

  <Card title="Maintenance API Endpoints" icon="code" href="/en/reference/api/maintenance-endpoints">
    REST API for creating rates, generating estimates, and retrieving billing data.
  </Card>

  <Card title="Maintenance Data Model" icon="diagram-project" href="/en/explanation/maintenance-architecture">
    How billing fits into the broader maintenance data flow.
  </Card>

  <Card title="Financial Reports" icon="chart-line" href="/en/reference/reports-financial">
    Financial reporting that incorporates maintenance billing data.
  </Card>
</CardGroup>
