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

# Sales targets

> Set per-location sales goals and track progress from admin and Shopify POS

Sales targets let you set per-location sales goals across three metrics and track progress in real time from both the Charlie admin and Shopify POS.

<Info>
  Sales targets are a measurement and motivation tool. They don't affect order routing or fulfillment constraints.
</Info>

## What you can track

Three metrics, configurable per location and period:

| Metric                          | Description                        | Value type |
| ------------------------------- | ---------------------------------- | ---------- |
| **Gross sales**                 | Total sales revenue for the period | Money      |
| **Average order value (AOV)**   | Average revenue per order          | Money      |
| **Units per transaction (UPT)** | Average items per order            | Decimal    |

### Period types

| Period    | Length                               |
| --------- | ------------------------------------ |
| **Day**   | 1 day                                |
| **Week**  | 7 days                               |
| **Month** | 1 calendar month from the start date |
| **Year**  | 1 calendar year from the start date  |

The period end date is computed automatically from the start date and the period type.

### Target status

Charlie computes the status of each target based on its current value, target value, and period dates:

| Status           | When                                   |
| ---------------- | -------------------------------------- |
| **Upcoming**     | Period hasn't started yet              |
| **In progress**  | Period is active and hasn't ended      |
| **Achieved**     | Period ended and the target was met    |
| **Not achieved** | Period ended and the target wasn't met |

## Setting up targets

### Single target

<Steps>
  <Step title="Open Sales targets">
    Go to **Charlie → Settings → Sales targets**.
  </Step>

  <Step title="Create a target">
    Click **Add target** and fill in the form:

    | Field            | Description                                                |
    | ---------------- | ---------------------------------------------------------- |
    | **Location**     | The location this target applies to                        |
    | **Metric**       | Gross sales, AOV, or UPT                                   |
    | **Period type**  | Day, Week, Month, or Year                                  |
    | **Period start** | The date the period begins (YYYY-MM-DD)                    |
    | **Target value** | The goal value in your store currency (or decimal for UPT) |
  </Step>

  <Step title="Save">
    Save the target. It appears immediately in the targets table with its computed status.
  </Step>
</Steps>

### Bulk import via CSV

For setting many targets at once across locations and periods.

<Steps>
  <Step title="Download the template">
    On the Sales targets page, click **Download template**. The template pre-fills a row for each of your locations so you can fill in the metric and target value without looking up IDs.
  </Step>

  <Step title="Fill in the CSV">
    Edit the template in your spreadsheet of choice.

    | Column          | Required | Description                                                 |
    | --------------- | -------- | ----------------------------------------------------------- |
    | `location_id`   | Yes      | Shopify location GID (`gid://shopify/Location/...`)         |
    | `location_name` | No       | For your reference, ignored on import                       |
    | `metric`        | Yes      | `GROSS_SALES`, `AOV`, or `UPT`                              |
    | `period_type`   | Yes      | `DAY`, `WEEK`, `MONTH`, or `YEAR`                           |
    | `period_start`  | Yes      | ISO date `YYYY-MM-DD`                                       |
    | `period_end`    | No       | Computed automatically if omitted                           |
    | `target_value`  | Yes      | Positive number in major units (e.g. `80000.50`)            |
    | `currency`      | No       | 3-letter ISO currency code, defaults to your store currency |
  </Step>

  <Step title="Upload and validate">
    Click **Import targets** and upload your CSV. The wizard walks you through three steps:

    1. **Upload** — pick the CSV file
    2. **Validate** — row-by-row error report. Fix any errors in your spreadsheet and re-upload before proceeding
    3. **Confirm** — review the parsed targets, then apply
  </Step>
</Steps>

### Export current targets

Click **Export** on the Sales targets page to download all current targets as CSV. Useful for backup, review, or making bulk edits before re-importing.

## Tracking from Shopify POS

The POS Sales targets tile lets your retail team see how they are tracking against the day's goals without leaving POS.

### The tile

The tile appears on the POS smart grid for the active location and shows a quick on-track summary (e.g. "2 / 3 on track"). Tap the tile to open the modal.

### The modal

The modal shows one card per metric (Gross sales, AOV, UPT):

