# `Sp_WorkOrder_BillForceComplete` (procedure)


- **Type:** PROCEDURE
- **Deterministic:** NO
- **SQL data access:** CONTAINS SQL

## Parameters

| # | Mode | Name | Type |
|---|---|---|---|
| 1 | IN | `sProInParam` | `varchar(10000)` |
| 2 | IN | `sMakePerson` | `varchar(100)` |
| 3 | IN | `sBrId` | `varchar(100)` |
| 4 | IN | `sSuId` | `varchar(100)` |
| 5 | OUT | `sReturn` | `varchar(1000)` |
| 6 | OUT | `sCode` | `int` |

## Body

_Body is not pre-cached. To inspect: `mysql --defaults-file=~/.my.cnf -e 'SHOW CREATE PROCEDURE `Sp_WorkOrder_BillForceComplete`'`._

## Narrative

**Business context:** 生产管理 / 生产工单 — toolbar action 强制完结 (force-complete) for whole 生产工单 masters. The operator selects one or more `mftworkordermaster` rows in the 生产工单 grid, opens a popup that requires a 完结说明 reason, and the action flips the bills to `bBillComplete=1` with full audit logging — used when the work-order can't be finished through normal reporting (defects, cancellations, residual qty).

**What it does:** Parses `sProInParam` (the JSON `{params:[{value:[{sId},…]}…], changeValue:{textareaValue}}` shape produced by GenericProcedureCall). Refuses empty payload (`paramsErro` constant) and missing reason (`sWorkOrderFinishNeedSm` constant). For each `sId`, sets `mftworkordermaster.bBillComplete=1`, `tBillCompleteDate=NOW()`, `sCompletePerson`, `sComRecordPerson`, `sReasonMemo`; cascades to `mftworkorderslave.sLossMemo`; flips `mftproductionplan.sState='6'` and `mftproductionplanslave.sState='5'`/`bProductionPlanComplete=1`; finally `INSERT INTO syscomplete` an audit row tagged `sForceComplete` quoting the reason.

**Invocation:** Dispatched dynamically by `GenericProcedureCallServiceImpl.doGenericProcedureCall()` (POST `/procedureCall/doGenericProcedureCall`) — 生产工单 grid's 强制完结 toolbar button names this proc. Per-row variant: `Sp_WorkOrder_BillForceCompleteSlave`. Install script: `script/标版/30100101/Sp_WorkOrder_BillForceComplete.sql`.
