# Indirect Goods Upgrade — Phase 6 FOC Inventory and Issue Completion

Completed: 11 July 2026

## Outcome

Indirect goods now have a separate operational FOC ledger and can be issued from that ledger to projects through the shared Material Issue screen. Normal indirect warehouse inventory is never changed by an indirect FOC issue.

## Enabled functionality

The `foc_issue_enabled` feature gate is enabled.

### Indirect FOC inventory

Added an operational FOC inventory page with:

- item and division selection;
- serviceable, repairable, damaged, expired and scrap conditions;
- source reference, invoice, batch and expiry tracking;
- positive and negative adjustments;
- existing-row adjustment support;
- adjustment reasons and user audit;
- current available/reserved quantities;
- sidebar navigation.

Only rows that are serviceable, approved, available and have net stock can be issued.

### Division availability

Added a dedicated indirect FOC availability endpoint. The shared issue form now requests the correct ledger based on context:

- warehouse context reads `indirect_goods_inventory`;
- FOC context reads `indirect_goods_foc_inventory`.

The FOC table no longer displays normal warehouse quantity as FOC availability.

### FOC issue

Indirect FOC inputs are processed by `IndirectGoodsIssueService::issueFoc()`.

For each issue the service atomically:

1. validates request status, request balance and division;
2. locks eligible FOC rows;
3. allocates FEFO then FIFO;
4. deducts FOC stock;
5. creates approved FOC dispatch adjustments;
6. adds zero-cost stock to indirect project inventory;
7. creates fulfillment and allocation provenance;
8. creates a real FOC-to-project movement;
9. updates request quantities and statuses;
10. rebuilds the indirect division ledger.

## Adjustment safety

- New FOC records must start with positive stock.
- Reductions cannot make stock negative.
- Non-serviceable conditions are quarantined and not issuable.
- Adjustment reasons are mandatory.
- Every change creates an FOC adjustment row.
- Manual adjustments rebuild the division summary.

## Verification

### Static checks

- Controllers and services pass PHP syntax checks.
- FOC inventory and FOC availability routes are registered.
- Blade views compile successfully.
- Domain invariant tests: 5 passed.

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

Temporary serviceable FOC stock of 3 units was created, then 1 unit was issued to a pending project request.

Verified during the transaction:

- fulfillment type: `foc_transfer`;
- fulfillment quantity: 1.0000;
- fulfillment cost: 0.0000;
- remaining FOC stock: 2.0000;
- adjustments: `stock_increase`, then `dispatch`;
- warehouse quantity change: 0.00;
- project quantity change: +1.00;
- released quantity change: +1.00;
- movement source: FOC;
- movement destination: project;
- reconciliation variance: 0.0000.

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

## Phase gate

Phase 6 is complete. Phase 7 may enable project returns that reduce indirect project inventory and increase only this indirect FOC ledger.