* **Current value** for the active period at the current POS location
* **Target value** as configured in admin
* **Progress percentage** of current vs target
* **Status badge** (Upcoming, In progress, Achieved, or Not achieved)
* **Period dates** the target applies to

If no target is set for the current period for a given metric, the card shows a "No target set" empty state with a link back to the admin.

### Include pending payments

By default, the POS tile and modal **exclude orders that are still pending payment** — a pending sale only counts toward your actuals once it's paid. To include them, turn on **Include pending payments** in the modal.

* The toggle sits just below the period selector in the modal
* It affects all three metrics (Gross sales, AOV, and UPT), since adding orders shifts the averages too
* Each till remembers its own setting, the same way it remembers the selected period
* The tile's on-track summary updates to match within a few seconds

### Offline behavior

The POS extension caches the last known values per device so the tile and modal still work without a connection. The cache refreshes every time the modal opens online.

<Note>
  The POS tile queries up to 5,000 orders per period for performance. If a period exceeds this volume, totals are approximate and a console warning is logged.
</Note>

### Languages

The POS tile and modal are translated into English and French out of the box. POS picks the language based on the device's POS language setting.

## How values are computed

Sales targets track your **local pickup and retail (POS) orders** at the location — other order types aren't counted. Charlie computes progress separately on each surface, from the data each one has available:

* **In the admin dashboard**, actuals come from Charlie's fulfillment analytics, aggregated per location over the target's period and windowed on when each order was fulfilled. This data has no payment-status dimension, so pending-payment orders always count here.
* **On the POS tile**, actuals are computed live from the Shopify Orders API for the current POS location, windowed on each order's creation time, and exclude pending-payment orders by default.

Both surfaces measure the same three metrics:

* **Gross sales** — total order revenue across the period
* **AOV** — gross sales / order count
* **UPT** — total item quantity / order count

`progressPct` = currentValue / targetValue × 100. Status is recomputed from the current date and the period dates on every load.

<Note>
  Money values (Gross sales, AOV) are stored in cents internally and displayed in your store currency. UPT is stored as a raw decimal (e.g. `2.5` units per transaction).
</Note>

<Note>
  **Admin and POS totals can differ, and that's expected** — the two surfaces use different data sources, windowing, and payment-status handling, as described above. Turn on **Include pending payments** on POS to bring its numbers in line with the admin dashboard.
</Note>

## Best practices

<CardGroup cols={2}>
  <Card title="Start with one metric per location" icon="play">
    Pick the most actionable metric per location (often gross sales for stores) before layering AOV and UPT.
  </Card>

  <Card title="Use the template for bulk setup" icon="file-arrow-down">
    Download the CSV template before bulk import — it's pre-filled with your location IDs so you don't have to look them up.
  </Card>

  <Card title="Re-export before big changes" icon="file-export">
    Export current targets before making sweeping edits so you can roll back via re-import if needed.
  </Card>

  <Card title="Refresh during shifts" icon="rotate">
    Encourage retail staff to open the POS modal at key shift times — totals refresh on every open.
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="POS tile shows old values">
    The POS extension caches the last known values per device. If you just edited a target in admin, open the modal once to trigger a refresh. The next render of the tile will reflect the new values.
  </Accordion>

  <Accordion title="POS tile shows no targets">
    Check:

    1. Is there a target for the current period (today's date falls within `periodStart` and `periodEnd`) at the active POS location?
    2. Did the metafield sync run after creating the target? Edits flow to the shop metafield `$app:sales_targets.data` automatically.
    3. Is the POS device online to fetch the latest metafield?
  </Accordion>

  <Accordion title="CSV import fails validation">
    Common causes:

    * `location_id` is not the full Shopify GID (`gid://shopify/Location/123`)
    * `metric` is lowercase or contains typos (must be `GROSS_SALES`, `AOV`, or `UPT`)
    * `period_start` is not in `YYYY-MM-DD` format
    * `target_value` includes a currency symbol — use plain numbers like `80000.50`
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Location capacity" icon="gauge-high" href="/locations/capacity">
    Daily order limits per location
  </Card>

  <Card title="Analytics" icon="chart-line" href="/analytics">
    Historical sales and fulfillment metrics
  </Card>
</CardGroup>
