# WP7 — Consignment receipt lines → the shared line-items component

**Repo:** FE (`/home/moonui2/public_html/moon-erp`) · **Branch:** `hazemdev2` · **Depends on WP6** · **BE change:** none

## Goal

`src/app/features/production/consignment/` receipt lines are **product · quantity · declared unit
cost · batch number · expiry · manufacturing date · computed line value · delete**. Give that grid
drag-to-reorder, drag-to-resize, and show/hide, persisted company-wide.

## ⚠️ Mechanism decided in advance: `TxColumnLayout`, NOT the shared component

The original brief said "convert to `TransactionLineItemsComponent`". **That has been overtaken by
WP6's finding — do not attempt the full conversion.**

`TxCellType` is `product | select | number | percent | computed | action | text` — **there is no
date cell**. WP6 hit exactly this on the MPS `period` column and took the documented escape hatch.
This grid has **two** date columns (`expiry_date`, `manufacturing_date`, confirmed at
`consignment.component.html:381` and `:390`). Rendering a date as `text` would drop the date picker
and let free text reach the payload; adding a `date` case means editing a component **12 live
screens render**.

**Settled call for this run: do not grow `TxCellType`.** The user-visible outcome is identical
either way — the same drag, the same resize, the same persisted layout — and this screen already
uses the shared `<app-product-search>` for its product cell, so the full conversion buys nothing the
owner would see. Use `TxColumnLayout` over the existing cells.

Read **both** reference implementations before writing anything:
- `a8c20cad5` — the BOM grid (FormArray rows)
- `433347abe` — the MPS grid (**`ngModel` signal rows, exactly like this screen**) and its report at
  `../tasks/WP6-report.md`

The MPS one is your closest match. Follow its structure; do not re-derive it.

## Keep the cells verbatim

Only column ORDER and WIDTH become dynamic. `declared_unit_cost × quantity = line_value` stays the
screen's own computed display cell — do not reimplement it.

## Ownership is on the HEADER, not the line — leave it there

Consignment is customer-owned material. The owning partner is a **document-header** field, not a
per-line one, which is why this grid converts cleanly. **Do not** add a per-line owner column, and do
not let the conversion introduce a default for any ownership field.

Relatedly, and load-bearing across Production: **`owner_partner_id = 0` is a deliberate sentinel**,
not an empty value — `null` = automatic split, `0` = force "own", `>0` = a specific customer. If any
part of this screen touches that field, a numeric input that emits `0` for blank would force every
line to "own" and leak customer material. Verify the field's emitted value for an empty control.

## docKey

**`production.consignment`** — registered by WP4. If a registry field key does not match the real
control name, fix the registry and say so in your report.

## Acceptance criteria

1. Add / edit / delete a receipt line works exactly as before, including validation.
2. The product cell is still the shared product search (it already is — don't regress it).
3. The computed line value still updates live as quantity or declared cost changes.
4. Header drag reorders, edge drag resizes, both persist and survive reload; hiding non-locked
   columns works; `product_id` and `quantity` stay locked.
5. Saving an unchanged receipt produces a payload identical to before this WP — including that no
   ownership field acquired a value it did not have. Say how you verified it.
6. `npx ng build --base-href /app/` green; `npx tsc --noEmit` no new errors.

## Hard rule

Do **not** modify `TransactionLineItemsComponent`, `transaction-line.types.ts`, or `TxColumnLayout`
— 14 live screens depend on them. If you believe this grid cannot get column control without such a
change, STOP and report rather than making it.

## Environment / rules

- ⛔ **NEVER** `git checkout` / `restore` / `stash` on `src/assets/i18n/ar.json` or `en.json`.
  Additive edits only; a new key goes in BOTH files.
- **Do NOT deploy to `/app`** — the orchestrator deploys.
- `chown moonui2:moonui2` every edited file. Commit on `hazemdev2`, conventional. **No push, no merge.**
- moonui2 ONLY — never `/home/moonui`. Never print a git remote URL.

## Out of scope

Other Production screens · the consignment backend contract · modifying
`TransactionLineItemsComponent` itself.
