# Indirect Goods Upgrade — Phase 7 FOC-Only Returns Completion

Completed: 11 July 2026

## Outcome

Indirect goods can now be returned from projects through a dedicated document workflow. Every completed accepted quantity moves from indirect project inventory to indirect FOC inventory only. Normal indirect warehouse inventory is never increased.

## Enabled workflow

The `returns_enabled` feature gate is enabled.

### Return lifecycle

```text
Create and submit -> Inspect -> Complete to indirect FOC
```

Completed returns cannot be edited through the workflow. Stock changes occur only during completion.

### Source selection

Returnable rows are calculated from exact fulfillment allocations:

```text
returnable = issued - returned - consumed - transferred
```

The create screen filters by project and division and displays only allocations with outstanding quantity and matching project inventory.

### Captured information

- `IGRT-YYYYMMDD-NNNN` return number;
- return date;
- project and division;
- original MR, request item, fulfillment and allocation;
- invoice and batch;
- submitted and accepted quantity;
- serviceable, repairable, damaged, expired or scrap condition;
- reason, receiver, document and notes;
- creator, inspector and completer audit fields.

## Completion transaction

For each accepted line `IndirectGoodsReturnService` atomically:

1. locks the return, fulfillment, allocation and project inventory;
2. revalidates source, project, item and division;
3. prevents over-return and negative project stock;
4. reduces indirect project inventory;
5. increments allocation and fulfillment returned quantities;
6. creates or updates destination indirect FOC inventory;
7. creates an approved `return_in` FOC adjustment;
8. creates project-to-FOC movement history;
9. updates fulfillment return status;
10. rebuilds the indirect division summary.

There is no code path from this workflow to `indirect_goods_inventory`.

## Condition handling

| Condition | FOC quality state | Issuable by default |
|---|---|---|
| Serviceable | Approved | Yes |
| Repairable | Quarantined | No |
| Damaged | Quarantined | No |
| Expired | Quarantined | No |
| Scrap | Quarantined | No |

Condition changes and disposal remain separate audited FOC operations.

## Operational pages

- Return list
- Project/division returnable-material selection
- Return details with inspect/complete actions
- Printable Indirect Goods Return Note — FOC Only
- Sidebar navigation

## Verification

### Static checks

- Models, controller and return service pass PHP syntax checks.
- Seven return routes are registered.
- All Blade templates compile successfully.
- Domain tests increased to 7 passing tests.

### Rolled-back end-to-end smoke test

One serviceable unit from a historic fulfillment was returned.

Verified during the transaction:

- return number: `IGRT-20260711-0001`;
- status: completed;
- warehouse quantity change: 0.00;
- project quantity change: -1.00;
- returned-to-FOC change: +1.00;
- indirect FOC quantity: +1.0000;
- FOC adjustment type: `return_in`;
- movement source: project;
- movement destination: FOC;
- fulfillment status: partially returned;
- reconciliation variance: 0.0000.

After rollback, all return, FOC, adjustment and baseline counts returned to their prior values.

## Phase gate

Phase 7 is complete. Phase 8 may integrate existing consumption, damaged and expiry operations with fulfillment allocations and the return/FOC condition model.
