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

# How to run a maintenance programme

> Turn one-off repairs into a schedule — the attributes you have to create yourself, a formula that raises the flag, and reserving the unit while work happens.

<Card title="Open in TWICE Admin" icon="external-link" href="https://admin.twicecommerce.com/inventory/stock-items" horizontal>
  inventory/stock-items
</Card>

Reserving one unit for a repair is a single action, and it is already covered in [Reserve a stock item](/docs/guides/inventory/reserve-a-stock-item). This guide is about the layer above it: a programme that tells you *which* units need attention before someone notices a problem.

<Warning>
  **TWICE has no maintenance module.** There is no built-in service schedule, no inspection checklist, no certification tracker, and no `Needs service` field waiting to be switched on.

  What there is: attributes you define, formulas that compute from them, reservations that take a unit out of availability, and documents attached to the record. A maintenance programme is something you assemble from those four. This guide is that assembly, and it is honest about the seams.
</Warning>

## Prerequisites

<Warning>
  **Required permissions:** `inventory:stock_item:view` and `inventory:stock_item:manage`, plus the ability to create attributes on the inventory resource. All four system roles hold the stock item permissions.
</Warning>

<Info>
  **Decide your trigger before you build anything.** Maintenance is driven by time or by use, and the two need different data:

  * **By time** — months since the last service. Needs a date you maintain.
  * **By use** — rentals, hours, cycles, distance. Needs a number you maintain.

  TWICE does not count either for you. Pick the one your equipment actually wears by, and be honest about whether anyone will keep it up to date. A programme built on a number nobody updates is worse than no programme, because it looks like it is working.
</Info>

## The Walkthrough

<Steps>
  <Step title="Create the attributes the programme runs on">
    None of these exist until you make them. Create them on the **inventory** resource — see [Create attributes](/docs/concepts/admin/attributes) for the mechanics.

    A workable minimum:

    | Attribute         | Format                | What maintains it                             |
    | ----------------- | --------------------- | --------------------------------------------- |
    | Last service date | Date                  | Set by whoever completes the work             |
    | Service count     | Number                | Incremented on completion                     |
    | Usage             | Number                | Whoever records use — TWICE does not count it |
    | Needs service     | Boolean, or a formula | Raised by hand, or computed                   |

    Group them so they sit together on the item rather than scattered through the Attributes tab.

    <Note>**Usage is the weak link.** There is no meter and nothing reads hours, cycles, or distance off a unit. If nobody is going to type it in, build the programme on elapsed time instead — a date is at least self-maintaining in the sense that it only has to be set once per service.</Note>
  </Step>

  <Step title="Make the flag compute itself">
    Setting **Needs service** by hand works and is a reasonable place to start. The programme gets useful when it raises itself.

    Make it a **formula** attribute instead. Formula attributes are computed rather than typed, they can reference other attributes on the same item, and TWICE recalculates them for you.

    The two shapes worth building:

    * **Usage-based** — service due once usage passes a threshold.
    * **Time-based** — service due once enough months have passed since the last service date.

    The function library and syntax are on the [Formulas](/docs/admin/formulas) page. Formulas are an item-level thing, so build them on the stock item rather than expecting a SKU to carry them down.
  </Step>

  <Step title="Find the units that are due">
    A flag is only worth having if you can list what it caught. In **Inventory > Stock items**, filter on the attribute — attributes are available as table columns and filters — and you have the work queue.

    Save that view. A maintenance programme is a thing someone opens every week, and a saved filtered view is what turns the attribute into a routine.
  </Step>

  <Step title="Take the unit out of service">
    When a unit is going into the workshop, reserve it. A reservation on the item's **Events** tab blocks the dates and stops the unit being offered while work happens, without changing its lifecycle.

    Reserve rather than archive. Archiving is for stock leaving service permanently, and it releases the holds behind existing bookings — a repair does not want that.

    Read more: [Reserve a stock item](/docs/guides/inventory/reserve-a-stock-item)
  </Step>

  <Step title="Attach the evidence">
    Service notes, invoices, and inspection paperwork go on the item's **Documents** tab, against the unit they belong to.

    This is what makes the record worth keeping. A unit's provenance — including what was done to it and when — is exactly what someone will want at resale, at warranty, or after an incident.
  </Step>

  <Step title="Close the loop">
    When work finishes, update the attributes: set the last service date, increment the service count, reset usage if that is how you measure. Then end the reservation so the unit returns to availability.

    If **Needs service** is a formula, it clears itself the moment the underlying values change. If it is a boolean, someone has to remember — which is the argument for the formula.
  </Step>
