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

# Inventory settings

> Set expiry alert horizons, decide whether the till may sell out-of-stock items, require expiry dates on delivery, and understand the reset.

export const StillStuck = ({topic}) => <div className="ck-callout ck-callout--note" role="note">
    <p className="ck-callout__body">
      <strong>Still stuck{topic ? ` with ${topic}` : ''}?</strong>{' '}
      Check <a href="/platform/help/troubleshooting">Troubleshooting</a> first —
      it covers the failures we see most often. If that does not resolve it,{' '}
      <a href="/platform/help/contact-support">contact support</a> and include
      your workspace name and the time the problem happened, so we can find the
      matching entry in your audit log.
    </p>
  </div>;

export const TaskHeader = ({before, time, after}) => <div className="ck-task">
    {before ? <div className="ck-task__cell">
        <div className="ck-task__title">Before you start</div>
        <p className="ck-task__body">{before}</p>
      </div> : null}

    {time ? <div className="ck-task__cell">
        <div className="ck-task__title">Takes about</div>
        <p className="ck-task__body">{time}</p>
      </div> : null}

    {after ? <div className="ck-task__cell">
        <div className="ck-task__title">When you're done</div>
        <p className="ck-task__body">{after}</p>
      </div> : null}
  </div>;

export const Path = ({steps = []}) => <span className="ck-path">
    {steps.map((s, i) => <span key={i} className="ck-path__step">
        {i > 0 ? <span className="ck-path__sep" aria-hidden="true">
            ›
          </span> : null}
        {s}
      </span>)}
  </span>;

export const Availability = ({editions = ['all'], plans, roles, note}) => {
  const list = editions.includes('all') ? ['clinic', 'pharmacy', 'lims'] : editions;
  return <div className="ck-avail" role="note" aria-label="Feature availability">
      <span className="ck-avail__label">Available in</span>

      {list.map(e => <span key={e} className={`ck-pill ck-pill--${e}`}>
          {EDITION_LABELS[e] || e}
        </span>)}

      {plans ? <span className="ck-avail__label">Plan</span> : null}
      {plans ? <span className="ck-pill ck-pill--plan">{plans}</span> : null}

      {roles ? <span className="ck-avail__label">Who</span> : null}
      {roles ? <span className="ck-pill ck-pill--role">{roles}</span> : null}

      {note ? <span className="ck-avail__note">{note}</span> : null}
    </div>;
};

<Availability editions={['pharmacy']} roles="Owner, manager or accountant" note="The Danger Zone is visible to the owner only" />

Four small settings on this tab decide how forgiving your stock records are: when expiry alerts start, whether the till may sell something the system thinks you do not have, and whether a delivery can be booked in without an expiry date.

<Path steps={['Sidebar', 'Settings', 'Pharmacy', 'Inventory']} />

<TaskHeader before="At least one stock item, so you can see the effect" time="5 minutes" after="Expiry alerts on your own schedule and a till that behaves the way you want when stock runs out" />

## What this tab controls

The card is headed **Inventory** — "Expiry alerts, dispensing enforcement and inventory data controls."

| Control                                                                         | What it does                                                                          | Default                                          |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------ |
| **Expiry alert horizons**                                                       | Up to four warning points, each 1–365 days. "Get alerted as stock approaches expiry." | **90/60/30 days** for a pharmacy                 |
| **Enforce inventory on dispense**                                               | Requires every dispensed medication to be linked to stock with enough on hand.        | **Off** — "Best-effort — never blocks (default)" |
| **New-item defaults** — **Low-stock threshold**, **Reorder quantity**           | Applied to items created without their own values, including catalog imports.         | Empty (no default)                               |
| **Require expiry date on new lots**, under **Receiving quality**                | Refuses to receive stock into a new lot with no expiry date.                          | **Off**                                          |
| **Allow selling items with no recorded stock**, under **Selling without stock** | Lets the till sell an item whose recorded stock is zero.                              | **On**                                           |
| **Danger Zone** → **Reset inventory…**                                          | Erases the whole inventory module for a clean re-import.                              | Owner only                                       |

The three switches save the moment you flip them. **Expiry alert horizons** and **New-item defaults** have their own **Save horizons** and **Save defaults** buttons.

## Set it up

