# Inventory count: counted product "disappears" from Stock Balances (zero-balance row gap)

> updated: 2026-06-27 · status: **FIXED + MERGED TO `main`** (BE `d247a63fa`). Portal ticket **ISS-2026-0004** (مون/project 283) → `client_review`.
> Code: BE `/home/moonui2/moon-erp-be` (`Modules/Inventory`). Reported on the `smart` deployment (CNT-000001 / CNT-000002).

## Symptom (client)
In `…/app/core/inventory-counts`, counting a product and setting it to **zero** makes it **disappear from "أرصدة المخزون" (Stock Balances)**. **Selective** — one counted product vanished (`P-000256`), another stayed (`P-000263`). Client noticed: an auto-adjustment `ADJ-000001` was created for the one that **stayed**, but **not** for the one that vanished.

## Root cause (code-verified)
The count cycle is otherwise correct — **nothing deletes or filters stock-balance rows** (grepped the whole BE: no `StockBalance` delete anywhere; `StockBalanceController::index` shows zeros by default; the FE screen even highlights zero-stock rows). The product wasn't deleted — **it never had a stock-balance row.**

`FinalizeCount::execute` (`Modules/Inventory/app/Actions/FinalizeCount.php`):
1. Per item: reads system qty from the existing `StockBalance` (or 0 if none), computes `difference = counted − system`.
2. Auto-creates an `InventoryAdjustment` **only for items with `difference != 0`**.

So a product whose **system qty is 0 (no balance row) counted to 0** → `difference = 0` → **no adjustment, and no balance row is ever created** → it's absent from "Stock Balances" (which lists existing rows) → looks like it "vanished". (`P-000256` = no diff → no ADJ → no row; `P-000263` = had a diff → `ADJ-000001` → got a row → stayed.)

## Fix
In `FinalizeCount::execute`, the per-item balance lookup now **`firstOrCreate`s** the row (matching the canonical `StockService::getOrCreateBalance` pattern — keys `product_id/product_variant_id/warehouse_id`, defaults `company_id, quantity 0, average_cost 0, total_value 0`) instead of `first()`. So **every counted product gets a stock-balance row** (0-qty if never stocked) and stays visible in "أرصدة المخزون". The difference/adjustment logic is unchanged (diff-0 items still create no adjustment).

- Test added (Pest): *"finalize creates a zero stock balance row for a counted product that had none"* → `InventoryCountApiTest.php`. **18 count tests green.**
- Changelog: `[Unreleased]` bullet added. `php -l`/`pint` clean.
- ⚠️ Note: client's `smart` copy needs the **next MoonStack update** (release/ship) before the fix is live there.

## Decision
Ensure-the-row at the **count** (where the user expects the product to appear), not by relaxing the report filters — keeps valuation/value reports correct (they still legitimately exclude zero-value rows) while the raw "Stock Balances" screen shows everything counted.
