# WP1 — Completion guard for un-issued materials

## Goal
When a user completes a production order that still has materials with `remaining_quantity > 0` (planned > consumed), the system must require **explicit confirmation** instead of silently completing. Under-issue is legitimate (you don't always consume 100%), so this is a confirm-gate, NOT a hard block. This prevents the ISS-9105 root cause (order PRD-2026-00022 was completed with a material at 5/12.36 issued, then the issue button vanished).

## Exact files
- BE: `/home/moonui2/moon-erp-be/Modules/Production/app/Http/Controllers/ProductionOrderController.php` — `complete()` method (~:314-329). Currently only checks `$order->canComplete()` then sets status=Completed.
- BE: `/home/moonui2/moon-erp-be/Modules/Production/app/Models/ProductionOrderMaterial.php` — `remainingQuantity()` (:64 = max(0, planned − consumed)).
- BE i18n: `/home/moonui2/moon-erp-be/Modules/Production/lang/{en,ar}/production.php` (add message key e.g. `materials_not_fully_issued`).
- FE: `/home/moonui2/public_html/moon-erp/src/app/features/production/orders/production-orders.component.ts` + `.html` — the `complete()` call site (find where it POSTs complete). Add a PrimeNG `confirmDialog`/confirm when the order has materials with remaining>0, sending the confirm flag.
- FE service: the production order service method for complete (search `complete` in `src/app/features/production/**/*.service.ts` or the component).
- FE i18n: `src/assets/i18n/{en,ar}.json` under `PRODUCTION.ORDERS.*`.

## Behaviour / interface
- `complete()` accepts an optional body flag `allow_under_issue` (bool, default false).
- If the order has ≥1 material with `remaining_quantity > 0` AND `allow_under_issue !== true` → return **HTTP 422** with a clear message listing that materials are not fully issued (message key). Do NOT complete.
- If `allow_under_issue === true` (or no material has remaining) → complete as today.
- Keep the existing `canComplete()` state check first (still required).
- FE: before calling complete, if any order material has `remaining_quantity > 0`, show a confirm dialog ("فيه خامات لسه ما اتصرفتش بالكامل — تكمّل بصرف ناقص؟ / Materials are not fully issued — complete with under-issue?"). On confirm → call complete with `allow_under_issue: true`. If none remaining → call directly.

## Acceptance criteria
- BE: completing an order that has a material with remaining>0 WITHOUT the flag → 422 + message; WITH `allow_under_issue:true` → 200 + status becomes completed.
- BE: completing an order whose materials are all fully issued → 200 (no flag needed), unchanged behaviour.
- FE: build green; the confirm dialog appears only when something is under-issued; on confirm it completes.
- No change to any other status transition.

## Tests
- Extend a Production feature test (new file `ProductionCompletionGuardTest.php` or add to `ProductionConfirmationsTest.php`): (a) complete with remaining>0 and no flag → assertStatus(422); (b) same with `allow_under_issue:true` → order completed; (c) complete with all materials fully consumed → 200 without flag. Pest/sqlite.
- FE: `ng build` green.

## Flags
- Not [FIN] (no GL). No migration.

## Out of scope
- Do NOT change canIssue/reopen (WP2), issue UX (WP3), or over-issue (WP4). Only the completion confirm-gate.
