# WP2 — Column reorder (drag) + resize on stock-issue + stock-receipt grids

## Goal
Add drag-to-reorder (CDK DragDrop on `<th>`) and drag-to-resize (pointer handle on `<th>`) to both hand-written grids, persisting via the existing `docConfig.lineColumnOrder` / `lineColumnWidth` (company-wide `core.document_settings`), gated by `core.settings`. Row rendering becomes column-order-driven so a reordered header moves the whole column (header + all its cells) — including the bespoke cells. Display-only.

## Depends on
WP1 (columns registered + visibility-driven). WP1 must be ✅ first.

## Exact files (FE)
1. NEW (recommended): `src/app/shared/directives/tx-column-layout.directive.ts` (or a small standalone helper) — extract the reusable mechanism from `transaction-line-items.component.ts`:
   - CDK `DragDrop` header reorder → `docConfig.setLineColumnOrder(docKey, keys)` (service :290).
   - Pointer-events resize handle → `docConfig.setLineColumnWidth(docKey, colKey, '<n>px')` (:321). MUST be RTL-aware (mirror the sign logic in transaction-line-items `onResizeStart` ~:389-468).
   - `widthFor(colKey)` reading `lineColumnWidth` (:304) else a default.
   - `orderedColumns(docKey)` reading `lineColumnOrder` (:282) to sort the registered line fields; locked/structural columns (# row-index, actions) pinned appropriately (row-# first, actions last), matching transaction-line-items `cols` computed (~:306-332).
   - Reorder/resize affordances only active when `permissions.hasPermission('core.settings')` (mirror `canReorder` ~:288).
2. `src/app/features/stock-issues/stock-issues.component.html` + `.ts` — convert the `<thead>`/`<tbody>` row from a FIXED `<th>`/`<td>` sequence to a loop over `orderedColumns('inventory.issue')`. Each column key maps to its cell renderer. Because the cells are bespoke (product-search, on-hand badge, consignor picker, serial/lot chips, batch, actions), use an `@switch (col.key)` in BOTH the `<th>` loop and the `<td>` loop so every existing cell markup is preserved verbatim — only its POSITION becomes dynamic. Apply `[style.width]` from `widthFor(col.key)` and the drag/resize handles on each `<th>`.
3. `src/app/features/stock-receipts/stock-receipts.component.html` + `.ts` — same conversion for `inventory.receipt`.

## DocConfigService API (already exists)
- `lineColumnOrder(docKey): string[]` (:282) / `setLineColumnOrder(docKey, keys)` (:290)
- `lineColumnWidth(docKey, key): string|null` (:304) / `setLineColumnWidth(docKey, key, w)` (:321)
- Persist path: same `core.document_settings` blob → `PUT /core/settings` (:330). Company-wide.

## Reference (copy the mechanics)
`transaction-line-items.component.ts`: `onColumnDrop` (~:352), `onResizeStart` (~:389-468, RTL-aware pointer events), `widthFor` (~:486-539), `cols` computed with order (~:306-332), `canReorder` computed (~:288). Template header: `<tr cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="onColumnDrop($event)">`, each `<th cdkDrag [style.width]="widthFor(col)">` with `.tx-drag-handle` (pi-grip-vertical) + `.tx-resize-handle` (pointerdown). Imports `DragDropModule` from `@angular/cdk/drag-drop`.

## Acceptance criteria
- [ ] Dragging a column header reorders the whole column (header + every row's cell, incl. bespoke cells) on both grids; order persists after reopen (company-wide).
- [ ] Dragging the resize handle changes the column width; width persists after reopen. RTL: resize direction correct from the right.
- [ ] Locked columns stay visible; row-# stays first, actions stay last regardless of order.
- [ ] Reorder/resize affordances only for `core.settings` users; others see the persisted layout, no handles.
- [ ] Consignor still conditional (`lineShowsConsignor`), badge/serial/lot/barcode all still work after reorder; per-row stock badge (R3) + serial/lot index maps unaffected.
- [ ] `ng build` green. No save/approval/posting change.

## Tests
- No FE runner. Gate = `ng build` green + opus review + manual acceptance on /app.

## Flags
- NOT [FIN]. No migration.

## Out of scope
- Any save/approval/posting logic. Read-only detail tables. Migrating the grids to TransactionLineItemsComponent wholesale (we reuse its mechanism via a directive, we do NOT replace the bespoke grids).