<Steps>
  <Step title="Set your expiry horizons">
    Type a number of days into the field and select **Add**. Each becomes a chip like **90 days**; remove one by selecting its ✕. Up to four. Select **Save horizons** — you get "Expiry alert horizons saved".
  </Step>

  <Step title="Decide about selling out of stock">
    Leave **Allow selling items with no recorded stock** on if goods routinely reach your shelf before they are booked in. Turn it off if you want the till to refuse instead.
  </Step>

  <Step title="Decide about expiry dates on delivery">
    Turn **Require expiry date on new lots** on if you want receiving to refuse an undated lot. The helper is blunt about the alternative: "Undated lots are allowed (not recommended for pharmacies)."
  </Step>

  <Step title="Set the new-item defaults">
    Enter a **Low-stock threshold** and a **Reorder quantity** in whole units, then select **Save defaults**. Leave either empty for no default.
  </Step>
</Steps>

## What changes once you save

| Setting                             | What you'll notice                                                                                                                                                                                                      |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Expiry alert horizons**           | An item crossing a horizon appears on the inventory **Alerts** tab and in the daily digest email. Removing a horizon stops those alerts; adding one can surface a batch of items at once.                               |
| **Allow selling…** turned **off**   | The till refuses the line outright when recorded stock is not enough — the sale stops until someone books stock in or adjusts the count.                                                                                |
| **Allow selling…** left **on**      | The sale goes through and the oversold quantity is logged. It reconciles itself when the stock is received, and anything still unreconciled shows up in the inventory digest. See [Record a sale](/pharmacy/pos/index). |
| **Require expiry date on new lots** | From that moment, **Receive** refuses a new lot with no expiry — on direct receiving and on purchase-order receipts alike. Topping up an existing dated lot is unaffected.                                              |
| **New-item defaults**               | Applied only to items created from now on. Existing items keep whatever they already have.                                                                                                                              |
| **Enforce inventory on dispense**   | Switched on, an unlinked medication or insufficient stock aborts the whole dispense. Switched off, dispensing never blocks and the drift is logged for review.                                                          |

**Requiring expiry dates does not fix the past.** Lots already booked in without one stay undated, and an undated lot is invisible to earliest-expiry picking and to every expiry alert — it will never warn you. Find them and correct them through a stock count. See [Batches and expiry](/pharmacy/inventory/batches-and-expiry).

## The Danger Zone

<Warning>
  **Reset inventory…** permanently erases the entire inventory module — catalog, lots, stock levels, ledger, purchase orders, vendors, locations and device history. It cannot be undone. Your medication list, store history and clinical records are kept. It exists for one purpose: a clean re-import after a bad first load.
</Warning>

The card is **hidden entirely** from anyone who is not the pharmacy owner — a manager or an accountant does not see a greyed-out button, they see nothing at all, and there is no explanation. That is intended.

The owner gets a preview before anything happens. The dialog is headed "Reset the whole inventory?", lists exactly how many records would go from each area, and only then asks you to type `RESET` to confirm deleting that many records. If your inventory is already empty it says so and offers no confirm button. When it finishes you get "Inventory reset — \{n} record(s) across \{n} table(s) deleted."

## Check it worked

Reload the tab — every switch and chip should be where you left it. Then test the behaviour: try to receive a lot with the expiry blank and see whether it is refused, and try to sell one unit of something recorded at zero.

## Common issues

<AccordionGroup>
  <Accordion title="I get no expiry alerts at all">
    Either every lot is dated further out than your longest horizon, or the lots have no expiry date. Undated lots never trigger an alert — that is what **Require expiry date on new lots** prevents happening again.
  </Accordion>

  <Accordion title="Add is missing next to the horizons">
    You already have four, which is the maximum. Remove one and the field comes back. Trying to add a fifth gives "Up to 4 horizons."
  </Accordion>

  <Accordion title="The till refuses an item that is on the shelf">
    **Allow selling items with no recorded stock** is off. Either turn it on, or book the delivery in first.
  </Accordion>

  <Accordion title="I can't find the Danger Zone">
    It is owner-only, and hidden rather than disabled. Ask the pharmacy owner.
  </Accordion>

  <Accordion title="The reset is blocked">
    The banner reads "This inventory cannot be reset" — clinical administration records reference these lots and a reset would destroy that traceability. Adjust quantities through a stock count instead. See [Stock counts](/pharmacy/inventory/stock-counts).
  </Accordion>

  <Accordion title="New items still have no low-stock threshold">
    The defaults apply only to items created after you saved them, and only where the item itself supplies no value. Edit the existing ones, or re-import them.
  </Accordion>
</AccordionGroup>

<StillStuck />
