# `Sp_Yfworkorder_BtnEventCustomerFail` (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_Yfworkorder_BtnEventCustomerFail`'`._

## Narrative

**Business context:** 研发 → 研发工单 (`mftworkorderslave` 研发 variant) — toolbar handler that marks slave rows as "客户驳回 / 客户未通过" (per the comment 研发工单客户通过 — the caption is the inverse-naming convention used across the 研发 流程). Records the customer-rejection reason on the slave row so the 研发 follow-up flow can branch.

**What it does:** Validates `sProInParam` (length ≥5, otherwise `Sp_Sis_GetConst('paramsErro',...)` and `sCode=-1`). Parses `$.params` array and the form's `$.changeValue` for `sCustomerFailType` and `textareaValue` → `sCustomerFailMemo`. Nested WHILE loop over `$.params[i].value[j].sSlaveId`. For each id, runs `UPDATE mftworkorderslave SET bCustomerStatusEnd=1, sCustomerFailType=p_sCustomerFailType, sCustomerFailMemo=p_sCustomerFailMemo WHERE sId=p_sId AND sBrandsId=sBrId AND sSubsidiaryId=sSuId`.

**Invocation:** Dispatched dynamically by `GenericProcedureCallServiceImpl.doGenericProcedureCall()` (POST `/procedureCall/doGenericProcedureCall`) — fired from the 研发工单 grid's 客户未通过 / 客户驳回 toolbar button (standard `Sp_<Module>_BtnEvent*` channel). Not bound on `gdsmodule` or `gdsconfigformmaster`; no other DB-routine callers, no xly-src references — discoverable only via the generic-dispatch contract.