</Steps>

## How do I know it worked?

* **The attributes are on the item**, and the item shows up when you filter on them.
* **The saved view lists exactly the units that are due**, and empties as work is completed.
* **A unit in the workshop is not bookable** — the reservation shows on its Events tab.
* **The paperwork is on the item**, not in someone's email.
* **After completion the flag clears** — by itself if it is a formula, by hand if it is not.

## Troubleshooting / Common Pitfalls

<AccordionGroup>
  <Accordion title="I cannot find the Needs service field">
    **It does not ship.** Neither do usage counters, service dates, or service counts. Some published pages name these as though they were built in — they are describing a pattern you build, not a feature you enable.

    **What to do:** create them as attributes, as in step one. Nothing about the programme works until they exist on your account.
  </Accordion>

  <Accordion title="The usage number is always out of date">
    **Expected, and the main reason usage-based programmes fail.** Nothing reads hours, cycles, or distance off a unit. The number is only as good as the discipline behind typing it in.

    **What to do:** either attach recording it to something that already happens every time — the return check, say — or switch the programme to elapsed time since the last service, which needs one update per service instead of one per rental.
  </Accordion>

  <Accordion title="A unit went out while it was supposed to be in for service">
    **Cause:** the flag was raised but the unit was never reserved. The attribute is information; it does not block anything on its own.

    **What to do:** make reserving the unit part of flagging it, not a separate step someone might skip. Flagging tells you; reserving stops it going out.
  </Accordion>

  <Accordion title="I archived a unit for a repair and now orders have conflicts">
    **Cause:** archiving releases the holds behind bookings that already had the unit assigned, leaving those orders in conflict. It is a lifecycle action, not an availability one.

    **What to do:** reserve for repairs; archive only for stock leaving service for good. To fix what has happened, unarchive and work through the conflicts on the affected orders.

    Read more: [Archive stock items](/docs/guides/inventory/archive-stock-items)
  </Accordion>

  <Accordion title="We need a checklist the technician has to complete">
    **Not available.** There is no inspection checklist, and no way to require one before a unit returns to the pool.

    **What to do:** keep the checklist wherever it lives now and attach the completed copy to the item's Documents tab. That gives you the record without pretending the enforcement exists.
  </Accordion>

  <Accordion title="We need to track certification or inspection expiry">
    **Only as a date you maintain.** There is no certification tracking and nothing warns you before an expiry.

    **What to do:** hold the expiry as a date attribute and build the same kind of formula flag against it, then work it from the same saved view. It is the same pattern as service intervals, pointed at a different date.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Reserve a stock item" icon="calendar-plus" href="/docs/guides/inventory/reserve-a-stock-item">
    Taking a unit out of availability while work happens.
  </Card>

  <Card title="Formulas" icon="calculator" href="/docs/admin/formulas">
    The syntax and function library behind a self-raising flag.
  </Card>

  <Card title="Attributes" icon="tags" href="/docs/concepts/admin/attributes">
    Creating the fields the programme runs on.
  </Card>

  <Card title="Read a stock item's history" icon="clock-rotate-left" href="/docs/guides/inventory/read-stock-item-history">
    Reading the service record back off a unit.
  </Card>
</CardGroup>
