# Routine Narratives — Playbook

Long-running job: write a business-context narrative for every procedure
(1,687) and function (177) page in `en/docs/auto-catalog/{procedures,functions}/`,
replacing the auto-generated `_No human-written narrative yet._` placeholder
under each page's `## Narrative` heading.

Goal: a maintainer reading the page learns **what business action this routine
serves**, not just what its parameter list is. The file:line citations live in
`reference/maintainer/`; routine narratives stay business-first.

---

## Narrative shape (≤ ~15 lines per routine)

```
**Business context:** [module path from gdsmodule.sChinese — leaf → root,
" → " separated] — [one sentence: what user action / business outcome
triggers this]

**What it does:** [terse mechanism, 1-3 sentences]

**Invocation:** [how it's reached — form-master sSqlStr, gdsmodule hook,
chained from another proc, JMS CHANGE_GDS_MODULE path, or "no callers
found (candidate dead code)"]

[Caveats / bugs / edge cases — only when worth flagging]
```

Three already-written samples for reference:
- `en/docs/auto-catalog/functions/Fn_find_modleAllId.md`
- `en/docs/auto-catalog/procedures/sp_get_sOppositeColor.md` (orphan example)
- `en/docs/auto-catalog/procedures/PRO_ERPMERGEBASESISWORKCENTER.md` (denorm-merge family)

---

## Lookup recipe (per routine)

```bash
ROUTINE="<name>"

# 1. Body
mysql --defaults-file=~/.my.cnf xlyweberp_saas_ai \
  -e "SHOW CREATE {PROCEDURE|FUNCTION} $ROUTINE"

# 2. Business-module location — form embeds (procs primarily)
mysql --defaults-file=~/.my.cnf xlyweberp_saas_ai -e "
  SELECT gfm.sId AS form_sId, m.sId AS module_sId, m.sChinese, m.sParentId
  FROM gdsconfigformmaster gfm
  LEFT JOIN gdsmodule m ON gfm.sParentId = m.sId
  WHERE gfm.sSqlStr      LIKE '%$ROUTINE%'
     OR gfm.sConfigSqlStr LIKE '%$ROUTINE%'
     OR gfm.sSqlCondition LIKE '%$ROUTINE%'"

# 3. Business-module location — module hooks (procs only)
mysql --defaults-file=~/.my.cnf xlyweberp_saas_ai -e "
  SELECT sId, sChinese, sParentId,
         sSaveProName, sSaveProNameBefore, sDeleteProName, sProcName
  FROM gdsmodule
  WHERE sSaveProName       = '$ROUTINE'
     OR sSaveProNameBefore = '$ROUTINE'
     OR sDeleteProName     = '$ROUTINE'
     OR sProcName          = '$ROUTINE'"

# 4. Climb the module tree for any sId found in #2 or #3 (replace MID)
mysql --defaults-file=~/.my.cnf xlyweberp_saas_ai -e "
  SELECT 1 d, sId, sChinese, sParentId FROM gdsmodule WHERE sId='MID'
  UNION SELECT 2, sId, sChinese, sParentId FROM gdsmodule
        WHERE sId=(SELECT sParentId FROM gdsmodule WHERE sId='MID')
  UNION SELECT 3, m3.sId, m3.sChinese, m3.sParentId
        FROM gdsmodule m3
        JOIN gdsmodule m2 ON m3.sId = m2.sParentId
        JOIN gdsmodule m1 ON m2.sId = m1.sParentId
        WHERE m1.sId = 'MID'
  ORDER BY d"

# 5. Other-routine callers (procs that CALL it, funcs that reference it)
mysql --defaults-file=~/.my.cnf xlyweberp_saas_ai -sNe "
  SELECT ROUTINE_TYPE, ROUTINE_NAME
  FROM information_schema.ROUTINES
  WHERE ROUTINE_SCHEMA = 'xlyweberp_saas_ai'
    AND ROUTINE_NAME != '$ROUTINE'
    AND ROUTINE_DEFINITION LIKE '%$ROUTINE%'"

# 6. Java / MyBatis XML / SQL-template refs
grep -rln "$ROUTINE" /Users/reporkey/Desktop/revs_engi_wiki/xly-src \
  --include="*.java" --include="*.xml" --include="*.sql" 2>/dev/null
```

**Orphan rule:** if #2 + #3 + #5 + #6 are all empty, the routine has no
discoverable caller. Flag in the narrative as `Status: appears orphaned. No
caller found in any channel — candidate for maintainer audit.`

**`sSaveProName`/`sSaveProNameBefore`/`sDeleteProName`/`sProcName` live on
`gdsmodule`**, not on `gdsconfigformmaster`. The auto-catalog page text and
older wiki drafts sometimes confuse this — trust the queries above.

---

## Style rules

- **Keep Chinese module names in Chinese.** `sChinese` is what the user sees
  in BACK. Don't translate `工作中心`, `选择工序(轮转)`, etc. — translating
  breaks searchability against the live UI.
- **Use the three headings literally:** `**Business context:**`,
  `**What it does:**`, `**Invocation:**`. Consistent shape aids scanning.
- **1–3 sentences per section. ≤15 lines total.** If the body is small and
  self-explanatory, the narrative can be shorter. Don't pad.
- **No file:line citations to xly-src** in routine narratives. Those belong
  in `reference/maintainer/`. Exception: if the routine is uniquely tied to
  a single Java caller, name the class (not the line).
- **Cross-link only when load-bearing.** Relative paths:
  `../../slices/...`, `../../reference/maintainer/...`,
  `../procedures/<other>.md`, `../functions/<other>.md`. Test that the
  target exists before adding the link.
- **Don't translate identifiers** — proc/function/column/table names stay as
  written.
- **Don't editorialize** ("interestingly", "it's worth noting") — state
  directly.
- **Don't claim Java callers without grepping.** The lookup recipe's step 6
  is the ground truth.

---

## Resume protocol — what counts as "done"

A routine is **done** when its `.md` file's `## Narrative` block contains
anything other than `_No human-written narrative yet._`.

To get the live pending count and next batch:

```bash
cd /Users/reporkey/Desktop/revs_engi_wiki/xly-wiki

# Pending count
grep -l "_No human-written narrative yet._" \
  en/docs/auto-catalog/procedures/*.md \
  en/docs/auto-catalog/functions/*.md | wc -l

# Next 20 pending (alphabetical)
grep -l "_No human-written narrative yet._" \
  en/docs/auto-catalog/procedures/*.md \
  en/docs/auto-catalog/functions/*.md | sort | head -20
```

---

## Persistence — `gen_catalog.py` is patched

Both `en/scripts/gen_catalog.py` and `zh/scripts/gen_catalog.py` now
snapshot the `## Narrative` (en) / `## 说明` (zh) block before the
`shutil.rmtree`, and re-inject preserved content during the regen. So
re-running the generator does **not** wipe human prose. Safe to regen
at any time.

zh translation is a follow-up pass after en is complete. For now, write
English narratives only.

---

## Subagent prompt template

When the user says "continue", spawn ONE subagent with this prompt:

```
Read /Users/reporkey/Desktop/revs_engi_wiki/xly-wiki/en/scripts/narrate_routines.md
in full. It contains the goal, narrative shape, lookup recipe, style rules,
and resume protocol for adding business-context narratives to xly's stored
procedures and functions.

Identify the next N pending routines using the resume-protocol command in the
playbook. N = 20 (or fewer if the routines are large/complex — judge from the
ROUTINE_DEFINITION size: large bodies take longer to read; aim for ≤90 minutes
of work).

For each routine, in alphabetical order:

1. Run the Lookup recipe end-to-end. Capture findings.
2. Write the narrative in the shape the playbook specifies — three labelled
   sections, business-first, Chinese module names preserved.
3. Edit the .md file: replace `_No human-written narrative yet._` with the
   narrative prose. Leave the `## Narrative` heading and surrounding blanks
   intact.

Don't dispatch sub-subagents. Don't rebuild the site. Don't run gen_catalog.py.
Don't translate anything to Chinese.

When done with the batch:
- List the routine names processed, one per line.
- Run the resume-protocol command and print the new pending count.
- Note any orphans found (status: "no callers found") so the user can audit.
- Append a row to the Progress log table in narrate_routines.md.
```

---

## Progress log

| Date | Procedures done | Functions done | Pending | Notes |
|---|---:|---:|---:|---|
| 2026-05-11 | 2 | 1 | 1861 | Initial 3 samples + gen_catalog.py preservation patch (en + zh) |
| 2026-05-12 | 37 | 4 | 1815 | Pass 1b — backup/copy/snapshot variants (templated narrative); 31 _copy1, 2 _bak, 1 _history, 4 _old/_Old, 3 date-suffixed |
| 2026-05-12 | 0 | 20 | 1775 | Pass 2 session 2 — `Fun_deleteManyChar` → `FUN_GET_DATE_KT_ADD`. 13 substantive + 7 orphan; production-scheduling time-arithmetic family clustered (FUN_GET_CALC_DATE*, FUN_GET_DATE_BC*, FUN_GET_DATE_DIFF_MINUTE, FUN_GET_CALCPLAN_DATE_END). |
| 2026-05-12 | 0 | 20 | 1755 | Pass 2 session 3 — `FUN_GET_DATE_KT` → `Fun_get_sProductId_process`. 15 substantive + 5 orphan. Two clusters: production-scheduling KT/UKT/YX time-arithmetic continuation (KT/UKT/UKT_ADD substantive, YX orphan); dynamic-report column-config family `Fun_get_show_config*` (12 routines, all substantive except `_ys100` orphan, called by Sp_EquipmentOutput_*/Sp_Manufacture_CapacityStatistics/Sp_MftPlan_MachineProcessLodading/Sp_SalesOrder_Analysis/Sp_CostAccount_*). Orphans: FUN_GET_DATE_YX, fun_get_jurisdiction, Fun_get_show_config_ys100, Fun_get_sProductId, Fun_get_sProductId_process. |
| 2026-05-12 | 0 | 20 | 1735 | Pass 2 session 4 — `FUN_GET_to_pinyin` → `Fun_GetHumpDiff`. 11 substantive + 9 orphan. Clusters: color-count JSON family (Fun_Getcolorcount substantive, _CalcQty1/_CalcQty2 substantive feeding Sp_Manufacture_InsertMftPlanSlave; _new + Test orphan); Ks (开数) packing helper (Fun_GetCalcMaterialsKs substantive, _Ks1 orphan since its branches were commented out); material-qty conversion Fun_GetAuxiliaryQtyUnit (large body, called by ReplaceFieldServiceImpl.getReplaceFieldReslut). Orphans: FUN_GET_to_pinyin, Fun_GetAddBillNo, Fun_GetAddMapJson, Fun_GetBarId, Fun_GetCalcMaterialsKs1, Fun_Getcolorcount_new, Fun_GetcolorcountTest, Fun_getDhouM, Fun_GetFatherProductId. Flags: Fun_GetCh — regex `[u0391-uFFE5]` is broken (literal `u`), filter is effectively no-op (bug suspect). |
| 2026-05-12 | 0 | 20 | 1715 | Pass 2 session 5 — `Fun_getInitColumnByProName` → `Fun_GetLoginUserName`. 12 substantive + 8 orphan. Clusters: JSON list pretty-printers `Fun_GetListByJson_ByKey*` (3 orphans — display helpers with no current call site); JSON `_ByKey` lookup family (ByKey/ByKey2/ByKey6 substantive feeding `Sp_OEE_ProductionReport*`/`Sp_Check_mftProductionReportValue*`/`Sp_WorkOrder_CalcDataPackProductStd`; ByKey1/5/New orphan); `_ByName` family substantive (Sp_GetMachineByApsRule, Sp_Manufacture_ProductionPlanInfoTree_Base_TC); login-info trio (`Fun_GetLoginUser`/`Language`/`Name`) all substantive — embedded in 采购/生产明细 form sSqlStrs and called by workflow `Sp_Apply_Flow_*`/`Sp_*_CheckFlow`/`Sp_Bill_Used`; `Fun_GetLimitDate` substantive (overdue-warning reports — Java callers commented out, proc-only path); `Fun_getInitColumnByProName` substantive (called by `GdsconfigtbMapper.getInitColumnByProName`); `Fun_GetListBy_BysCombineChild` substantive (Sp_reportdata_WorkOrder*). Orphans: Fun_GetJson_Length, Fun_GetknifeProcessQty, Fun_GetknifeReportQty, Fun_GetListByJson_ByKey, Fun_GetListByJson_ByKey_split, Fun_GetListByJson_ByKey_wrap, Fun_GetListJson_ByKey1, Fun_GetListJson_ByKey5, Fun_GetListJson_ByKeyNew. |
| 2026-05-12 | 0 | 20 | 1695 | Pass 2 session 6 — `Fun_GetLoginUserType` → `Fun_GetProcessAuxiliaryQty`. 12 substantive + 8 orphan. Clusters: data-scope filter pair `Fun_GetLookCustomer`/`Fun_GetLookProcess` (substantive — embedded as `IN (...)` clauses in `Sp_financial_*`/`Sp_Manufacture_*`/`Sp_OEE_*`/`Sp_PC_*Inspection`/`Sp_Mobile_PatrolInspection`); machine shift-window trio `Fun_GetMachineWork{Start,End,Work}Date/Type` (Start + WorkType substantive via `Sp_bd_MachinePlanStatus`/`Sp_bd_McPlan{Conter,Rate}`; End orphan); material-qty conversion family `Fun_GetMaterialsQtyUnit` substantive (52 proc callers + Java `CalculationStdServiceImpl.java`/`ReplaceFieldServiceImpl.java`) and `Fun_GetMaterialsQtyUnitSupple` substantive (Sp_*_CalcDataFlex pair, board-thickness variant); `Fun_GetNum` substantive (排产/Auto-order/Sp_Create_sControlFaceNameTable*); JSON helpers `Fun_getOneByKey`+`Fun_getPlanDate` substantive (Sp_Manufacture_ProductionPlanInfoTree_Base*/Trace family — filter-JSON compilers); `Fun_GetPackQty` substantive (form sId `16054917...0000` in OEE管理 → 打印成品标签(OEE)); `fun_getNextMonth_lasterWeekday` substantive (Sp_Calc_sEmt only); `Fun_GetProcessAuxiliaryQty` substantive (Sp_Check_sOis/Opc/Opkg/Opn/Opn1). Orphans: Fun_GetLoginUserType (sibling of GetLookCustomer/Process pair but never called), Fun_GetMachineLenWidth (superseded by APS-suffixed variant), Fun_GetMachineWorkEndDate, Fun_getMoneyFormart (catalog header is mis-copied from a JSON helper), Fun_GetNumFirst, Fun_getPartNameStatus, fun_GetPreProcessQty (hardcodes one process `sId` literal). Flag: Fun_GetMachineWorkWorkType returns a varchar literal but declares `datetime` — type mismatch worth noting. |
| 2026-05-12 | 0 | 20 | 1675 | Pass 2 session 7 — `Fun_getProcessByControlName` → `Fun_iCalcListJson`. 7 substantive + 13 orphan. Clusters: work-order process-chart pair `Fun_getProcessByControlName`/`Fun_getProcessByWorkOrderId` (both orphan — wrapper + delegate, never called); customer-specific report-id dispatch quartet `fun_getreportId_by{ArrMaterialsType,MaterialsType,cus}` + `fun_gettzreportId_bycus` + `Fun_GetReportId_byLogType` (all 5 orphans — tenant-baked GUID dispatch tables with no live caller); `Fun_GetSystemSetting` substantive (canonical `SysSystemSettings` key-value reader — 37 routine callers including the auxiliary/materials qty-unit family + `Sp_Calc_s*` + `Sp_BillOf*`); `Fun_GetReelAuxiliaryQtyUnit` orphan-via-dead-chain (only caller `Sp_saveReturn_sPmd` is itself orphan); `Fun_GetTrunkQty` substantive (OEE 打印成品标签 form sId `16054917...4000`); `fun_getWorkProcess_NextId`/`NextIdnew`/`NextQty` substantive (`Sp_WorkOrder_CalcDataPack*Std*`/`Sp_Calc_sWod`); `fun_getWorkProcess_Next_WareHouseNo` orphan; `Fun_HasJsonKey` substantive (`Sp_Manufacture_ProductionPlanInfoTree_Base*`/`sp_manufacture_productionplaninfotrace*`); `Fun_iCalcListJson` substantive (`Sp_WorkOrder_CalcDataBsProductStd`/`Sp_WorkOrder_CalcDataPackProductStd` + customer overlays); test-counter pair `Fun_GetTestCount`/`Fun_GetTestMaterialsCount` orphan (sample-order/打样 KPIs with no live caller); `Fun_getProductMaxStyle` orphan-from-in-scope-view (only caller `Sp_Ai_AddQuoQuoAfter` is `ai_*` subsystem, out of scope; also hard-codes tenant-specific `eleprocess.sId` literals); `Fun_GetproductstockQty` orphan. Flags: `Fun_GetTestCount`/`Fun_GetTestMaterialsCount` catalog headers mis-copied from `Fun_GetNum` (`获取字符串中数字`); the 4 `getreportId*` + `gettzreportId*` orphans embed tenant-specific customer + report GUIDs (will silently miss-route if cloned to a different deployment); `Fun_getProductMaxStyle` and `Fun_GetTrunkQty` hard-code product/process sIds + paper-size constants. |
| 2026-05-12 | 0 | 20 | 1655 | Pass 2 session 8 — `FUN_JSON_CHAR` → `GetMaterialsAuxiliaryQty`. 5 substantive + 15 orphan. Clusters: tiny JSON accessors `FUN_JSON_CHAR`/`FUN_JSON_INT` orphan-via-dead-chain (only callers `sp_btn_action` + `sp_btn_action_updatequoquotationslave` are themselves orphans); production-scheduling Gantt JSON sanitizers `Fun_RemoveJsonEmptyKey`/`Fun_RemoveJsonKey` substantive (`sp_manufacture_productionplaninfotrace`/`*1`/`Sp_Manufacture_ProductionPlanInfoTree_Base*`); canonical i18n constant-resolver pair `Fun_Sis_GetConst` (220 routine callers — entire `Sp_Check_s*`/`Sp_BtnEvent*`/`Sp_Calc_s*` chain) + `Fun_Sis_GetConstNew` (132 callers — per-user-language variant reading `sftlogininfo.sLanguage`); work-order downstream-usage check trio `fun_workmaterials_used`/`fun_workprocess_used`/`fun_workproduct_used` all orphan-via-dead-chain via `Sp_WorkOrder_CheckUpdateNew` (which is itself orphan); orphan one-offs: `Fun_JsonExistsColor_ByName`, `FUN_MATERIALS_SMAIL` (305cm sheet-packing estimator), `Fun_MoneyToCh` (25K-char 大写金额 converter), `Fun_Subsequent_process` (quotation 后道工序 JSON tree), `Fun_System_ReplaceField_JSON`, `Fun_up_workOrderProcessId` (caller `fun_GetPreProcessQty` is orphan), `get_config_data`/`get_config_data_JSON` (dropdown localizers — overlap with `Fun_Sis_GetConstNew`), `GetChineseChar` (broken regex — same `[u0391-uFFE5]` literal bug as `Fun_GetCh`), `GetDispatchUnit` (orphan-via-dead-chain through `Sp_Manufacture_ProductionProcess`), `GetMaterialsAuxiliaryQty` (capitalized predecessor of the live `Fun_GetMaterialsQtyUnit` family). Flags: `GetChineseChar` regex `[u0391-uFFE5]` is literal — same bug as `Fun_GetCh` (session 4); `fun_workmaterials_used` second IF tests `p_sUsed` instead of `p_sUsed2`, so the 生产领料 branch never returns; `get_config_data_JSON` hardcodes `iIncrement = 1509089` and ignores its `sConfigSlaveId` parameter (debug scaffolding); `GetDispatchUnit` and `GetMaterialsAuxiliaryQty` hardcode tenant-specific GUIDs; `fun_workprocess_used` and `Fun_MoneyToCh` headers mis-spelled / generic. |
| 2026-05-12 | 7 | 13 | 1635 | Pass 2 session 9 — `GetMaterialsPrice` → `to_pinyin` (mixed 7 procs + 13 funcs alphabetically — `11`, `addFieldScript`, `callAllId`/`callAllIdbVisible`/`callAllIdChid`/`callAllIdChidVisible`, `call_SP_Inventory_ProductCalcQty`, `待产量上报`, then `GetMaterialsPrice`/`GetNextMachine`/`GetPriorPlate`/`GetPriorProcess`/`GetPriorProcessPlan`/`IsNumeric`/`JSON_MERGE_REPLACE`/`newId`/`NewId2`/`Sp_Sis_GetMertialsInventoryFormGuid` (func variant)/`Stuff`/`to_pinyin`). 9 substantive + 11 orphan. Clusters: APS gantt prior/next family (`GetNextMachine` 7 callers in `Sp_Manufacture_*Report` + `Sp_OEE_*`; `GetPriorPlate`/`GetPriorProcessPlan` substantive — `Sp_Manufacture_GetAPSState`; `GetPriorProcess` substantive — 7 manufacture/OEE callers); module-tree maintenance family (`callAllId` substantive — Java `GdsmoduleServiceImpl.updateGdsmodule()` + `LicenseServiceImpl.updateAllId()`; `callAllIdbVisible`/`callAllIdChid`/`callAllIdChidVisible` orphan); id-generators (`newId` substantive — 137 routine callers + 4 forms + Java; `NewId2` orphan); materials-cost helpers (`GetMaterialsPrice` substantive — 17 Calc routines + 2 forms; `Sp_Sis_GetMertialsInventoryFormGuid` substantive — 20+ inventory routines); SQL-Server polyfills (`IsNumeric` substantive — 30+ Bill/Calc/Manufacture routines; `Stuff` substantive — `Sp_System_ReplaceField*` family); `addFieldScript` substantive (DBA upgrade helper, lives in 20211104 upgrade bundle); `JSON_MERGE_REPLACE` substantive (`Fun_get_show_config_basic`). Orphans: `11` (developer scratch — header mis-copied as 现金日记帐 but body is product-class sales summary), `callAllIdbVisible`/`callAllIdChid`/`callAllIdChidVisible` (sibling family unused — `callAllId` is the live one), `call_SP_Inventory_ProductCalcQty` (one-shot DBA rebuild), `待产量上报` (Chinese-named clone of `Sp_Manufacture_ProductionReport`), `NewId2`, `to_pinyin` (Java-side has the live pinyin path). Flags: `IsNumeric` regex `'-?[1-9]d*$'` and `'-?[0-9]+(.[0-9]{1,3})?$'` are subtly wrong (unescaped `d` and `.`); `GetPriorProcess` references session vars `@uGuid`/`@sCurProcessName` instead of proc-local — copy-paste bug; `newId`/`NewId2` catalog headers claim 27 digits but body produces 32; `JSON_MERGE_REPLACE` catalog header is truncated/garbled (claims keys-from-1-win, body does the opposite); `Stuff` uses `LOCATE` to compute the right-slice — bug when the deleted substring also appears earlier in `str`; `Sp_Sis_GetMertialsInventoryFormGuid` has both a FUNCTION and PROCEDURE with the same name + `Sp_` prefix on a function. |
| 2026-05-12 | 20 | 0 | 1615 | Pass 2 session 10 — `del_quoworklog` → `PRO_ERPMERGEBASEELEPRODUCT` (all 20 procedures). 14 substantive + 6 orphan. Clusters: gdsmodule/permission tree builders `getModuleTreePro`+`getModuleChildrenPro`+`getModuleKeyPro`+`getSysjurisdictionTreePro`+`getSysjurisdictionChildrenPro` (all substantive — MyBatis CALLABLE mappers `GdsmoduleMapper`/`SysjurisdictionMapper`, Java `MenuServiceImpl`/`SysjurisdictionServiceImpl`/`GdsmoduleServiceImpl`, controller endpoints `getModuleTreePro`/`getModuleKeyPro`/`getSysjurisdictionTreePro`; `@Cacheable` + cache-evict on module mutation); ERPMERGEBASE denorm-merge family continuation (`ELECUSTOMER`/`ELEEMPLOYEE`/`ELEMACHINE`/`ELEMATERIALS`/`ELEPROCESS`/`ELEPRODUCT` all substantive — `ProDao.proErpMergeBase<Entity>(map)` + MyBatis `ProMapper.xml`, JMS CHANGE_GDS_MODULE consumer); standalone substantives: `del_quoworklog` (MySQL EVENT daily 04:00 — truncates 17 `_tmp` tables), `Fun_Gb2Big_ChineseToBig` proc (繁體中文 Big5 label cache rebuild, paginated cursor over `gdsconfigformslave`), `planScriptTmp` (called from `Sp_Manufacture_GetAPSState` but body is fully commented out — inert denormalizer for `MftProductionPlanSlave`). Orphans: `deleteBill` (DBA customer-purge script `Sp_Del_Bill_ByCustomerName.sql` defines+drops it; persistence is install artifact), `deleteMesg` (审批消息 cleanup helper, not wired), `Empty` (Workbench wizard skeleton — no statements), `Fun_Get_Change_WorkOrderStatus` ("Fun_" but is a PROCEDURE; 14K body computes work-order `bBillComplete` but unreferenced), `init_plc_config` (DBA PLC-import seeding tool, hardcodes 12-machine loop + `sBrandsId='1111111111'`), `phoneDeal` (cursor template that only echoes `sId`). Flags: `PRO_ERPMERGEBASEELECUSTOMER` swaps `sCustomerName = @sCustomerNo` and `sCustomerNo = @sCustomerName` in three `UPDATE` SET clauses (bug — labels written to wrong columns); `getSysjurisdictionTreePro` hardcodes a single-row exclusion `m.sId <> '11811781131121915101184660940'` (tenant-specific); `planScriptTmp` is structurally alive but inert (every body statement commented out) — flag during APS audit; `Fun_Get_Change_WorkOrderStatus` declares `result bit(1)` and ends with commented-out `# return result` — was originally a FUNCTION, never re-wired; `Fun_Gb2Big_ChineseToBig` has BOTH a FUNCTION and PROCEDURE with the same name (function does the unpaginated all-tables version; procedure does only `gdsconfigformslave` paginated). |
| 2026-05-12 | 20 | 0 | 1595 | Pass 2 session 11 — `PRO_ERPMERGEBASEELETEAM` → `Sp_Add_Flow` (all 20 procedures). 16 substantive + 4 orphan. Clusters: PRO_ERPMERGEBASE* denorm-merge family completion — `ELETEAM`/`GDSMODULE`/`MFTWORKORDERCONTROL`/`SISCUSTOMERCLASSIFY`/`SISDELIVER`/`SISFORMULA`/`SISPAYMENT`/`SISPROCESSCLASSIFY`/`SISPRODUCTCLASSIFY`/`SISSALESMAN`/`SISTAX` (all 11 substantive — `ProDao.proErpMergeBase<Entity>(map)` + MyBatis `ProMapper.xml`, driven by per-entity `Change*ServiceImpl` JMS consumers); PRO_ERPMERGE big-row builders `PRO_ERPMERGEMFTWORKORDER`/`PRO_ERPMERGEPRODUCTIONREPORT`/`PRO_ERPMERGESALSALESORDER` (substantive — denormalized-row rebuilders driven by `MegerWorkOrderServiceImpl`/`MegerProductionReportServiceImpl`/`MegerSaleOrderServiceImpl`); retention companion `PRO_ERPMERGEDELHISTORY` (substantive — Spring `@Scheduled(cron = "0 10 3 * * ?")` daily 03:10 via `MergeTableDelHistoryThread` → `MegerDataFactoryServiceImpl.delMergeTableHistoryData`); `Sp_Add_Flow` (substantive — workflow-engine entry point; `CheckExamineFlowDataServiceImpl.doSendCheckFolwData` → `doProByNameFlow(..., "Sp_Add_Flow", ...)`; inserts `biz_flow` row carrying 47+ specialised `Sp_Apply_Flow_*` calc-procs). Orphans: `PRO_MATERIALS_SMAIL` (305cm sheet-packing estimator — procedure version of the orphan FUN_MATERIALS_SMAIL from session 8), `sendPlcData` (one-liner returning newId() — 自定义按钮 template scaffold), `sp_add_elecustomer_to118` + `sp_add_elecustomer_to118_after` (培训 / training-demo template pair for the 第三方接口 push-out feature, paired but never wired to a real button). Flags: `PRO_ERPMERGEMFTWORKORDER`/`PRO_ERPMERGEPRODUCTIONREPORT`/`PRO_ERPMERGESALSALESORDER` all have `DELETE FROM <table> WHERE sSlaveId = sSlaveId` — IN parameter shadows the column name, so MySQL binds both sides to the parameter making the predicate a tautology that wipes the whole table on every invocation before the single-row INSERT (real bug worth maintainer audit); `Sp_Add_Flow` has a stray `SELECT ddd FROM bbbb;` near the top of `top:BEGIN` block, neither table exists — would throw at runtime when `addFlowPro` is true (`CheckExamineFlowDataServiceImpl` has a Java-side `insertbizFlow` fallback for `addFlowPro = false` path); `PRO_ERPMERGEBASESISTAX` pushes the new tax rate retroactively onto historical work-order/sales-order rows. |
| 2026-05-12 | 20 | 0 | 1575 | Pass 2 session 12 — `Sp_addBtn_gdsmodle` → `Sp_afterSave_sMad` (all 20 procedures). 0 substantive + 20 orphan. Clusters: the entire `Sp_afterSave_s<Code>` thin-wrapper family (`sAcc`/`sCio`/`sCldApply`/`sCmt`/`sDgd`/`sDgda`/`sDgda_phone`/`sDgn`/`sGYKK`/`sLok`/`sLos`/`sMad` — 12 routines, all orphan) — each is a 1-line delegator to `Sp_saveReturn_s<Code>` with `iFlag=2`, dispatched (historically) via `gdsmodule.sSaveProName`, but in production every `sSaveProName` slot now holds the corresponding `Sp_Check_s<Code>` name instead. Two outliers: `Sp_afterSave_sDgda` inlines the reverse-write logic with raw PREPARE/EXECUTE dynamic SQL against `saldelivernotifyslave` / `saldelivergoodsslave` / `mitmaterialsstorebarcode`; `Sp_afterSave_sDgda_phone` is a one-shot INSERT-aggregator that BUILDS `saldelivergoodsslave` rows from `mitmaterialsstorebarcode` scans grouped by product/location. Post-审核 cousin family `Sp_AfterPost_s<Code>` — `sAcc`/`sQtt`/`sSod` all orphan: `sAcc` updates `mftqualityaccidentMaster.bFile`; `sQtt` has the richest body (CheckFlow + bCheck/sStatus + propagation to `salsaleschanceproduct`/`eleproductcustomer.dQuotationPrice` + bFailure rebuild) but no dispatch slot exists in `gdsmodule`; `sSod` is an empty stub for the 名片单页/B2C auto-approval flow. Standalone orphans: `Sp_addBtn_gdsmodle` (one-shot DBA helper retrofitting the 10 standard toolbar buttons onto every Business module's primary form), `sp_addCustomer` (第三方接口 training-demo proc taking the canonical `sBody`/`sParam` signature), `Sp_addSysbrands` (tenant provisioning — clones seed-tenant `'1111111111'` metadata into a new `sysbrands` row), `Sp_AdjustMoney_BtnRepair` + `Sp_AdjustMoneyCl_BtnRepair` (报销申请 batch-edit button procs for general + 差旅 reimbursement, follow the `sButtonParam.sql` template but no button row references them). Flags: `Sp_addBtn_gdsmodle` 审核 BtnExamine block guards its `NOT EXISTS` check against `'BtnBsOperation.BtnInvalid'` (copy-paste bug, should be `'BtnExamine'`); `Sp_AdjustMoney_BtnRepair` + `Sp_AdjustMoneyCl_BtnRepair` set `sCode=-1` on empty `sAdjustMemo` but never `LEAVE top` so the update still runs; `Sp_AfterPost_sQtt` second cursor inside `iFlag=1` bounds its loop using `viw_mftworkorderprocess` count (wrong table — should be the quotation join used by the cursor); `Sp_AfterPost_sQtt` hardcodes `M.sFormId = '101251240115016036175782700'` (tenant-specific form GUID); `Sp_addSysbrands` catalog header (`根据模块sId删除模块（包含子模块）`) is mis-copied from a different routine; `Sp_addSysbrands` clones `gdsconfigformslave` reusing the seed-tenant `sId` values rather than generating new ones (risk of cross-tenant collision); `Sp_afterSave_sDgd` declares unused `sDeliverSrc`; `Sp_afterSave_sLos` carries a debug `-- select aa from bb;` comment; `Sp_afterSave_sGYKK` is the only family member that propagates `@sCode`/`@sReturn` back to its own OUT params. |
| 2026-05-12 | 20 | 0 | 1535 | Pass 2 session 14 — `Sp_afterSave_sPkg` → `Sp_afterSave_sSmi` (all 20 procedures, continuing the `Sp_afterSave_s<Code>` family). 16 substantive + 4 dormant. Key correction vs session 12's "all orphan" finding: when the corresponding `Sp_Check_s<Code>` sibling has a live `gdsmodule.sSaveProName` binding, it DOES call `Sp_afterSave_s<Code>` near the tail of a successful save — so the family is reachable through the Check-sibling path even when the gdsmodule slot doesn't point directly at the afterSave name. Live via Sp_Check sibling binding: `sPkg` (采购对账), `sPmd` (生产领料/补料/来料入库, 3 modules), `sPmt` (付款单), `sPod` (采购订单), `sPst` (成品入库), `sPtr` (成品领用单据), `sQtt` (报价单), `sRct` (收款单), `sRgd` (2/4 新增销售退货), `sSck` (销售对账单据), `sSiv` (销售发票单据). Live via `Sp_Invalid_backwriting` dispatch only (Sp_Check sibling is itself unbound): `sPpa` (采购申请), `sRcts` (收款汇总), `sScr` (派车单), `sSfu` (商机跟进), `sSmi` (半成品入库申请). Dormant (Sp_Check sibling unbound + no dispatch entry, OR dispatch entry commented): `sPpr` (产量上报 — both call sites commented), `sPrj` (2/4 采购退货 — form uses Sp_Calc_sPrj), `sScd` (长期合同), `sSdp` (开发计划/印前任务计划/项目立项). Outlier substantive: `Sp_afterSave_sPkg` carries real body — distributes master-grouped `purpurchasecheckingslave` totals down to `purpurchasecheckingdetail` rows via nested cursor; `Sp_afterSave_sPpr` carries 超报校验 + report-hour recalculation but is dormant. Flags: `Sp_afterSave_sPpr` uses `sGuId` (capital `I`) variable inconsistently (MySQL case-insensitive saves it); `Sp_afterSave_sPmt` and `Sp_afterSave_sSmi` catalog headers say "保存前" but routines are after-save (iFlag=2); `Sp_afterSave_sPtr` catalog header says 报废 (legacy) but current form is 成品领用单据; `Sp_afterSave_sRcts` Sp_Invalid_backwriting dispatch points at sFormGuid `101251240115017022732698090` which doesn't exist in current `gdsconfigformmaster` or `gdsmodule` — stale or tenant-specific. |
| 2026-05-12 | 20 | 0 | 1515 | Pass 2 session 15 — `Sp_afterSave_sSmia` → `Sp_Apply_Flow_CPReject` (all 20 procedures). 11 substantive + 9 dormant/orphan. Sp_afterSave family continuation: `sSmia` (半成品入库申请, form `101801153119616759337165930`), `sSmo` (半成品出库, form `101801153119616759303641850`), `sSmoa` (半成品出库申请, form `101801153119616759337728990`) — all three reach via `Sp_Invalid_backwriting` dispatch AND via their `Sp_Check_s<Code>` sibling that calls them internally, but the Sp_Check siblings are themselves unbound in this DB (so the Invalid_backwriting path is the live one); `sSod` substantive (1/3 新增销售订单 + 1/3 新增轮转销售订单, `Sp_Check_sSod` + `sDeleteProName` slot + Invalid_backwriting); `sWod` substantive (生产工单 + 2/3 新增生产补单 + 轮转工单, both `Sp_Check_sWod` + `sDeleteProName` slot + Invalid_backwriting; catalog header says "保存前" but is after-save iFlag=2). Dormant: `sStl` (财务调整单据 — `Sp_Calc_sStl` bound but `Sp_Check_sStl` doesn't call afterSave + no Invalid dispatch), `sWXKK` (外协入库扣款 — has real body with negative-price guard but no callers anywhere), `tice` (设备维修通知, eptmachinefixednotice), `tore` (设备维修入库, eptmachinefixedinstore). Sp_Ai_* AI-assistant scaffolding family — all 5 orphan: `Sp_Ai_AddCommonAfter`, `Sp_Ai_AddCommonAfterNew`, `Sp_Ai_AddQuoQuoAfter` (calls orphan `Fun_getProductMaxStyle`), `Sp_Ai_AddSalsalOrder`, `Sp_Ai_AddWorkOrder` — zero refs in gdsmodule, forms, other routines, or xly-src (no Java handler dispatches `Sp_Ai_*`); all stub bodies, mostly commented out, hardcoded to seed-tenant `'1111111111'`. Sp_AL_SHDCheckSave (送货单 batch-children qty redistribute) — substantive logic but orphan (no callers). DBA install helpers sp_alert_bit/sp_alert_text (schema-hardening) — orphan-by-design, ship in install scripts. Sp_Apply_Flow_Cahreceipt/CLReject/CPReject — workflow-apply data builders, substantive: dispatched dynamically by Java `CheckExamineFlowDataServiceImpl.doSendCheckFolwData()` via `doProByNameFlow(..., sApplyProName, ...)` where `sApplyProName` is read from `gdsmoduleflow.sApplyProName` (table is empty in this DB — workflow configs are tenant-provisioned per deployment). Flags: `Sp_afterSave_tore` catalog header is copy-pasted from `tice` sibling (says 回厂通知单保存后 for both); `Sp_afterSave_sWod` catalog header says 保存前 but is after-save; `sp_alert_text` catalog header (`根据模块sId删除模块`) is mis-copied — body actually widens >1000-byte nullable varchars to TEXT; Sp_Ai_AddQuoQuoAfter calls `Fun_getProductMaxStyle` which is itself orphan-via-dead-chain. |
| 2026-05-12 | 20 | 0 | 1475 | Pass 2 session 17 — `Sp_Apply_Flow_Order` → `Sp_Apply_Flow_Qualityaccident` (all 20 procedures, continuing the `Sp_Apply_Flow_*` workflow-apply family). 20 substantive + 0 orphan. All follow the family pattern: dispatched dynamically by Java `CheckExamineFlowDataServiceImpl.doSendCheckFolwData()` via `doProByNameFlow(..., sApplyProName, ...)` from `gdsmoduleflow.sApplyProName` (empty in this DB — workflow configs tenant-provisioned per deployment). Modules covered: 销售订单 (Order, minimal payload, sProductInfo JSON-or-eleproduct fallback), 销售订单变更 (OrderChange + superseding OrderChangeNew with 10 tiers + 营销一/二部 dept classification + 7 scenario flags incl. 是否烟包 product-classify-root + form-sId checks), 工艺变更 (ProcessChange with 10 tiers + companion in-flow updaters Proc1/Proc2 writing dPoorMoney/iOrderChange), 工序发外检验 (ProcessTest with 5 tiers, dynamic 外协人员 from opsoutsideprocessmaster.sId=sSrcId, + Proc1/Proc2 updaters for iTypeResult1/iTypeResult), 成品盘点 (productpd, 2 tiers 仓库组长+成本会计, repeated malformed predicate from session 16's materialspd), 成品发外检验 (ProductTest with 5 tiers, early-exit when iTestResult=0, + Proc1/Proc2 updaters), 版本变更 (ProductVersion, 2 tiers 技术部+仓储, no Proc companions), 采购对账修改单价 (PurCheck with dept-walking 二级/一级 tiers + price-variance line summary, KK-prefixed slaves exempted from variance), 采购订单 (PurOrder minimal old proc with hardcoded sUser='管广飞' + live PurpurchaseOrder with 7 tiers + iType/iType1 variance flags + bPrice=1 guidance-priced classify check), 采购申请 (Purpurchaseapply with iType-branched tier selection + superseding Purpurchaseapplynew with dept-walking + 4 senior tiers + iApplySort 烟包), 质量事故 (Qualityaccident with 11 tiers + 3-way 会签 assembly into temp table from bDeductionMaterials/bDeductionSupply/sType + dLoseMoney>5000 OR dRewardPunishmentMoney>2000 threshold + iCustomerLook conditional + 烟包 via SisCustomerProperty). Flags: (1) Sp_Apply_Flow_OrderChangeNew hardcodes tenant-specific dept-root GUIDs (`17344171700007029955590024910000` 营销一部, `20231120093814840397991462270158` 营销二部) + form-sIds `192116810113315234963208090` and `101801153119616594919790770` + process-sId `1691254111216986535514780` + product-classify-root `16624527080007919539418229414000`; (2) Sp_Apply_Flow_productpd 仓库组长 predicate `iPosition=32 AND (sEmployeeNo='00034' OR iPosition=7)` is malformed — the `iPosition=7` disjunct is unreachable since the outer `AND iPosition=32` already filters; same bug shape as `Sp_Apply_Flow_materialspd` from session 16; tenant-baked sEmployeeNo `'00034'`/`'06376'` literals; (3) Sp_Apply_Flow_PurCheck variance formula `SUM(dMaterialsMoney) − SUM(dMaterialsPrice*dMaterialsPrice)` looks wrong — multiplies new-price by new-price instead of `dAuxiliaryQty*dMaterialsPrice` (likely copy-paste); inspect before threshold logic relies on it; (4) Sp_Apply_Flow_PurOrder hardcodes `sUser="管广飞"` (a person's name) — clearly dev scaffolding, superseded by Sp_Apply_Flow_PurpurchaseOrder in production; (5) Sp_Apply_Flow_PurpurchaseOrder `p_iOut1` count of guidance-priced lines is missing `WHERE sParentId=sGuId` predicate — counts globally across all orders, not just this one; threshold `>30000` hardcoded but comment header claims "超过2万的总经理审核" (20k vs 30k mismatch); (6) Sp_Apply_Flow_Purpurchaseapplynew references local `p_iType` for read but JSON_OBJECT emits master column `iType` directly — local read is dead; (7) Sp_Apply_Flow_Qualityaccident `p_ThreeFlow` (生产计划部经理) is declared and emitted in JSON but never populated (its SELECT is commented out) — consumers receive empty string; `iCustomerLook` requires both `bCustomerLook=1` AND `p_FiveFlow<>''` so customer-look review is silently skipped when the order 制单人 is deleted; (8) Sp_Apply_Flow_ProcessChange_Proc2 catalog header copy-pasted from Proc1 (both say "工艺变更 过程1"); (9) Sp_Apply_Flow_ProcessChange `p_iOut2` (`LOCATE('YFGD',sWorkOrderNo)>0`) inferring work-order prefix from string — fragile to work-order numbering scheme changes; (10) all Apply-time procs leave `sSrcReportData` commented out, falling back to `Sp_Add_Flow`'s default report data per family convention. |
| 2026-05-12 | 20 | 0 | 1495 | Pass 2 session 16 — `Sp_Apply_Flow_Fksq` → `Sp_Apply_Flow_OpsProductMorebecome` (all 20 procedures, continuing the `Sp_Apply_Flow_*` workflow-apply family). 20 substantive + 0 orphan. All routines follow the family pattern: dispatched dynamically by Java `CheckExamineFlowDataServiceImpl.doSendCheckFolwData()` via `doProByNameFlow(..., sApplyProName, ...)` where `sApplyProName` is read from `gdsmoduleflow.sApplyProName` (table empty in this DB — workflow configs tenant-provisioned per deployment). Modules covered: 费用报销/付款申请 (Fksq + near-duplicate Fybx), 设备维修 (MachineFix), 补料申请 (MaterialsApply), 领料申请 (MaterialsApplyLL), 退料申请 (MaterialsBack + companion in-flow updater MaterialsBack_Proc1), 材料变更单 (MaterialsChange), 材料盘点 (materialspd), 物料指导价 (MaterialsPrice), 研发反馈 (MaterialsReturn), 材料检验 (MaterialsTest + companion in-flow updaters MaterialsTest_Proc{1,2}), 材料测试反馈 (mftMaterialsReturn), 发外对账 (OpsCheck), 工序发外 (OpsProcess), 整单发外 (OpsProduct), 整单发外 multi-row (OpsProductMore), 成品外购单价变更 (OpsProductMorebecome). Flags: (1) Sp_Apply_Flow_Fksq + Sp_Apply_Flow_Fybx near-duplicate (Fksq reads iCigPack from advanceCostCheckMaster, Fybx from expensereimbursementmaster — likely one supersedes the other); (2) Sp_Apply_Flow_MachineFix sets "sDeptName" key twice in output JSON, hardcodes machine sId `17030614920003057848750279902700` for iOut branch; (3) Sp_Apply_Flow_MaterialsBack has stray `select p_OneFlow;` debug echo; (4) Sp_Apply_Flow_materialspd 仓库组长 predicate `iPosition=32 AND (sEmployeeNo='00034' OR iPosition=7)` is malformed — iPosition=7 branch unreachable; (5) Sp_Apply_Flow_MaterialsPrice hardcodes department sId `'20231120093820561209518017890988'` and skips FiveFlow tier; (6) Sp_Apply_Flow_MaterialsReturn fails silently with sCode=-8 if `sGuid` isn't wrapped as JSON `{"params":[...]}`; (7) Sp_Apply_Flow_MaterialsTest declares unused `p_iOut1`; (8) Sp_Apply_Flow_OpsCheck/OpsProcess hardcode 7-element exempt 工序-sId list (`1691254111216986535514710`...) and source-form sIds (`101801153119616594919790770`, `192116810113315234963208090`); (9) Sp_Apply_Flow_OpsProcess climbs `sisdepart.sParentId` twice for 生产部长 — fragile to depth changes; (10) Sp_Apply_Flow_OpsProduct CONCATs p_OneFlow with p_TwoFlow (营销部长 + 对应部门部长 merged into one comma-joined list); (11) Sp_Apply_Flow_OpsProductMore: `p_iCount2` (基准价×毛利率) computed but `iOut2` set from `p_iCount4` (订单单价) — variable-naming drift; (12) **Sp_Apply_Flow_OpsProductMorebecome real bug**: `p_ThreeFlow` set to 总经理 (`iPosition=1`) then immediately overwritten by 财务总鉴 (`iPosition=11`) — 总经理 tier never returned; also `p_iCount3` assigned twice (second shadows first), `p_iCount4` referenced but never assigned, so `iOut2` always 0; (13) tenant-specific department-root GUIDs hardcoded across the Ops* procs: `20231120093814639059733069696942` (生产), `17344173190001090119214960551400` (供应链), `16624527080007919539418229414000` (烟包产品 classify root). |
| 2026-05-12 | 20 | 0 | 1375 | Pass 2 session 22 — `Sp_bd_MachinePlanTemplate` → `Sp_bd_TmAnalysis` (all 20 procedures, continuing the `Sp_bd_*` / `Sp_Bd_Root_*` dashboard family). 14 substantive + 6 dormant. Substantive-via-install-script in `xly-src/script/标版/30100101/`: `Sp_bd_MachinePlanTemplate` (车间效率综合看板-根 single-machine key/value bundle, 19K body), `Sp_bd_McPlanConter` (计划产量 dashboard), `Sp_bd_McPlanRate` (计划达标率 = 实际/计划, uses `Fun_GetMachineWorkStartDate`), `Sp_bd_OrderProgress` (生产计划看板 work-order list, paginated + group-by injectable), `Sp_Bd_Root_allstatus` (top-of-board status, mixed real/simulated env data, 封存), `Sp_Bd_Root_allstatus_1` (销售-by-印件属性 tile, hardcoded +300 offset + per-bucket value forces), `Sp_Bd_Root_allstatus_2` (采购-by-材料分类 tile, +100 offset, no date filter), `Sp_Bd_Root_allstatus_3` (今日要事 8-bucket counter strip across mft/sal/pit/ops/salreject), `Sp_Bd_Root_Production` (production-board template w/ hardcoded environment readings). Dormant (no install script, no callers anywhere): `Sp_Bd_Root_allstatus25` + `_new` (16-press demo grid with fixed `iPlcNo` literals `00000010`/`00000005`/`CD102-7`), `Sp_Bd_Root_allstatus_1_new`/`_2_new`/`_3_new` (rowset-returning sibs, no install script). Demo-data placeholders: `Sp_bd_TeamDayMonthCompare`/`Sp_bd_TeamDayMonthCompare1` (hardcoded 89% for all 8 series), `Sp_bd_TeamOee` (3 literals 89/69/29), `Sp_bd_team_TmAnalysis` (`Sp_bd_TmAnalysis` variant — filters commented out, ignores `sPlcNo`), `Sp_bd_TmAnalysis` (overwrites IN `sSuId` to `'2220000222'`). Flags: (1) **`Sp_Bd_Root_allstatus26` real bug**: `INSERT INTO p_Bd_PlcNo_No(sMachineNo,iNo)` and cursor `SELECT sMachineNo,iNo` reference column `sMachineNo` that the temp table never defines (only `iPlcNo`,`iNo`) — proc throws on seeding INSERT every call; (2) `Sp_Bd_Root_allstatus` mixes real `viw_plc_machine` reads with simulated `rand()` overwrites — live readings are immediately discarded; (3) `Sp_Bd_Root_allstatus_2`/`_2_new` 本月 date filter commented out — sum spans all history; (4) `Sp_Bd_Root_allstatus_1`/`_1_new` per-bucket numeric forces (36/58/86) collapse real sales to demo constants; (5) `Sp_bd_TeamDayMonthCompare`/`_1`/`Sp_bd_TeamOee` accept full dashboard signature but use no inputs — entirely demo data; (6) `Sp_bd_team_TmAnalysis` filter block commented out — proc ignores `sPlcNo` and returns global all-time stats; (7) `Sp_bd_TmAnalysis` overwrites IN `sSuId` to demo-tenant `'2220000222'`; (8) `Sp_Bd_Root_Production` hardcodes `temperature='27.6度'` and `humidity='56.2%'`; (9) `Sp_bd_MachinePlanTemplate` shift-quantity defaults `dDayPlanQty=8000` / `dMonthPlanQty=240000` — tenant-specific; (10) all 20 reachable only via external dashboard HTTP endpoint that invokes the proc by name. |
| 2026-05-12 | 20 | 0 | 1415 | Pass 2 session 20 — `Sp_Bd_bi22` → `Sp_bd_EqAnalysis` (all 20 procedures). 15 substantive + 5 orphan. Continues the workshop-kanban family: 现场 4-tile boards `Sp_Bd_bi22/23/24` (印刷/糊盒/品检 — install scripts under `xly-src/script/标版/30100101/kanban/`, reachable only via external dashboard HTTP endpoint by proc-name), `Sp_Bd_bi4` (三屏设备 outlier — no install script, candidate orphan), `Sp_Bd_bi22_nomes` (orphan non-MES fork). Older 车间-wide family: `Sp_Bd_cq_workshop_hh/mt/pj/pm/sy/ys` covering 糊盒/模烫/品检/喷码/丝印/印刷 (only `_ys` has an install script — others reachable only via dashboard endpoint), `Sp_Bd_cq_workshop_ys_nomes` orphan non-MES fork. Sealed Cqzy_workshop family: `workshop1` 综合-根 (live, install script present), `workshop2/3` (live, install scripts present, predecessors of cq_workshop_sy/pj), `workshop5/6` (marked `封存` 2021-06-20 — retired non-MES variants targeting `commonAuto/templateQCM_CQZY5/6` front-end templates, no install script). Equipment-status dashboard trio: `Sp_bd_Eqabnormal` substantive (调机时间分析 dashboard, 异常 idle >15min over yesterday's shift, install script), `Sp_bd_EqAdjust` substantive (调机 setup-time analysis, install script), `Sp_bd_EqAnalysis` substantive (大屏展示 → 功能模块 → 小模块-设备全面分析, form-master sId `101251240115016087744264440`). Flags: (1) `Sp_Bd_bi22_nomes`/`Sp_Bd_cq_workshop_ys_nomes` — non-MES fallback forks with no install script or call site; (2) `Sp_Bd_bi4` 三屏设备 numbering out of band vs bi16-24 cohort, no install script — likely one-off; (3) `Sp_Bd_cq_workshop_ys` iNo mapping skips position 5 (`(4,4),(3,6)` — likely typo); (4) `Sp_Bd_cq_workshop_mt` is family root (call-comment copy-pasted into all `_hh/_pj/_pm/_sy` siblings — stale references); (5) `Sp_Bd_Cqzy_workshop5/6` carry 封存 markers but bodies are intact — verify no legacy dashboard endpoint before dropping; (6) `Sp_bd_Eqabnormal` COMMENT header `调机时间分析` is copy-pasted from `Sp_bd_EqAdjust` — body is actually 异常 (abnormal idle) analysis, not 调机; (7) all three Eq* procs share the `MOD(iPlcNo,14) BETWEEN 1 AND 12` test-PLC exemption — tenant-specific PLC numbering convention; (8) `Sp_bd_EqAnalysis` declares `sReturn varchar(255)` — likely too narrow for multi-machine JSON, callers should compare expected length; (9) all 20 PLC literal lists tenant-deployment-specific. |
| 2026-05-12 | 20 | 0 | 1435 | Pass 2 session 19 — `Sp_Apply_Flow_Work` → `Sp_Bd_bi21` (all 20 procedures). 14 substantive + 6 orphan. Exits the `Sp_Apply_Flow_*` family with the final 3 entries (Work — 工单 minimal display-only payload; Ystz — 预算调整单 with 8 tiers + 烟包; Yzfy — 费用预支单 with 7 tiers + 2 control-dept overrides for 人力资源/总经办). Sp_BatchGetSid substantive (条码(随机码)生成 form `16050651010009472619904464080000`, bulk newId allocator). Sp_Bd_bi_Lostorder substantive (客户估价分析 dashboard chart, form `16758336770001677223131387683300`). Enters the `Sp_Bd_bi<n>` workshop-kanban family — 15 routines covering 喷码/模烫/印刷/糊盒 workshop + 现场 boards: substantive-via-install-script (bi16 喷码, bi17 模烫, bi18 印刷+MES, bi19 糊盒, bi20 喷码现场, bi20_1 OEE-gauge, bi20_1_newZZT current variant, bi20_2 + bi20_2new time-breakdown, bi21 模烫现场) — all have install scripts under `xly-src/script/标版/.../kanban/` but no live form/hook/Java binding (reachable only via external dashboard HTTP endpoint by proc-name); orphan variants (bi18_nomes 非MES fork, bi20_1_new superseded by _newZZT, bi20_2_nomes non-MES fork, bi20_hh 糊盒-PLC fork w/ copy-pasted header, bi20_ys 印刷-PLC fork w/ copy-pasted header). Flags: (1) Sp_Apply_Flow_Ystz emits `"EightFlow", p_SevenFlow` — assigns 总经理 value to 董事长 slot (copy-paste bug); (2) Sp_Apply_Flow_Ystz/Yzfy hardcode 事业部 dept-root sId `17344171700007029955590024910000`; (3) Sp_Apply_Flow_Yzfy hardcodes 4 GUIDs incl. 人力资源 + 总经办 control-dept sIds; (4) Sp_Apply_Flow_Work emits no `<Tier>Flow` JSON keys — relies on `gdsmoduleflow` rows for approver resolution rather than embedded roster (unusual for this family); (5) Sp_Bd_bi20_hh/Sp_Bd_bi20_ys catalog headers say `喷码+分切现场` but bodies target 糊盒 PLCs (`34,33,32,30`) and 印刷 PLCs (`4,6,2,5`) respectively — copy-pasted header bug, also makes them unsearchable from UI; (6) Sp_Bd_bi20_2new comment-header still references `Sp_Bd_bi20_2(14,...)` not updated for the new name; (7) Sp_Bd_bi18 vs Sp_Bd_bi18_nomes — former is MES-integrated, latter (orphan) is non-MES fallback fork; same _nomes/_new fork pattern recurs across bi20_1/bi20_2; (8) all Sp_Bd_bi* PLC iPlcNo literals are tenant-deployment-specific (no `elemachine.sName` lookup) — re-mapping needed if cloned. |
| 2026-05-12 | 20 | 0 | 1395 | Pass 2 session 21 — `Sp_bd_EqLoad` → `Sp_bd_MachinePlanTemplate_new` (all 20 procedures, continuing the `Sp_bd_*` dashboard family). 7 substantive + 13 orphan. Continues the equipment-dashboard family from session 20. Substantive-via-install-script in `xly-src/script/标版/30100101/`: `Sp_bd_EqLoad` (设备负荷 top-18 排程 backlog bar chart), `Sp_bd_EqSpeed` (速度嫁动率 capped 0-120%), `Sp_bd_EqStatus` (数字工厂状态看板 right donut, 封存 2021-06-20), `Sp_bd_EqTime` (时间稼动率), `Sp_bd_EquipmentLoad1` (本月设备产量 top-8), `Sp_bd_MachineOee` (设备OEE展示 — placeholder, emits 4 literal constants 89/69/29/70 with no production-table reads), `Sp_bd_MachinePlanDate` (车间效率综合看板-根), `Sp_bd_MachinePlanStatus` (机台当前转台饼形图), `Sp_bd_MachinePlanTemplate_new` (单机看板 左边+顶部 from family-base install script). Orphan (封存 sealed 2021-06-20/21, no install script, reachable only by tenant-baked dashboard endpoint by proc-name): `Sp_bd_EqStatus_new` (refined latest-row donut for 数字工厂), `Sp_bd_EquipmentLoad` (dynamic-SQL multi-state load chart — superseded by `_1`), `Sp_Bd_hy_workshop_oy` (凹印车间 6-machine cursor — customer-specific `hy_` fork, hardcoded PLC list 1-6), `Sp_bd_machine_TmAnalysis` (单个机台时间分析 pie — hardcoded `sSuId='2220000222'` after IFNULL ignores its IN parameter), and the entire `Sp_bd_MachinePlanTemplate_{1,2,3,3_new,4,5,5_new}` cohort (单机设备看板 1屏 `commonAuto/QCZH1` tiles: `_1` 本班数据, `_2` 本班-本月, `_3`/`_3_new` 本设备月度+标准值, `_4` 本班时间分析, `_5`/`_5_new` 本班本月时间分析). Flags: (1) `Sp_bd_MachineOee` is a stub — 4 hardcoded literal percentages, no PLC/production reads, but COMMENT header `设备OEE展示` overstates the body; (2) `Sp_bd_machine_TmAnalysis` overwrites its `sSuId` IN parameter with hardcoded `'2220000222'`, ignoring tenant context; (3) `Sp_bd_EqStatus_new` drops `sLoginId`/`bFilter`/`sCode`/`sReturn` from the parent signature — JSON donut is `SELECT`-emitted instead of returned via OUT; (4) `Sp_bd_EqSpeed` is referenced by 4 `Sp_plc_implementation*` procs only as a `-- call` debug comment, not a real CALL; (5) `Sp_bd_MachinePlanTemplate_2` is referenced by 3 `Sp_mes_TimeActivation_*` procs only as a `-- call` debug comment + a same-named `p_bd_MachinePlanTemplate2` temp table (name collision, not a real call); (6) `Sp_bd_MachinePlanTemplate_3`/`_5` similarly referenced only by their `_new` successors as `-- call` debug comments; (7) hardcoded shift-quantity defaults `dDayPlanQty=8000`/`dMonthPlanQty=240000` recur across the MachinePlanTemplate family — re-mapping needed per tenant; (8) `MOD(iPlcNo,14) BETWEEN 1 AND 12` test-PLC exemption recurs across Eq*; (9) all 20 reachable only via external dashboard HTTP endpoint that invokes the proc by name. |
| 2026-05-12 | 20 | 0 | 1315 | Pass 2 session 25 — `Sp_beforeSave_sPct1` → `Sp_beforeSave_sScr` (all 20 procedures, continuing the `Sp_beforeSave_s<Code>` thin-dispatcher family from session 24). 18 substantive + 2 orphan. All 20 share the identical body shape: optional `sGuid` quote-wrap normalisation, then a single `CALL Sp_saveReturn_s<Code>(sGuid,sBrId,sSuId,1,@sCode,@sReturn)` delegating to the saveReturn sibling; medium/large bodies (sPst 7K, sPtr 2.5K, sQtt 1.7K, sRct 18K, sRcts 20K, sScr 2.4K, sSck 21K) retain extensive commented-out legacy fallback SQL — direct multi-statement updates against the same upstream tables (`SalSalesOrderMaster.dRealAdvanceMoney`, `salsalescheckingslave`-driven aggregates, `pitproductinstoreslave`-driven aggregates, etc.) that the active path now delegates. Substantive-via-gdsmodule-sSaveProNameBefore hook: `sPis` (采购入库), `sPiv` (采购发票), `sPkg` (采购对账), `sPmd` (生产领料 + 生产补料 + 生产退料, three modules), `sPmt` (付款单), `sPod` (采购订单), `sPpr` (产量上报), `sPst` (成品入库), `sQtt` (新报价单), `sRct` (收款单), `sRgd` (销售退货), `sSck` (销售对账). Substantive-via-Sp_delete_backwriting/Sp_Invalid_backwriting dispatchers only (no `gdsmodule.sSaveProNameBefore` slot found — save-time hook configured at form-master/customer-override layer): `sPct1` (品质首检 mobile, form `12012615914116373957014740`), `sPdt` (成品检验, form `15831288240001057224508428921300` + 2 customer-override forms), `sPpa` (采购申请, form `192116810113315217105813660`), `sPtr` (form `101251240115015920999005840` resolves to 成品领用单据 in gdsmodule; **but proc's own header + commented-out legacy SQL target `pitproductrejectslave` = 成品报废 — dispatcher/proc doctype mismatch**), `sRcts` (收款单（汇总）, form `101251240115017022732698090`), `sScr` (派车单, form `15839936170002427227633635401000`). Orphans: `Sp_beforeSave_sPrj` (采购退货 — `Sp_saveReturn_sPrj` exists but no dispatcher branch, no gdsmodule hook, no other caller anywhere; the 采购退货 doctype is not wired into the dispatch pair, unlike its sibling 销售退货 → sRgd); `Sp_beforeSave_sScd` (长期合同 — same situation, `Sp_saveReturn_sScd` exists but no caller). Flags: (1) **`Sp_beforeSave_sPtr` doctype mismatch**: dispatcher comment annotates the `101251240115015920999005840` branch as `成品报废` but the form-guid resolves to `成品领用单据` in `gdsmodule`; the proc's own header + commented-out legacy SQL (`pitproductrejectslave.dProductQty` → `salchildproductapplyslave.dProductOutStoreQty`) target 成品报废. Either the comment is stale or the dispatcher routes the wrong doctype to this proc; (2) **`sRgd` and `sPtr` invalidate asymmetry**: both are called by `Sp_delete_backwriting` but **not** by `Sp_Invalid_backwriting` — invalidate path does not replay these writebacks, unlike all other family members; (3) `sPiv` (采购发票) is **not** referenced by either dispatcher proc — invalidate/delete paths do not replay this writeback either, only the save-time hook fires; (4) `sPmt` and the medium/large procs (sPtr/sRcts/sScr/sPst/sRct/sSck/sQtt) skip the `sGuid` quote-wrap step, relying on the saveReturn sibling to handle raw input — divergence from the canonical pattern; (5) `sRcts` skips the `IF IFNULL(sGuid,'') <> ''` guard entirely — invokes saveReturn even on empty input; (6) `sPpr` retains a commented-out `LEAVE top;` dev escape hatch; (7) `sQtt` dispatcher includes 3 commented-out alternate quotation-form sIds (估价单-书刊/标签/软包) that would also route here if uncommented — partial rollout of multi-form quotation flow; (8) `sPmd` is the most heavily wired — 3 gdsmodule hooks + 4 dispatcher branches (生产补料, 来料入库, 生产领料, 生产退料) all collapse to the same proc, so the inner `Sp_saveReturn_sPmd` must internally branch by table/form-type; (9) commented-out legacy fallback bodies on the larger procs are kept for reference but contradict the active delegation — maintainer audit candidates for cleanup. |
| 2026-05-12 | 20 | 0 | 1295 | Pass 2 session 26 — `Sp_beforeSaveReturn_sPtr` → `Sp_beforeSave_tore` (all 20 procedures, continuing `Sp_beforeSave_*` family from session 25). 12 substantive + 8 orphan. Two sub-clusters: (a) the entire **`Sp_beforeSaveReturn_s<Code>` cohort** (sPtr, sQtt, sRct, sSck, sScr) — 7-arg signature mirroring `Sp_saveReturn_*` (sGuid longtext + iTag + sCode + sReturn), all five orphans (no form-master ref, no gdsmodule hook, no other proc caller, no xly-src hit) and superseded by their `Sp_beforeSave_s<Code>` siblings already wired via `Sp_Invalid_backwriting`/`Sp_delete_backwriting`; `_sRct` is by far the largest (≈28K, updates 13 downstream tables including CahReceiptMaster/SalSalesOrder/MftWorkOrder/SalDeliverGoods/Cah financial chain) — looked like a comprehensive draft that never went live; (b) **`Sp_beforeSave_s<Code>` thin-wrapper continuation** (sSdp, sSfu, sSiv, sSmi, sSmia, sSmo, sSmoa, sSod, sStl, sTLPmd, sWod, sWXKK, sYzfy, tice, tore) — same `quote-wrap-then-CALL Sp_saveReturn_*` shape as session 25's batch. Substantive-via-gdsmodule-sSaveProNameBefore: `sSiv` (销售发票单据 / 销售送货流程), `sSod` (1/3 新增销售订单 + 1/3 新增轮转销售订单 / 订单生产流程), `sWod` (轮转工单 + 生产工单 + 2/3 新增生产补单 — also as `sDeleteProName` on those same modules, so save and delete share the writeback path). Substantive-via-dispatcher-only (`Sp_Invalid_backwriting` + `Sp_delete_backwriting` both branch on sFormGuid): `sSfu` (商机跟进单据 form `101251240115016035948853880`), `sSmi` (半成品入库 form `101801153119616759291255520`), `sSmia` (半成品入库申请 form `101801153119616759337165930`), `sSmo` (半成品出库 form `101801153119616759303641850`), `sSmoa` (半成品出库申请 form `101801153119616759337728990`). Substantive-via-delete-only (asymmetric, `Sp_delete_backwriting` only — no Invalid branch): `sWXKK` (外协商扣款 form `1691254111217013458193680`), `tice` (回厂通知单 form `1691254111217313133811620`), `tore` (固定资产入库 form `1691254111217313178187860`). Orphans (sub-cluster b): `sSdp` (开发计划 — saveReturn sibling exists but no caller anywhere), `sStl` (header just `前反写数量` with no document name, suffix sStl matches no module — likely placeholder for an unimplemented module), `sTLPmd` (生产退料 — saveReturn sibling missing; the actively-wired 生产退料 path runs through `Sp_beforeSave_sPmd` instead — sTLPmd looks like an earlier variant superseded by sPmd), `sYzfy` (预支费用 — 9-arg sig with `sTableName/sFormGuid/sLoginId/iFlag` extras doesn't match any framework save-hook contract; body is a substantial budget validator against `advanceCostCheckMaster/Slave` + `departmentalbudgetmaster/Slave` for the master's create-date month/department, BUT body also stray-calls `Sp_afterSave_sDgn` near top — paste error from a delivery-notify template). Flags: (1) **`Sp_saveReturn_sSmia` and `Sp_saveReturn_sSmoa` do not exist in this DB** but their `Sp_beforeSave_*` + `Sp_afterSave_*` siblings call them; runtime error path if these dispatcher branches ever fire; (2) **`Sp_saveReturn_sTLPmd` also does not exist** — sTLPmd before-save would error on first invocation; (3) **`Sp_beforeSaveReturn_sRct` header** is mis-copied as `估价单保存前反写状态` (sQtt's header) despite operating on the receipt graph (CahReceiptMaster/CahPaymentMaster) — stale paste; (4) **dispatcher-coverage asymmetry**: sWXKK / tice / tore are called only by `Sp_delete_backwriting`, not by `Sp_Invalid_backwriting` — cancel-invalidate of these records does not replay the writeback; (5) `Sp_beforeSave_sYzfy` 9-arg signature is incompatible with the framework's standard 5-arg save-hook contract — even if someone wanted to wire it via `sSaveProNameBefore`, the dispatcher would not call it; (6) `Sp_beforeSave_sYzfy` body contains a debug `Select … From advanceCostCheckslave …` whose result is never captured — leftover from development; (7) `Sp_beforeSave_tice` / `Sp_beforeSave_tore` skip the standard `sGuid` quote-wrap, relying on the saveReturn sibling to handle raw input (same divergence noted for sPtr/sRcts/sScr in session 25); (8) `Sp_beforeSave_sWod` carries 2 extra IN params (`sAllData`, `sLoginId`) vs sibling 5-arg shape but neither is used — dispatcher passes `''` literals; (9) the entire `Sp_beforeSaveReturn_*` cohort being orphan suggests a planned alternate framework architecture (perhaps moving the backwriter logic into pre-commit code rather than save-time hooks) that was abandoned. |
| 2026-05-12 | 20 | 0 | 1455 | Pass 2 session 18 — `Sp_Apply_Flow_QualityaccidentCL` → `Sp_Apply_Flow_Supply` (all 20 procedures, continuing the `Sp_Apply_Flow_*` workflow-apply family). 20 substantive + 0 orphan. All follow the family pattern: dispatched dynamically by Java `CheckExamineFlowDataServiceImpl.doSendCheckFolwData()` via `doProByNameFlow(..., sApplyProName, ...)` from `gdsmoduleflow.sApplyProName` (empty in this DB — workflow configs tenant-provisioned per deployment). Modules covered: 质量事故 variants (QualityaccidentCL 材料损失 8 tiers + 5k threshold; QualityaccidentCustomer 客户索赔 6 tiers + 烟包; QualityaccidentMaterials 供应商扣款 9 tiers + Proc1 dOKMaterialsMoney updater; QualityaccidentNB 内部扣款 4 tiers anchored to 责任部门; QualityaccidentsSupply 外协商扣款 9 tiers + dept-fallback + Proc1 updater), 返工单 (ReturnWork 3 tiers, joins mftproductionplanbillslave to salsalesorderslave for price), 设计申请 (salDesign 3 tiers, applicant-dept-driven OneFlow + form-sId filter `1691254111217201634922170`), 研发申请材料测试 (salesmaterials 6 tiers + 短路 collapse), 销售退货 (salesreturn 3 tiers — executed return on salrejectgoodsmaster), 销售退货申请 (salesreturnapply 4 tiers + 营销一/二部 + 烟包 + 非事故 flag), 销售发票舍入 (SalInvoice 6 tiers, applicant-dept twice climbed, 汇率差异 excluded from threshold), 销售对账修改单价 (SalSaleCheck 6 tiers + price-variance + 烟包-via-SisCustomerProperty), 销售订单 (SalSaleOrder 14 tiers + 会签 + 营销一/二部 + 7 routing flags — largest body), 送货通知单 (SalSalesNotify 5 tiers + 营销一/二部 + 逾期客户/有数量/烟包), 客户准入 (sCustomer 6 tiers + 一次性客户 detection), 框架协议 (sCustomerAccord 6 tiers with 营销一/二部 position-tier swap via p_saledeptl), 阶梯价格审批 (StepPrice 7 tiers + <10% 毛利率 cutoff + 烟包 + commented-out cur1 over SisRate), 供应商准入 (Supply 11 tiers + classify-driven iFlow 1/2/3 + payment-term iFlow1 + 供应链 dept iDept). Flags: (1) Sp_Apply_Flow_QualityaccidentCL 烟包 declaration + lookup commented out, iCigPack emitted directly from master; (2) Sp_Apply_Flow_QualityaccidentCustomer hardcodes 烟包产品 classify root `16624527080007919539418229414000`; (3) Sp_Apply_Flow_QualityaccidentsSupply emits JSON key `"ElevenFlow "` (with trailing space) — downstream consumers keyed on bare `ElevenFlow` will miss this tier; (4) Sp_Apply_Flow_QualityaccidentsSupply_Proc1 catalog header `供应商扣款单号 过程1` copy-pasted from QualityaccidentMaterials_Proc1 sibling; (5) Sp_Apply_Flow_salDesign form-sId `1691254111217201634922170` hardcoded as match filter — silently empty payload for any other form bound to salsalesordermaster; (6) Sp_Apply_Flow_salesreturnapply hardcodes 营销一/二部 dept-root GUIDs + 烟包 classify root (same pattern as SalSaleOrder); (7) Sp_Apply_Flow_SalInvoice/SalSaleCheck header comments document threshold gating (100元/2万 cutoffs) but procs emit only roster — threshold gating left to consumer JSON-evaluator (no `p_iOut1/p_iOut2` cutoff flags emitted); (8) **Sp_Apply_Flow_SalSaleOrder duplication**: `p_ElevenFlow` and `p_TwelveFlow` both populate from `iPosition=34` (duplicate value — only one of 营销负责人 ElevenFlow/TwelveFlow should differ), and `p_MoreFlow` = same `iPosition=3` as `p_ThreeFlow` (会签 and 营销部长 collapse identical); (9) **Sp_Apply_Flow_SalSalesNotify wrong-table bug**: 烟包 count lookup hits `salsalesinvoiceslave` (the invoice slave) but should hit `saldelivernotifyslave` (the notify slave) — likely a copy-paste from Sp_Apply_Flow_SalInvoice; iOut2 wrong for delivery-notify forms with no companion invoice yet; (10) Sp_Apply_Flow_sCustomer comment for `iPosition=20` 税务费用核算单元 carries `???` (developer uncertainty); `sParentName` JSON label says 供应商分类 but body returns `siscustomerclassify.sName` (customer classify) — copy-pasted label; hardcodes `sCustomerPropertyId='16988935270007883055824272309000'` (一次性客户 / zero-credit profile); (11) Sp_Apply_Flow_sCustomerAccord variable name `p_saledeptl` (with trailing `l`) — typo, but used consistently throughout the proc; (12) Sp_Apply_Flow_StepPrice carries a large commented-out CURSOR (`cur1` over `SisRate`) — earlier design used per-margin-band dynamic tier-and-position selection, replaced by simpler `<110%` cutoff; (13) Sp_Apply_Flow_Supply hardcodes 12 tenant-specific GUIDs (4 payment terms + 6 supplier classifies + 供应链 dept root + 烟包 classify) — supplier classifications need re-mapping if cloned to a different tenant. |

| 2026-05-12 | 20 | 0 | 1215 | Pass 2 session 30 — `Sp_BtnEventWorkPost_New` → `Sp_BtnUpdate_InvoiceSubCheck` (all 20 procedures). 20 substantive + 0 orphan. One singleton (`Sp_BtnEventWorkPost_New`) for 工单成本分析 grid manual-adjustment (`accordercostanalysis` `dAdjustHour`/`dAdjustProcessQty` overwrite, then re-derive `dAreaQty`/`iProcessColorQty` via `mftworkordercontrol` join — `Sp_BtnEvent_*` dispatcher family). Then the entire `Sp_BtnRepair_Update*` cohort (17 procs) plus 2 older-naming siblings (`Sp_BtnRepairUpdateCheckMemo`, `Sp_BtnRepairUpdateJzMemo`) and 1 `Sp_BtnUpdate_*` (`Sp_BtnUpdate_InvoiceSubCheck`). All follow the same dispatch pattern: front-end "批量修改" toolbar dialog passes the procedure name through `GenericProcedureCallServiceImpl.doGenericProcedureCall()` POST `/procedureCall/doGenericProcedureCall`, with `sProInParam` carrying `{params: [{value: [{sId}]}], changeValue: {<field>, textareaValue}}` per the `xlyEntry/.../templates/templesql/sButtonParam.sql` template's documented `BtnRepair` contract. None registered in `gdsmodule`/`gdsconfigformmaster`/other procs/xly-src — the proc name lives on the front-end button config (dynamic dispatch). Tables/modules covered: 销售设计 `salsalesdesignmaster.sStates` (UpdateBackStates); 客户档案 `elecustomer` 13-field bulk profile edit (UpdateCustomer); 生产计划单 `mftproductionplanbillslave.sBackMemo` (UpdateBackMemo); 生产计划 `mftproductionplanslave.sMemo` (UpdatePlanMemo); 采购入库 `purpurchaseinstorededmaster.sBackMemo` (UpdateGYSFKBackMemo) + `purpurchaseinstorededslave.dMaterialsMoney` w/ tax-rate re-derive (UpdateGYSMaterialsMoney); 委外入库 `opsoutsideinstorededmaster.sBackMemo` (UpdateWXFKBackMemo) + `opsoutsideinstorededslave.dMaterialsMoney` w/ tax-rate re-derive (UpdateWXSMaterialsMoney); 产品报价 `eleproductpriceslave` 7-column quote-price + bNotUsed edit (UpdateNotUsed); 销售订单 `salsalesorderslave.sPMCReason` (UpdatePMC), `salsalesordermaster` 4-field (UpdateSalesMaster), `salsalesorderslave` 4-field + 翻单 reorder branch + cascade to `saldelivernotifyslave` (UpdateSalesSlave); 工艺变更 `mftprocesschangemaster.dPoorMoney` (UpdateProcessMaster); 工单 `mftworkordermaster.dMCostMoney` (UpdateWorkOrderMaster); 供应商档案 `elesupply` 11-field profile edit (UpdatesSupply); 物流单 `logisticsorderslave` proportional money-redistribution (UpdateLogSlavePrice); 质量事故 `mftqualityaccidentMaster` `sCheckMemo`+sCkPerson+tCKDate via degenerate cursor (BtnRepairUpdateCheckMemo) and `sJzMemo`+sJZPerson+tJZDate (BtnRepairUpdateJzMemo); 销售开票 `SalSalesInvoiceMaster.bSubCheck` 0→1 submit-for-review (BtnUpdate_InvoiceSubCheck). Flags: (1) `Sp_BtnRepair_UpdateSalesMaster` writes 4 fields unconditionally (no `IF(IFNULL(p_x,'')='',A.x,p_x)` guard) — blank dialog entries blank existing values, unlike its UpdateCustomer/UpdatesSupply/UpdateSalesSlave siblings; (2) `Sp_BtnRepair_UpdateNotUsed` uses `IFNULL(p_x, 0)` per price column — fields not entered in the dialog are reset to 0 rather than preserved; (3) `Sp_BtnRepair_UpdateBackMemo` has a debug stray `select aa from bb;` comment-line in declarations (harmless but flag for cleanup); (4) `Sp_BtnRepairUpdateCheckMemo`/`JzMemo` use a structurally degenerate cursor loop (cursor query already keyed on `sId=p_sId`) — the cursor adds the `sBrandsId/sSubsidiaryId` tenancy filter but the inner Update omits it; (5) all 19 BtnRepair procs lack `IF LENGTH(sProInParam) < 5` short-circuit + `paramsErro` Sp_Sis_GetConst error-return seen in the canonical `sButtonParam.sql` template — silent no-op on malformed input; (6) `Sp_BtnRepair_UpdateSalesSlave` has a commented-out cascade-to-`saldelivergoodsslave` block — the notify-slave cascade is live but the deliver-goods-slave cascade was disabled; (7) `Sp_BtnEventWorkPost_New` `iProcessColorQty = p_dAdjustProcessQty * (B.dCalcQty1 + B.dCalcQty2) * 0.001` — `0.001` divisor is hardcoded (likely g→kg or 1/1000 conversion factor); (8) `Sp_BtnEventWorkPost_New` source `script/标版/30100101/cost/Sp_BtnEventWorkPost_New.sql` is the only `Sp_BtnEvent*_New` install-script hit — most `_New` revisions are deployed via the live DB without checked-in source. |
| 2026-05-12 | 20 | 0 | 1155 | Pass 2 session 33 — `Sp_Calc_sDgn` → `Sp_Calc_sMat` (all 20 procedures, continuing the `Sp_Calc_s<Code>` audit/un-audit family). 12 substantive + 8 dormant/orphan. Substantive — all dispatched via `gdsmodule.sProcName` by Java `BusinessBaseServiceImpl.getPrcName(...)`: sDgn (送货通知单 + 材料送货通知单), sEmmt (设备维修), sEmr (设备报修), sEmt (设备保养登记 — back-writes plan slave), sEtp (设备保养计划), sExp (费用分摊 — tiny stub, missing already-checked guard), sFma (文件管理), sFtf (财务转账 — posts CahStockInvoice + CahWasteBook + SysLocking), sLok (物流对账 — posts CahPaymentables, refreshes CahSupplyInit), sLos (物流单 — back-writes saldelivergoodsslave; @author zhucx 2021-11-29), sMad (材料调拨 — paired stock movements on two modules 材料调拨单据 + 材料调拨(出)). Dormant/orphan: sDYDgd + sEmp (ship install scripts in 30100101/ but no live binding — duplicates of sDgd/sEtp-shape), sEtpCH (设备保养时间变更 — no script no binding), sFixe (固定资产 — no script no binding), sFksq + sFybx (byte-identical pair both auditing expensereimbursementmaster despite separate 付款申请/费用报销 labels), sFksq1 (newer paymentRequest variant — no binding), sInded (内部扣款 → flips mftqualityaccidentSlave; no binding), sMat (物料审核 — copy-pasted SalSalesOrderSlave workflow loop into a material-master audit; flag for review). Cosmetic COMMENT bug across many: `'商机跟进'` (sales-lead) copy-pasted onto unrelated 设备 / 文件 audits — purely descriptive, ignore. |
| 2026-05-12 | 20 | 0 | 1135 | Pass 2 session 34 — `Sp_Calc_sMaterials` → `Sp_Calc_sOpc` (all 20 procedures, continuing the `Sp_Calc_s<Code>` audit/un-audit family). 13 substantive + 7 orphan. Substantive — all dispatched via `gdsmodule.sProcName` by Java `BusinessBaseServiceImpl.getPrcName(...)`: sMaterialsBgd (材料变更单 — back-writes mftworkordermaterials + refreshes EleMaterialsStock), sMcd (材料盘点单据 — commits MitCheckProfitLoss + re-aggregates MitMaterialsStore/EleMaterialsStock), sMit (材料期初单据 + 材料期初 list — seeds MitMaterialsStore from MitMaterialsInitSlave), sMma (材料库存调整单据 — qty-side adjust on MitMaterialsStore), sMmm (材料存货调整单据 — value-side adjust on MitMaterialsStore, finance variant of sMma), sMpa (领料申请单据 + 补料申请单据 + 补版申请单据 — 3 MES modules share one Sp_Calc; back-writes MftWorkOrderMaterials + sgdsemigoodsmatchbillmaterials, logs kpidetail), sMpp (产品工艺模板 + 膜类工艺(模板) — master-only template lock), sMpt (产品工艺卡 — **bound on 9 sibling modules**: 轮转/丝印/膜类/套装/材料/预设 + legacy + PLM 工艺模板预设单 + 产品工艺卡; back-writes EleProduct/mftproductcontrol/salsaleschanceproduct/salsalesdevplanmaster — largest sibling cohort in family), sMsy (采购询价单 — back-writes elematerialssupply price/lead-time; header notes auto-audit-on-save), sOdt (发外检验单据 + 发外检验(mobile) — back-writes OpsOutsideProcessSlave/opsoutsidearriveslave with QC verdict), sOis (工序发外确认 + 发外报工(mobile) + 工序发外确认单据 — 3 modules; back-writes MftWorkOrderProcess advance + OpsOutsideInStoreMaster + QlyOutSideProductTestSlave + EleKnifeMould tool-return; xly-src ships an upgrade patch `20220126-2861-仓库冻结后，入库、领料、送货单不可消审/` and a `客户/千彩/` override), sOiv (发外发票 legacy + 发外发票(新) — posts CahPaymentables, KPI, reconciles OpsOutsideCheckingSlave; xly-src upgrade `20220104审核去除结账校验/`), sOpc (工序发外 + 整单发外 + 合格证登记 + 刀模外发单据 — **4 modules**; back-writes MftWorkOrderProcess + salsalesorderslave lock + EleKnifeMould tool-debit). Orphan: sMaterials (物料信息审核 master-only stub, no binding — companion sMaterialsBgd is the live one), sMft (新材料测试 — no binding, no xly-src), sMit1 (材料期初数据导入(财务) — install scripts only, no binding; `AccMaterialsInitMaster`-only finance-seed possibly folded into sMit), sModule (系统模块 save hook per header but not in live `sSaveProName` slot — likely moved to Java), sMpd (设计排版单 — install script only, no binding), sMpz + sMsc (新材料测试申请(品质) — duplicate sChinese, both unbound; family of 3 with sMft all dormant). Flags: (1) **`Sp_Calc_sOpc` `整单发外` module is bound with `Sp_Check_sOpp`/`Sp_beforeSave_sOpp` (sOpp prefix) but `sProcName` still points to `Sp_Calc_sOpc`** — mixed dispatch suffix; (2) **`Sp_Calc_sMpz` and `Sp_Calc_sMsc` share identical `sChinese='新材料测试申请(品质)'`** — likely one is renamed fork of the other; (3) **the entire 新材料测试 family (sMft/sMpz/sMsc) is dormant** — the live flow appears to have moved off these procs; (4) `Sp_Calc_sMpt` 9-module binding is the densest in family so far — eclipses `Sp_Calc_sMpa` (3) and `Sp_Calc_sOpc` (4); (5) `Sp_Calc_sMsy` header explicitly documents the auto-audit-on-save path; (6) `Sp_Calc_sOiv` legacy `发外发票` carries `Sp_beforeSave_sOiv` as **both** `sSaveProNameBefore` and `sDeleteProName` while the (新) variant is leaner — schema-evolution residue; (7) `Sp_Calc_sOis` has the most-forked deployment artefacts in this batch (4 xly-src locations including a customer-override at `script/客户/千彩/`); (8) `Sp_Calc_sModule` body could not be fully tabulated — DB connection dropped mid-read on body fetch (recoverable but flagged); (9) `Sp_Calc_sMpd` install script `script/标版/30100101/Sp_Calc_sMpd.sql` is present but module sId never bound — possibly retired in a schema migration. |
| 2026-05-12 | 20 | 0 | 1035 | Pass 2 session 39 — `Sp_Calc_sSpp` → `sp_CalcWagebyReport` (all 20 procedures, finishing the `Sp_Calc_s<Code>` audit/un-audit family and stepping into 3 cost-accounting `BtnEvent` siblings + 2 helpers + 1 wage-by-report BtnEvent). 11 substantive + 9 orphan. Substantive — all dispatched via `gdsmodule.sProcName` by Java `BusinessBaseServiceImpl.getPrcName(...)`: sStl (财务调整单据 — `CahFinancialAdjust` audit with SysLocking + bFrozen guard), sUdf (财务凭证单据 — `udfvouchermaster/slave` with expense-account 6601/6602 部门/费用科目 guard), sUdft (凭证模板单据 — `udfvouchertemplatemaster`), sWod (印刷工单 family — **22+ module bindings** for 生产工单/轮转/合版/丝印/柔印/数码/膜类/书刊/通用/套装/材料加工/实验/打样/制版/测试/印刷工作单 + 各类补单 + 2/3新增 variants + 兼容停用; back-writes mftproductionplan/MftProductMaster + reserves EleMaterialsStock/EleKnifeMould + may trigger Sp_System_CheckFlow + Sp_Bill_Used; **densest binding so far — eclipses sSod's 30 by going across the entire production-order family**; also called from sibling procs Sp_Calc_sBgd/sRct/sRcts/sRct_copy1; ships customer overrides at script/客户/金宣发/千彩/上海亚峰). BtnEvent dispatched by `GenericProcedureCallServiceImpl.doGenericProcedureCall()`: BtnEventCalcCost (业财一体化 / 成本核算 — full month-end cost-accounting run; updates mftworkordermaster.tFactCountCost + writes back to MftWorkOrderSlave/CotOrderCostAnalysis/EleProductStock/PitProductInStoreSlave; flips sysaccountperiod.bCost=1), BtnEventReCalcCost (mid-month re-cost legacy 封存 by 杨恒林 2021-09-20), BtnEventReCalcCost_new (current rewrite; guards on sysaccountperiod.bCalProducts=1 + later-period bCost=1; recalc only, no period close), sp_CalcWagebyReport (按上报计算工资 button — JSON-param dispatch, evaluates eleprocess.sConversionFormulaId via Sp_System_ReplaceField onto mftproductionreportemployee). Helpers: CalcAttribDate (生产管理/上报 helper — vesting-date attribution by shift cut-off; called by Sp_Calc_sPpr), CalcPlan_dHour (生产管理/排程 helper, 作者: 钱豹 — per-plan-row machine-hour calculator using elemachine.sAdjustableFormulaId via Sp_System_ReplaceField_Detail; called by Sp_Manufacture_InsertMftPlanSlave + Sp_Manufacture_SetTime). Orphan: sSpp (`Sp_Calc_s*` against salsalesprintplanmaster 印前计划 — comment 商机跟进 stale; 印前任务计划 actually uses sSdp), sStd (against QlyProcessTestMaster but comment 销售订单 stale — copy-pasted), sSuBJ (against PurPurchasesuppinquirymaster 采购询价单 — 采购询价单 actually uses sMsy), sSup (against elenewsupply 新供应商), sSupply (against elesupply 供应商 — neither sSup nor sSupply is bound; live audit handler is named elsewhere), sYear (against elematerialsyearmaster 年度单价), sYsTb (against departmentalBudgetMaster 预算填报审批), sYzfy (against advanceCostCheckMaster 预支费用审批), tice + tore (against eptmachinefixednoticemaster + eptmachinefixedinstoremaster — equipment fixed-asset notice/instore pair, comment 印刷工单审核 copy-paste stale; both miscased sCheckPersON). Flags: (1) **`Sp_Calc_sWod` 22+ bindings is the new family record** — covers the entire 生产单据 sub-tree including legacy/兼容停用 variants + 2-3新增 reorganisations + 打样/制版/测试 prepress side; (2) **9 stale COMMENT/sChinese descriptions** across sSpp/sStd/sSuBJ/sSup/sSupply/tice/tore — comment block looks copy-pasted from template without update; (3) **sUdf 6601/6602 expense-account guard**: 费用类凭证 lines are forced to include 部门 (sFflex5) + 费用科目代码 (sFflex9) — chart-of-accounts assumption hardcoded; (4) **sYsTb + sYzfy both have the sysaccountperiod.bFrozen guard commented out** in the deployed body — budget submissions and advance-expense audits can be applied to finance-closed periods; flag for finance maintainer; (5) **tice + tore both write to mis-cased `sCheckPersON`** (capital ON suffix instead of sCheckPerson) — case-sensitive collations would error; the rest of the system uses `sCheckPerson`; (6) **BtnEventReCalcCost is marked 封存 by 杨恒林 2021-09-20 but still deployed** — the `_new` variant is the active path; legacy presence is a re-cost rollback option; (7) **CalcAttribDate, CalcPlan_dHour are leaf-helpers** (no caller in dispatch slots), only called from sibling procs — they're worth narrating because the sibling procs do invoke them; (8) `Sp_Calc_sSpp` page comment says 商机跟进 but body targets prepress-plan master — likely a renamed/abandoned sibling; (9) `Sp_Calc_sSuBJ`, `Sp_Calc_sSup`, `Sp_Calc_sSupply` look like dormant duplicates of currently-wired audits — the live audit handlers for 采购询价/供应商准入 must be wired under different proc names; (10) `Sp_Calc_sWod` body is 167KB — by far the largest in the family and required body-summarization. |
| 2026-05-12 | 20 | 0 | 975 | Pass 2 session 42 — `Sp_check_productstoreLimitNew` → `Sp_Check_sMcd` (all 20 procedures, entirely from the `Sp_Check_s<Code>` post-save validator family — gdsmodule.sSaveProName slot dispatched by Java `BusinessBaseServiceImpl.checkUpdate(..., "sSaveProName")` after the save batch commits, per `CheckSaveServiceImpl.java`). 11 substantive + 9 orphan/dormant. Substantive — bound to gdsmodule.sSaveProName: sAcc (质量事故报告 + 设备异常单 + 新增质量事故报告 + 新增客户投诉单 — branches on sFormGuid for 不良品/外协扣款 rule battery), sCmt (材料检验 + 库存检验 + 材料检验mobile — cursor money/tax/qty back-calc with sComputeId/sReComputeId formulas), sCut (物料转换 — 红冲 guard via SUM dAuxiliaryQty pattern), sDgd (送货单 + 扫码送货 + 材料送货单 — money/tax/foreign-currency back-calc + 红冲 guard), sDgn (送货通知单 + 材料送货通知单 — same back-calc; bRemainderScrap guard; sCantChooseBfck), sLok (物流对账单 — opsoutsidecheckingslave money/tax recompute; script typo Sp_Check_ssLok.sql), sLos (物流单 — freight-cost proportional apportionment from logisticsorderdetails.dProductMoney across slaves), and the OEE pair Sp_Check_SaveOeeReport + Sp_Check_SaveOeeReportCheck (called from Sp_Calc_sPpr — both back-fill plc_machinedata aggregates onto mftproductionreportslave). Chain: Sp_Check_sDgda_phone is a thin PDA wrapper calling Sp_afterSave_sDgda_phone then forwarding to Sp_Check_sDgda (which itself runs barcode-warehouse propagation + 员工绑定 guard via Fun_Sis_GetConstNew('sDgdNotEmployee') + Sp_Check_dOraQtyTs over-issue guard). Orphan/dormant: Sp_check_productstoreLimitNew (next-gen inventory-availability gate using Sp_Sis_GetProductInventoryFormGuid — no caller anywhere), Sp_Check_QlyMaterialRule (sFormId='12012615914116374916774630' = 进料检验规则; eleteststandardobject dedup check — never bound), Sp_Check_sCio (no-op stub; peer Sp_Calc_sCio is bound but Sp_Check is not), Sp_Check_sFksq + Sp_Check_sFybx (付款申请/费用报销 advance-cost-check guards against advanceCostCheckMaster + back-fill sAccountNo from descriptionoffeesslave; both unbound — half-wired feature), Sp_Check_sLosTest (earlier draft of Sp_Check_sLos; called from Sp_Calc_sLos with the Test suffix; missing the bAheadComplete/single-tax/single-supplier guards added later), Sp_Check_sMad + Sp_Check_sMcd (材料调拨/材料盘点 — modules have sSaveProName='' but sProcName=Sp_Calc_sM*; likely invoked from the audit handler), Sp_Check_SaveOeeReportAAA (dev scratch copy with hardcoded sBrandsId='1111111111' test tenant). Flags: (1) **the Chinese description "保存之前数据校验" on every Sp_Check_s* page is misleading** — these are dispatched via sSaveProName which `BusinessBaseServiceImpl` runs AFTER the save batch commits (line 1824 `checkUpdate(..., "sSaveProName")`); the actual pre-save peer is `Sp_beforeSave_s<Code>` bound on sSaveProNameBefore (line 1778); (2) **Sp_Check_sMcd has an unqualified `sMaterialsId` reference** in the `dProfitLossPrice/dMaterialsPrice/dProfitLossMoney` assignment — should be `M.sMaterialsId`; probable bug producing wrong prices on multi-line 盘点s; (3) **Sp_Check_sLok install script is shipped as `Sp_Check_ssLok.sql`** (double s typo) — verify deployment scripts pick the right name; (4) **Sp_Check_sFksq and Sp_Check_sFybx both operate on `expensereimbursementmaster`** but the live 付款申请 form uses a different proc — these two are unbound and look like a half-wired feature; (5) **Sp_Check_sMad / Sp_Check_sMcd / Sp_Check_QlyMaterialRule have no gdsmodule binding** despite shipping install scripts — likely wired via customer overrides or invoked from the audit handler (Sp_Calc_sM*) rather than the save-checker dispatch; (6) **the OEE pair (SaveOeeReport / SaveOeeReportCheck) is called from `Sp_Calc_sPpr` not from a module hook** — the production-report audit handler explicitly delegates OEE back-fill; (7) Sp_Check_SaveOeeReportAAA's `sBrandsId='1111111111'` confirms the test-tenant sandbox convention. |
| 2026-05-12 | 20 | 0 | 871 | Pass 2 session 47 — `Sp_Create_sControlFaceNameTableThree` → `Sp_DaysaleSalesMan` (all 20 procedures, alphabetic continuation). 6 substantive + 14 orphan/dormant. Substantive — sp_btn_action-style (dispatched by `GenericProcedureCallServiceImpl.doGenericProcedureCall()` via form button binding): Sp_CTPPlanList_BtnEventFinished (出版完成 button on 待出版任务列表; flips bPublish on mftproductionplanslave), Sp_CTPPlanList_BtnEventFinished_cut (切版完成 sibling, flips bCut; reuses tPublishDate slot intentionally), Sp_Customer_BtnEventInvalid + Sp_Customer_BtnEventCancelInvalid (客户作废/取消作废 — flips elecustomer.bInvalid + writes syslog with sFormId='192116810111915048607109671'), Sp_customerclassify_BtnEventInvalid + Sp_customerclassify_BtnEventCancelInvalid (客户分类作废/取消作废 — flips siscustomerclassify.bInvalid + syslog with sFormId='11811781131121915196321754040'), Sp_CustomerComplaints_BtnRepair (内部质量投诉/客户投诉 报修/修复 button; flips mftqualityaccidentMaster.sType=3 + sCheckMemo via dynamic UPDATE). Form-bound report dispatches (`gdsconfigformmaster.sSqlStr`): Sp_Daysalecustomer (销售管理→销售分析(客户角度) form 192116811011016400861831491 — daily-sales 31-day pivot by customer from viw_salsalesorder; uses Sp_Outstanding_Query for paging), Sp_DaysaleSalesMan (销售管理→销售分析(人员角度) form 101801153119616636370835770 — twin keyed by sSalesManId joining SisSalesMan). Helpers in dispatch chain: Sp_Create_sControlFaceNameTableTwo + Sp_Create_sControlFaceNameTableThree (生产排程 拼版/折页 control-face descriptor expanders; called by `Sp_Create_sControlFaceNameTable` dispatcher when the descriptor matches the `A-B` or `A+B-C+D` patterns respectively; dispatcher itself called from `Sp_Manufacture_InsertMftPlanSlave` during 排程 row creation; Three delegates symmetric `2A+2B` to `Sp_Create_sControlFaceNameTableFive`). Orphan/dormant: sp_cs1 (developer one-shot replaying Sp_CalculationWages over 2022-07-01..2022-08-09 — hardcoded date window), sp_cursor_CardEdit + sp_cursor_CardEdit1 (replay Sp_elematerials_AfterUpdateCard_Edit over elematerials WHERE iAssort<3 — param-bearing + param-less twin variants), sp_cursor_test + sp_cursor_test1 (developer scratch/template — corrugated material card edit and eleteststandarditem.iOrder renumber; both labelled `/*Delcare a cursor*/`-style boilerplate), Sp_Customerlist_BtnEventCheck1 + Sp_Customerlist_BtnEventUnCheck1 (**封存 by author zhucx 2021-05-21** per header; 1级审核/消审 of elecustomer; replaced by the standard Sp_Check_*/`gdsmoduleflow` audit), Sp_DailyStatisticalReport (生产管理 产量日汇总 — rebuilds mftDaySumReport from mftproductionreportslave+employee; no live binding; only install script + monthly counterpart Sp_MonthlyStatisticalReport exists), Sp_DailyStatisticalSalary (生产管理 工资结算 month-scope; walks sissalarystructureplan.sCycle='1' rows and applies sFormulaId via Sp_System_ReplaceField onto mftpayrollstatementcalc + mftDaySumReport + mftproductionreportslave/employee; 3 install-script variants including doubled-prefix `Sp_Sp_DailyStatisticalSalary.sql` and customer override `script/客户/金九/`; no live binding). Flags: (1) **Sp_CustomerComplaints_BtnRepair name vs body mismatch** — name says 客户投诉 but updates `mftqualityaccidentMaster` (质量事故); the 客户投诉 form binds to it because internal-quality-complaint and customer-complaint share `mftqualityaccidentMaster` storage, but the proc name is misleading. (2) **`Sp_Customerlist_BtnEventCheck1/UnCheck1` author-comment explicitly marks them 封存 2021-05-21** but they're still deployed — leftover from a removed UI button; safe-to-delete candidate. (3) **`Sp_Sp_DailyStatisticalSalary.sql` (doubled prefix)** sits next to `Sp_DailyStatisticalSalary.sql` in 30100101/ — script-bundle typo; only the latter created the live proc. (4) **`script/客户/金九/Sp_DailyStatisticalSalary.sql`** is a customer-override path — the proc was once live for 金九 印务 but no longer hooked in the standard 30100101 deployment. (5) **the `sp_cursor_*` (4 procs) + `sp_cs1` (1 proc) cluster** is developer scratch / replay helpers — all parameterless or with hardcoded date windows, none in dispatch slots; flag for cleanup pass. (6) **`Sp_CTPPlanList_BtnEventFinished_cut` writes the cut timestamp into `tPublishDate`** (publish column) instead of a separate `tCutDate` — confirms a "most-recent-stage timestamp" design rather than per-stage timestamps; review if precise stage history is ever needed. (7) **`Sp_Create_sControlFaceNameTableThree` is the only variant without an install script in xly-src** — the dispatcher + variants One/Two/Four/Five all ship as `.sql`, but Three was apparently added later; deployment relies on the patched DB image. (8) **the 5 `*_BtnEvent*Invalid*` procs (Customer/customerclassify pairs + the Customerlist封存 pair)** all share the `sp_btn_action`-style JSON payload signature and live syslog write-back — confirms the standard ad-hoc invalidation pattern across master tables. (9) `Sp_Daysalecustomer` and `Sp_DaysaleSalesMan` both target seven specific sFormId values for `viw_salsalesorder` — these are the canonical 销售订单 form-variants in the catalog; useful reference for downstream reports. |
| 2026-05-12 | 20 | 0 | 1055 | Pass 2 session 38 — `Sp_Calc_sScd` → `Sp_Calc_sSpfu` (all 20 procedures, continuing the `Sp_Calc_s<Code>` audit/un-audit family). 12 substantive + 8 orphan. Substantive — all dispatched via `gdsmodule.sProcName` by Java `BusinessBaseServiceImpl.getPrcName(...)`: sScd (长期合同 — frame contract; back-writes quoquotationslave + seeds CahReceivables, KPI optional, full audit chain; 2 modules), sSck (销售对账单 — bound on 销售对账单据 plus 4 reused packaging forms 盒型定义/盒数据/盒型组件维护/自动拼版单据; writes-back upstream SalDeliverGoodsSlave/saldelivernotifyslave/SalSalesOrderSlave/MftWorkOrderSlave + CahReceivables + kpidetail), sScr (派车单 — back-writes saldelivergoodsslave with dispatch ref/date), sSdfu (开发跟进 + 印前任务跟进; writes-back salsalesdevplanslave + salsalesorderslave), sSdp (开发计划 + 印前任务计划 + 项目立项单据 — 3 modules; writes-back salsalesdevmaster + mftproductprocess), sSdv (开发申请 + 开发申请->开发计划 + 工单变更申请 + 项目评定 — 4 modules; writes-back salsaleschanceproduct), sSfu (商机跟进单据 — writes-back salsaleschancemaster + salsaleschanceproduct), sSgm (装配工艺卡 — writes-back sgdsemigoodsmatchprocess; **page comment 发外检验 mismatches body's sgdsemigoodsmatchmaster target**), sSiv (销售发票 — bound on 销售发票单据 + 销售发票明细; full AR chain with CahReceivables insert + CahCustomerInit/CahFinancialAdjust refresh + writeback to salsalescheckingmaster/saldelivernotifyslave/salrejectgoodsslave; flow-check, KPI), sSmb (装配工单 + 配墨工单; expands BOM into mftproductionplan + reserves EleMaterialsStock + MitMaterialsStoreVirtual + writes-back SalSalesOrderSlave; uses Materials_cursor), sSod (销售订单 — **30+ module bindings**: 销售订单(兼容停用) + 1/3新增销售订单 + 1/3新增轮转销售订单 + 轮转/丝印/膜类/套装/书刊/材料类销售订单 + 打样申请 + 项目申请(S-BOM) + 合版订单处理 + 印前文件处理 + 配送任务/配送记录/备货完成/备货记录/代收记录/配送预测 + 补货订单 + 异常待处理订单 + 工单任务预测 + 待交接订单任务 + 新材料测试订单 + 常规类销售订单测试功能; **densest binding in the family so far** — eclipses sMpt's 9 modules; also called from Java by `ErpOrderProcurementServiceImpl.doCallSsod()` on the auto-audit path for online orders + business-card orders, immediately followed by `doCallSsodAfter()`), sSodAfter (post-audit hook, **stub body** — exists for customer overrides; **Java-only invocation** via `ErpOrderProcurementServiceImpl.doCallSsodAfter()` after `doCallSsod()`, exceptions swallowed). Orphan: sScxl (数采下料 — Xfq_Working_record_lineMaster bCheck flip, no binding), sSmc (半成品盘点 — sgdsemigoodscheckmaster, no binding), sSmi (半成品入库 — sgdsemigoodsinstoremaster, no binding; install + optimize scripts only), sSmia (**page comment 装配工单 mismatches body's sgdsemigoodsinstoreapplymaster target**; no binding), sSmo (半成品出库 — sgdsemigoodsoutstoremaster, no binding; **page comment 装配工单 mismatches**), sSmoa (**page comment 装配工单 mismatches sgdsemigoodsoutstoreapplymaster**; no binding), sSodbecome (销售订单变更审核 — rich change-propagation body for SalSalesOrderbecomeMaster that writes-back salsalesordermaster/slave + mftworkordermaster/slave + saldelivernotifyslave/saldelivergoodsslave, but no live binding anywhere), sSpfu (**page comment 商机跟进 mismatches body's salsalesprintfollowupmaster target (打样跟进)**; no binding). Flags: (1) **`Sp_Calc_sSck` is reused on 4 packaging-related forms (盒型定义/盒数据/盒型组件维护/自动拼版单据) outside its declared 销售对账 scope** — the body's salsalescheckingmaster reads may silently no-op for those, or a customer override is in play; (2) **`Sp_Calc_sSod` has 30+ module bindings** including many compatibility-mode/legacy variants — single largest dispatch cohort in the catalog; (3) **5 procs have page comment ≠ body table**: sSgm (装配工艺卡 vs 发外检验 comment), sSmia/sSmo/sSmoa (sgdsemigoods*-apply tables vs 装配工单 comment), sSpfu (打样跟进 table vs 商机跟进 comment); (4) **`Sp_Calc_sSodbecome` body is rich but binding is missing** — either superseded by btn-event handler or pending re-wire; (5) **`Sp_Calc_sSodAfter` exists purely for the Java auto-audit path** (`ErpOrderProcurementServiceImpl.doCallSsodAfter()`), not the UI 审核 button — customer-override extension point with swallowed exceptions; (6) `Sp_Calc_sSod` body length is 69KB — by far the largest in the family. |
| 2026-05-12 | 20 | 0 | 831 | Pass 2 session 49 — `Sp_Do_UpdateByPageSizeBefore` → `Sp_Excu_Pro_RetOut` (all 20 procedures, alphabetic continuation). 4 substantive + 16 orphan/dormant. Substantive: Sp_Do_UpdateByPageSizeBefore (shared paginator helper called by ~10 sibling report procs Sp_BillOfNoPicking, Sp_Cashier_SumJournal, Sp_MachinePoweranalysis/SpeedAnalysis, Sp_Manufacture_ProductionArrange/Pro, Sp_mes_TeamQtyReported, Sp_Sales_SalesAnalysiseOfSalesperson, Sp_Manufacture_ProductionWorkCenter; PREPARE/EXECUTE dynamic-SQL builder for totalCount+countMapJson via temp-table aliased as A), Sp_Element_ProduceReportSum (生产管理→OEE管理→工资查询 — bound on gdsmodule.sProcName for 工资查询 + referenced from Fun_getInitColumnByProName; CbxMaterialsUnit-aware area calc; 4-mode rollup machine/process/team/employee through Sp_Outstanding_Query), Sp_EquipmentOutput_Machine (生产管理→生产运营报表→印刷产量达标率 form-master data source for elemachine.sMachineType=1 — per-shift planned-vs-actual rollup over mftworkorderslave/mftworkordercontrolslave/mftproductionreportslave; expands columns per day×班次 via Fun_get_show_config_*), Sp_EquipmentOutput_Machine_YH (生产管理→生产运营报表→印后产量达标率 — twin of `_Machine` scoped to `sMachineType<>1`; **comment header "印刷机台汇总达成统计" copy-pasted from sibling — flag for review**). Orphan/dormant (16): Sp_doFlow_opsProcess (workflow-apply contract signature, single UPDATE of `opsoutsideprocessslave.dQuotationPrice` from JSON payload — never wired to `gdsmoduleflow.sApplyProName`), sp_doTestGgf (`测试管智能华对接数据源过程` — boilerplate from xly's data-source-integration code generator with empty `业务处理部分`), Sp_elematerials_AfterUpdate (大型物料-master denormalizer: sismaterialsclassify-tree backfill of sOne/sTwoParentId/Name + cost-frame copy + 卷筒料 guard + 营销部 4-department classification whitelist + delegates to AfterUpdateCard — entire family unbound), Sp_elematerials_AfterUpdateCard + _Edit (corrugated-board 见坑 layer-loss/加工费 cursor with hardcoded P=1.03/B=1.05/A-flute=1.07 rates + ×1.25 for iAssort<>1 — Edit variant omits sMaterialsName overwrite), Sp_elematerials_BeforeUpdate (downstream-reference freeze guard against 10 tables mitmaterialsinitslave/mitmaterialscheckslave/QuoQuotationmaterials/mftproductmaterials/salsalesordermaterials/mftworkordermaterials/purpurchaseorderslave/purpurchaseinstoreslave/mitproductionmaterialsslave/mitmaterialsstoreadjustmentslave), Sp_elematerials_CheckUpdate + Sp_eleproduct_CheckUpdate (sftlogininfo.bJurisdictionShow-bypass freeze guards on `elematerials`/`eleproduct` main-table edits; eleproduct variant has **leftover "采购订单已生成，材料不能删除" copy-paste message bug** + uninitialized p_sCheckBillNo), Sp_elematerials_UpdateStyle (refactor extract of reel-stock-only-width guard from `_AfterUpdate`), Sp_eleteststandardFeed_BeforeUpdate + _First_ + _Patrol_ + _Product_BeforeUpdate (4 identical-shape uniqueness guards keyed by hardcoded eleteststandard.sFormId literals `'12012615914116374916774630'` (进料), `'12012615914116370215408310'` (首检), `'12012615914116374914703890'` (巡检), `'12012615914116374917672960'` (成品) — all authored as that form's sSaveProNameBefore but never bound), Sp_eptmachinemaintenance_Lader + _OEE (`维修后领导确认`/`维修后机长确认` grid-action button stamps on `eptmachinemaintenancemaster.bLeader/bCommand` — generic-procedure-call signature matches but no button event row exists), Sp_Excu_Pro_RetOut (`调用存储过程获取返回参数` developer scratch utility with the actual CALL half commented out, only the OUT-read PREPARE/EXECUTE remains). Flags: (1) **the 9 `Sp_elematerials_*`/`Sp_eleproduct_*`/`Sp_eleteststandard*_BeforeUpdate` cluster is one of the densest orphan blocks seen so far** — authored as the full pre-save/post-save validator suite for the 物料/产品/检验规则 base forms but the `gdsmodule.sSaveProName`/`sSaveProNameBefore` columns are empty on those modules; either tenant overrides supplied alternates, or this whole tier was abandoned. (2) **Sp_EquipmentOutput_Machine_YH reuses Sp_EquipmentOutput_Machine's "印刷机台汇总达成统计" COMMENT** — actual scope per binding is 印后. (3) **Sp_eleproduct_CheckUpdate has uninitialized p_sCheckBillNo concatenated into its error message** — clearly copy-pasted from materials guard and shipped half-edited; user would see literal `: ` with no bill name. (4) **Sp_Element_ProduceReportSum is the only ProduceReport family member to deploy via the generic Sp_Outstanding_Query/Sp_Do_UpdateByPageSizeBefore pagination wrapper** — most siblings use a direct dynamic-SQL path; this matters when troubleshooting 工资查询 performance. (5) **Sp_Do_UpdateByPageSizeBefore is the standard paginator helper used by ~10 report procs** — equivalent in role to Sp_Outstanding_Query but specifically the "temp-table → 20-row page" variant; both routes co-exist. (6) **Sp_Excu_Pro_RetOut has its CALL half commented out** — only the OUT-read half is live, confirming developer-scratch status. (7) **the four `Sp_eleteststandard*_BeforeUpdate` procs differ ONLY by the embedded sFormId literal** — strong candidate for a single parametrized validator if the family is ever revived. |
| 2026-05-12 | 20 | 0 | 791 | Pass 2 session 51 — `Sp_financialClosing_BtnEventCheckout` → `sp_getErpPlanData_before` (all 20 procedures, alphabetic continuation). 11 substantive + 9 orphan/dormant. Substantive — the `Sp_financialClosing_BtnEvent*` cluster maps to 系统设置 → 系统参数 → 财务结账 form sId 19211681019715761427895700 (form parented to gdsmodule 19211681019715761427873800 "财务结账"). All dispatched dynamically by `GenericProcedureCallServiceImpl.doGenericProcedureCall()` from toolbar buttons on that form: BtnEventCheckout (结帐 — calls Sp_financialClosing_BtnEventCalcMaterialPrice + Sp_Insert_EstimateInstore; refuses to close current month or with unfrozen prior period), BtnEventCheckoutCheckNew (异常核查 / 结帐前检查 — delegates to BtnEventCheckout_Check; coerces sCode=-1 back to 1 so dialog displays warning), BtnEventEstimation (本期材料暂估 — rebuild accmaterialsstore sFormId='192116810113315220315711060' from prior estimate + this-period purchase + 寄售仓 movements; resolves prices through 3-tier fallback), BtnEventExpense (自动提取凭证费用 — pulls voucher debits per cost-frame keyed by udfvoucherslave.sFflex9/sDepartId into accexpenseentrydepartmentmaster/slave + accexpenseentryworkcenterslave, runs Sp_System_CheckSaveFlowCps + Sp_Calc_sCps), BtnEventOutSideEstimation (发外暂估 — twin of Estimation on accordercostanalysis iType=7 + accoutsideproductstore), BtnEventProductStock_New (产品月结 / 产品存货核算 — ~50K-char body; rebuild accproductstore + accyfcyproductstore for the period via Sp_System_ProductCost_OutPrice), BtnEventReCheckout (反结帐 — 杨恒林 2021-05-23 封存 comment; clears EleMaterialsStockSumMonth/Month + eleproductstocksummonth/month + CotOrderCostAnalysis; sweeps dCostPrice/dCostMoney=0 across 11 master/slave bill tables; flips bFrozen=0). OEE: Sp_GET_OeeFistOneDataByMachineId (`OEE获取第一条数据` — bound via 3 Java call sites: `LoginController.userOeelogin()` for terminal bootstrap, `OeeServiceImpl` for service refresh, `OeeHandleServiceImpl` for the 上报 handler). Customer integration: sp_getErpPlanData_before (高旺 customer-specific SQL Server `lxfmac` push; called by `GwServiceImpl.tbsjCron()` — but the `@Scheduled` cron in `ScheduledTasks.tbsjCron` is **commented out**, so the integration is dormant). Helper: sp_get_sOppositeColor_data (JSON_TABLE deserializer for the opposite-side-color blob; only caller is sibling `sp_get_sOppositeColor`, itself orphan-by-grep — paired helper bundle). Orphan/dormant (9): Sp_financialClosing_BtnEventOutSideEstimation_new (staging rewrite of the OutSideEstimation proc — same shape, tab-indented format, no live binding), Sp_financialClosing_BtnEventOutSideEstimation_test (incomplete test sandbox — body truncated, only the temp-table population block present), Sp_format_column (DBA grid-column-width grooming tool over gdsconfigformslave/userslave; `COMMENT` "根据模块sId删除模块（包含子模块）" is a copy-paste bug unrelated to body), Sp_fstj_details (`放数统计明细-wx-12-17` — wx-customer-named report on viw_mftworkorderafterqty; no caller anywhere), Sp_Gb2Big_ChineseToBig (GB→Big5 localisation backfill across gdsmodule/gdsconfigformmaster/gdsconfigcharmaster/gdsconfigformslave/gdsformconst/gdsjurisdiction; manual DBA tool for HK/TW tenants), Sp_Generic_Procedure_Call (template skeleton — body is empty apart from `paramsErro` guard; explicitly NOT the runtime dispatcher), sp_get_salsal_order (`测试电商接口数据源过程` — 自定义接口 sample/template with inline `-- 温馨提示` developer hint), sp_get_unTodo + sp_get_unTodo_Apply (待办事项 widget data sources from biz_todo_item + biz_flow — no static binding but front-end Todo panel uses them dynamically through a non-`gdsconfigformmaster` channel; sp_get_unTodo_history references sp_get_unTodo), sp_getAllPartsName (sisproductclassify.sAllPartsName comma-split → dropdown options; `COMMENT '实际库存'` is a copy-paste bug — actual purpose is parts-name lookup). Flags: (1) **the `Sp_financialClosing_BtnEvent*` cluster is the canonical month-end close pipeline** — full sequence is: 异常核查 (CheckoutCheckNew → BtnEventCheckout_Check) → 自动提取凭证费用 (BtnEventExpense → Sp_System_CheckSaveFlowCps + Sp_Calc_sCps) → 本期材料暂估 (BtnEventEstimation) → 发外暂估 (BtnEventOutSideEstimation) → 产品月结 (BtnEventProductStock_New) → 结帐 (BtnEventCheckout → CalcMaterialPrice + Insert_EstimateInstore); 反结帐 (BtnEventReCheckout) rewinds the cost-price stamps and clears all four month-end ledgers. (2) **the OutSideEstimation `_new`+`_test` sandboxes**: `_new` looks like a near-complete reformat, `_test` is incomplete — neither is wired; either promote `_new` or delete both. (3) **`Sp_financialClosing_BtnEventReCheckout` has both `30100101/cost/` and `optimize/` install scripts** — performance-patched variant exists; verify which is deployed before changing. (4) **`Sp_Generic_Procedure_Call` is NOT the dispatcher** — that role belongs to Java `GenericProcedureCallServiceImpl.doGenericProcedureCall()`. The proc with this name is a per-developer template skeleton; the misleading name caused confusion. (5) **`Sp_Gb2Big_ChineseToBig` paginates `gdsconfigformslave` 1,000-row pages via a cursor** to avoid lock-table-size blowups — pattern worth copying for other tenant-wide UI-label sweeps. (6) **`sp_getErpPlanData_before` integration is dormant** — the `@Scheduled(cron="${gw.tbsjCron}")` stanza in `ScheduledTasks.java` is commented out; re-enabling sends 高旺 ERP plan rows to the customer's SQL Server `lxfmac` table. (7) **`Sp_format_column`, `Sp_Gb2Big_ChineseToBig`, `Sp_Generic_Procedure_Call`** all have misleading or stale COMMENTs — pattern of copy-paste comment without update across the DBA-tools / template cohort. (8) **`Sp_fstj_details` "wx-12-17" suffix** likely identifies a customer (wx) and a date — typical of one-shot customised reports that get forgotten in the catalog. (9) **`sp_get_unTodo*` are wired through a non-`gdsconfigformmaster` channel** — the to-do widget predates form-master and uses an internal registration path; static grep can't see them but they are very much live. |

| 2026-05-12 | 20 | 0 | 519 | Pass 2 session 65 — `Sp_OEE_ProductionReportAll` → `Sp_PC_FirstInspection` (all 20 procedures, alphabetic continuation). 13 substantive + 7 orphan/dormant. Substantive — form-master report data sources (`gdsconfigformmaster.sSqlStr`): Sp_OEE_ProductionReportAll (OEE管理→OEE本设备对应工序任务 form 101251240115016087809801980 — paged OEE 上报任务 list over mftproductionplanslave with CkxProcessFilter + Fun_GetLookProcess data-permission), Sp_OneDatePlan_Machine (生产管理→生产运营报表→机台计划达成日报 form 1921168137117916508762815480 — 白班/晚班 plan-vs-actual + 合计 row per elemachine; **hard-coded pageSize=18**), Sp_OutSideProcess_ProgressOfImplementation (外协管理→分析报表→外加工执行情况 form 19211681019715708477023400), Sp_OverdueNoCheck (销售管理→客户对账管理→超期未对账预警表 form 19211681019715708437112060 — overdue 对账 early-warning), Sp_OverdueNotReceivables (销售管理→开票&回款→超期未收款预警表 form 101251240115015879457139790 — overdue AR early-warning), Sp_Payables_AP (财务管理→应付账款→应付账款 form 192116810113315319067607260 — comment "应付账款 2025-12-30 新"; aggregates purchase-instore + outsourcing + adjust/return/payment streams + init-balance into INOUT dNoPayMoney/dDuePayMoney; also bound on 5 订单-付款明细表 sub-forms + 供应商流水账), Sp_Payables_APAccount (财务管理→应付账款→供应商流水账 form 192116810113315319144212730 — supplier ledger; delegates to Sp_Payables_AP body for the AP working table; iSum switches detail vs 汇总), Sp_Payables_APDetail (6 订单-付款明细表 sub-forms under 常用模块→常用设置: 采购 192116810113315319128813950, 付款 134212800, 调整金额 135996200, 调整票据 138829320, 退款 140301650, 开票 141949790; iSelect+iType routes to the AP-event variant), Sp_PC_FirstInspection (3 forms: 质量管理→过程质量控制(PQC)→首检任务列表 form 12012615914116372413380860 + 移动端管理→现场→功能操作→过程首检 form 12012615914116373903372280 + 印刷大检 101801153119616509369924030; **comment marks the body 封存 20211108**; restricts to mftProductionPlanSlave processes with EleTestStandard.sFormId=`12012615914116370215408310`; nested CASE/TIMESTAMPDIFF computes latest non-empty tFirstInspectionTime). Generic helper: Sp_Outstanding_Query (cross-module paginator/aggregator — 96 sibling routines hand it dynamic SQL + paging/grouping inputs; produces totalCount + countMapJson; COMMENT "未清存储过程查询、汇总、分页" — original 未清/未结 purpose generalised to most paginated reports). PLC integration: Sp_OEE_ScanInsertToERP (sealed 20210817 PLC scan ingester — called by Java `PlcToErpServiceImpl` in xlyPlc with `String splc="Sp_OEE_ScanInsertToERP"; call splc(sBrId, sSuId, sPlcAddr, sValues, ...)`; Siemens S7 scheduler synchronously executes per-machine), Sp_OEE_ScanInsertToERP2013 (variant with same `封存` marker; called from Sp_OEE_ScanInsertToERP as delegate path; same xlyPlc call site when deployment pins the 2013 variant). Pre-save validator: Sp_OpsOutsideprocess_CheckUpdate (成品外购 / 工序发外 save-time recompute — distributes dOtherMoney into dMaterialsPrice, refreshes tax-decomposed columns via sistax join, refuses with `该订单存在相同产品，单价不一致数据，请检查修改后重新保存！` when same sProductId resolves to multiple prices; called by sibling Sp_Check_sOpc + Sp_Check_sOpp gdsmodule.sSaveProName hooks). Workflow pre-flow: Sp_OpsOutsideprocess_CheckUpdate_ZF (变体 of CheckUpdate — header COMMENT "工序发外单据其它费用保存"; same recompute pattern; called from Sp_Check_sOpc). Orphan/dormant (7): Sp_OEE_SearchProductionReport (OEE quick-lookup of last 100 viw_mftproductionreport rows for sMachineId; small dynamic-SQL body; no caller anywhere), Sp_OpsOutside_Customer (per-customer 外发加工 money summary for date range over opsoutsideprocess*+elecustomer; no binding — likely superseded variant), Sp_Opsoutsideprocess_BtnEventConfirm (`Sp_BtnEvent_*`-shape JSON handler flipping bConfirm/tConfirmDate/sConfirmPerson on mftworkorderprocess+opsoutsideprocessslave joined via sWorkOrderProcessTbId; no caller — would have been wired to a 确认 toolbar button), Sp_OpsOutSideProcess_BtnEventFinished (`Sp_BtnEvent_*`-shape JSON handler flipping bExamine on mftworkorderprocess; parses but does not persist textareaValue; no caller), Sp_OutsideInspection_BtnRepair (`Sp_BtnRepair_*`-shape JSON handler marking 外协检验 lines iTestResult=2 with sExceptionMemo + dynamic valueKey-driven column update; no caller), Sp_Order_Scrap_Confirm_Flow (`流程启动前调用` pre-flow hook for OrderScrapConfirm 废品确认 workflow — sets bBfCheck on mftworkordermaster, deletes stale biz_flow/biz_todo_item rows for `type='OrderScrapConfirm'`, builds 会签 participant list via eleemployee/eleteam.sForemanId + 外发废 supervisor when dWastesQty6>0; no `gdsmoduleflow.sApplyProName` binding found — flow runtime row likely references it, verify). Flags: (1) **Both `Sp_OEE_ScanInsertToERP*` procs are marked 封存 in body COMMENT (`20210817`) but still survive** — the Java code in `xlyPlc/PlcToErpServiceImpl` still references the base name; verify which deployment is pinned to the 2013 variant. (2) **`Sp_OneDatePlan_Machine` overrides incoming `pageSize` to a hard-coded 18** — surprising for a paginated report; either intentional (one-page-per-shift report layout) or stale debug code. (3) **`Sp_Payables_AP` body comment `应付账款 2025-12-30 新` confirms a recent rewrite** — old body likely retained somewhere with `_old` suffix; verify before changing. (4) **`Sp_Payables_AP` is bound on 8 forms across 财务管理→应付账款 + 常用模块→常用设置** — single-procedure dense binding; changes ripple widely. (5) **`Sp_Outstanding_Query` is the catalog's widest helper (~96 callers)** — performance changes here affect almost every paged business report; treat as load-bearing. (6) **`Sp_PC_FirstInspection` 封存 marker but 3 live form bindings** — sealed-yet-deployed pattern same as the OEE ScanInsertToERP pair; deployment may have a successor proc that the form is currently routed to, but verify. (7) **`Sp_OpsOutSideProcess_BtnEventFinished` reads `$.changeValue.textareaValue` but never writes it** — the captured memo is parsed and lost; either a bug or the memo was intended for a slot that was later dropped. (8) **`Sp_Order_Scrap_Confirm_Flow` mutates both `biz_flow` and `biz_todo_item`** — typical workflow pre-launch hygiene pattern (delete stale instance rows before re-issuing); the `OrderScrapConfirm` type literal is the workflow-engine key. (9) **`Sp_OpsOutsideprocess_CheckUpdate_ZF` body is materially identical to `Sp_OpsOutsideprocess_CheckUpdate`** except for the `_ZF` variant's extra `dOldMaterialsPrice=0 when dMaterialsPrice=0` reset block — paired call sites in `Sp_Check_sOpc` (both) and `Sp_Check_sOpp` (non-ZF only) hint at a 转发/拆分 distinction; review whether keeping both is intentional. |
| 2026-05-12 | 20 | 0 | 499 | Pass 2 session 66 — `Sp_PC_PatrolInspection` → `Sp_PlanListQualificat_BtnEventCheck` (all 20 procedures, alphabetic continuation). 15 substantive + 5 orphan/dormant. Substantive — form-master report: Sp_PC_PatrolInspection (3 forms: 质量管理→过程质量控制(PQC)→巡检任务列表 + 移动端管理→现场→功能操作→过程巡检; 封存 20211108 comment in body but bindings live; computes tThisPatrolInspection via TIMESTAMPDIFF; state label 已首检/未首检/超期未巡检/N分内巡检/未到巡检时间). Scheduled backup: Sp_plan_mftproductionplanBak_daily (called daily by MySQL EVENT `sp_eventpro_day_machinedatabak`; snapshots mftproductionplan{,slave}+plc_machinedata into *bak with 12-month retention) + Sp_plan_mftproductionplanBak (parameterised cousin; only xly-src caller is a commented-out `CALL` in `Sp_financialClosing_BtnEventCheckout.sql` — effectively unused). 计划列表 toolbar `Sp_BtnEvent_*` family (dispatched by `GenericProcedureCallServiceImpl.doGenericProcedureCall()` — generic JSON-payload contract): Sp_PlanList_BtnEventInkingFinished (印油完工; UPDATE mftproductionplanslave SET dInkingMoney + dynamic valueKey columns), Sp_PlanList_BtnEventMouldFinished (模具完工; SET bMould=1, tMouldDate, sMouldPerson), Sp_PlanListCTP_BtnEventFinished (出版完工 generic + 3 narrower variants: `_Control` updates mftworkorderslave.bPublish+iPublishQty per workorder, `_Qty` writes iPublishQty/iUsePublishQty/sUsePublishType/iCTPStyle on plan row, `_UseQty` requires only iPublishQty; comment on `_Control` notes the per-workorder shift); Sp_PlanListCTP_BtnRepair (CTP-field cell-edit repair via dynamic valueKey UPDATE); Sp_PlanListCUT_BtnEventFinished (模切完工; SET bCut=1, tCutDate=now(), sCutPerson) + Sp_PlanListCUT_BtnEventFinishedFHQZ (反核 model: clear tCutDate/sCutPerson/bCut=0); Sp_PlanListMakeup_BtnEventFinished (拼版完工; SET bMakeup=1, tMakeup=NOW(), dMakeupMoney via dynamic builder) + Sp_PlanListMakeup_BtnEventFinishedfhpb (反核拼版: clear them); Sp_PlanListMasterials_BtnEventCheck (材料确认 via viw_salsalesdevplan→salsalesdevplanmaster.bCheck1) + Sp_PlanListMasterials_BtnEventUnCheck (反核 with refusal `品质部已审核，请先通知消审` when 品质部 bCheck=1); Sp_PlanListMemo_BtnRepair (`sManualNo`/`sDecompose` inline-edit on mftproductionplanslave; per-field guard so empty inputs are no-ops); Sp_PlanListQualificat_BtnEventCheck (合格审核 — UPDATE salsalesordermaster.bCheckQualificat=1; vestigial `@p_sIdTmp` resolution kept but unused). Orphan/dormant (5): sp_pitProductstoredata (printed-item store paged query over `PitProductStore`; no binding anywhere — likely abandoned draft of 未对账印件清单 fetch); Sp_plan_teamrate (速度嫁动率(分组报表)机台; only xly-src hit is `script/客户/朝阳/` customer override with a different `sDay`-first signature — DB has saas signature but no live form binding); Sp_PlanListMemo_BtnRepair, Sp_PlanListMasterials_BtnEvent{Check,UnCheck}, Sp_PlanListQualificat_BtnEventCheck — all carry the generic-dispatch contract but neither `gdsmodule` hook nor xly-src install script ship them; presumed wired by tenant-side form configuration. Flags: (1) **`Sp_PC_PatrolInspection` 封存 20211108 marker in body comment but 2 live form bindings** — same sealed-yet-deployed pattern as Sp_PC_FirstInspection in session 65 and the OEE ScanInsertToERP pair; sealed comments are not authoritative. (2) **`Sp_plan_mftproductionplanBak` is dormant** — its only xly-src reference (`Sp_financialClosing_BtnEventCheckout.sql:143`) is a commented-out `-- call`; the parameterless daily variant superseded it via the event scheduler. (3) **The `Sp_PlanList*_BtnEvent*` family has paired forward/反核 variants for CUT (`FHQZ`) and Makeup (`fhpb`)** — different suffixes for the same un-check semantic, hinting at independent authoring; either rename to a consistent `_Reset`/`_UnCheck` or document the suffix dictionary. (4) **Sp_PlanListMasterials_BtnEvent{Check,UnCheck} writes the secondary audit triplet `bCheck1/tCheckDate1/sCheckPerson1`** on `salsalesdevplanmaster` — separate from primary `bCheck`; the UnCheck guard refuses unless primary already cleared (`品质部已审核` message confirms the two-tier audit model: 品质 first, 材料 second). (5) **`Sp_PlanListQualificat_BtnEventCheck` resolves `@p_sIdTmp` via `viw_salsalesdevplan` but the subsequent UPDATE uses `p_sId` directly** — `@p_sIdTmp` is dead code; either remove the resolution or fix the UPDATE to key off it. (6) **`Sp_plan_teamrate` carries the saas multi-tenant signature in DB but the only xly-src copy is in `script/客户/朝阳/` with a different `sDay`-first signature** — likely promoted from a 朝阳 customisation, never wired to a saas form; verify whether it should be deleted or re-bound. (7) **`Sp_PlanListCTP_BtnEventFinished_Control` updates `mftworkorderslave` (workorder layer) instead of `mftproductionplanslave` (plan layer)** — its 3 siblings all update the plan row; the per-workorder makeup model needs a different target. Body comment `出版完成,后改为按照工单拼版` confirms the deliberate policy switch. (8) **Several `Sp_PlanList*_BtnEvent*` procs have no `gdsmodule.sProcName` binding in DB and no xly-src install script** — they're live in DB but the trigger linkage is tenant-side (front-end button config); the binding lives in form metadata, not gdsmodule. |

| 2026-05-12 | 20 | 0 | 399 | Pass 2 session 71 — `Sp_productionPlan_BtnEventAutoOrderSettime` → `Sp_productionPlanInfo_BtnEventCancelRelease` (all 20 procedures, alphabetic continuation). 13 substantive + 7 orphan/dormant. Substantive — full `Sp_productionPlan_BtnEvent*` toolbar family on the 生产排程 / 生管主计划 grids (`mftproductionplanslave` + `mftproductionplanslavelock`), all dispatched dynamically by `GenericProcedureCallServiceImpl.doGenericProcedureCall()`: Sp_productionPlan_BtnEventCnl (composite cancel-lock-and-recompute — calls Sp_productionPlan_BtnEventLockSd_cnl then Sp_Manufacture_SetTime), Sp_productionPlan_BtnEventLockSd (row-level lock — re-numbers iOrder of later locked rows to make room; uses `sNotChoose`/`sManufactureChooseMachine` constants), Sp_productionPlan_BtnEventLockSd_cnl (sub-step of BtnEventCnl — same body as LockSd but with the iOrder shift commented out), Sp_productionPlan_BtnEventAutoOrderSettime (按照锁定计划到货等排序 — called only by Sp_Manufacture_SetTime; builds two temp tables, classifies iOrderPlanType 1=locked/5=未评审/6=sState=3/else=2, rewrites iOrder for non-locked rows on the machine), Sp_productionPlan_BtnEventLock24Hour (锁定24H机台任务 — resolves current 班次 via FUN_GET_DATE_BC + elemachine.sWorkType/sShiftsWork/sOffWork, snapshots active-shift rows into mftproductionplanslavelock, logs to syslog with sFormId='19211681019715708440774010'), Sp_productionPlan_BtnEventLock24HourNotCalcTime (same as Lock24Hour but skips downstream time recalc), Sp_productionPlan_BtnEventLockrow (row-level move-to-confirm-table — copies selected sIds into mftproductionplanslavelock + sets bLock/bEmploy=1, sState=2; rejects with `sStandardWorkHourZero` when dHour=0), Sp_productionPlan_BtnEventLockrowNotCalcTime (Lockrow without time recalc), Sp_productionPlan_BtnEventunLockrow (inverse of Lockrow — clears bLock/bEmploy on the row + iAutoOrder=0 on sibling same-product unlocked rows at sState IN (0,1,2)), Sp_productionPlan_BtnEventunLockrowNotCalcTime (unLockrow without time recalc), Sp_productionPlan_BtnRepairdAjusthour (`Sp_BtnRepair_*` family — mass-writes dAdjustHour on all rows sharing sMachineId + sWorkOrderControlId; rejects with `chooseData` / `sProductionPlanChooseAdjustTime`), Sp_productionPlanInfo_BtnEventCancelRelease (`机台计划：取消下达` — per-row inverse of 下达; skips frozen rows with non-fatal sCode=1 and "冻结的单子已跳过" message), Sp_productionplan_ControlProcessNew (`+点击 / load-from-slave` expand handler for a 生产主计划 row — called by Java `WorkOrderPlanServiceImpl.getControlProcessList()` via `call Sp_productionplan_ControlProcessNew(...)` string concat; builds wide Productionplan_ControlProcess_Tmp temp table with process status tree from `eleprocess`/`mftproductionplan`/`elemachine`/`sisworkcenter`/`sgdsemigoodsmatchbillslave`). Orphan/dormant (7): Sp_productionplan_ControlProcess (older V1 of the load-on-demand 工序 tree; superseded by ControlProcessNew), Sp_productionplan_ControlProcess1 (paged variant with Sp_Outstanding_Query contract; no caller anywhere), Sp_productionplan_ControlProcessTrack (跟踪 variant — resolves sWorkOrderId via mftworkorderslave instead of mftproductionplan; no caller), Sp_Productionplan_Pie_Char + V10.1 (生成计划:卡片图 dashboard data-source for the per-工作中心 load cards; computes sLimitDate via DATE_ADD + dRate = d2HourSum / dStdWorkCenterHour; V10.1 adds an extra "发外" pseudo-row from Viw_OpsOutsideProcess — neither is bound in gdsconfigcharmaster/gdsconfigcharmaster0302, both candidates for audit), Sp_Productionplan_sColumnarStack_Char + V10.1 (生成计划:叠状柱形图 dashboard data-source — per-机台 stacked-column by state 已下达/已排程/已暂停/未排程; bFilter='0000000000' switches to a 发外 source from opsoutsideprocessslave; neither variant bound in chart tables). Flags: (1) **The whole `Sp_productionPlan_BtnEvent*` lock/unlock family has zero `gdsmodule.sProcName` binding** — wired entirely via the JSON-shape dispatcher contract and live tenant-side form metadata; install scripts ship in `script/标版/30100101/schedule/` but the toolbar-button → proc-name mapping is not visible to grep. (2) **`Sp_productionPlan_BtnEventAutoOrderSettime` is reached only indirectly** — caller is `Sp_Manufacture_SetTime` (which itself is called by `Sp_productionPlan_BtnEventCnl`); not dispatched directly from the UI. (3) **The `Sp_productionplan_ControlProcess*` cluster** — only `ControlProcessNew` is live (via Java caller); ControlProcess + ControlProcess1 + ControlProcessTrack are all orphaned variants. (4) **Both `Sp_Productionplan_Pie_Char` + `_V10.1` and `Sp_Productionplan_sColumnarStack_Char` + `_V10.1` lack any live chart binding** — `gdsconfigcharmaster.sProcedureName` does not reference them; they look like dashboard data-sources that were never wired into a chart row, or whose chart rows were deleted. (5) **`Sp_productionPlan_BtnEventLockSd_cnl` body is materially identical to `Sp_productionPlan_BtnEventLockSd`** except the iOrder-shift `UPDATE mftproductionplanslave SET iOrder = iOrder + (p_iMaxOrder - p_iOrder + 1)` is commented out — pair-of-near-duplicates pattern. (6) **`Sp_productionPlan_BtnEventunLockrow` clears `iAutoOrder=0` only for siblings on the same `sProductId`** — the lock-side `Sp_productionPlan_BtnEventLockrow` has the symmetric SET commented out, so the auto-order propagation is asymmetric across the lock/unlock pair. (7) **Sp_productionPlan_BtnEventLock24Hour writes `sFormId='19211681019715708440774010'` (生管主计划) into syslog regardless of which form actually triggered it** — likely stale audit-stamp; if the proc is also fired from the 生产排程 form the audit row will attribute it to 生管主计划. |
| 2026-05-12 | 20 | 0 | 379 | Pass 2 session 72 — `Sp_productionPlanInfo_BtnEventCancelZDDate` → `Sp_ProductProcess` (all 20 procedures, alphabetic continuation). 17 substantive + 3 orphan. Substantive — full `Sp_productionPlanInfo_BtnEvent*` toolbar family on the 生产排程 form (`mftproductionplanslave`, sFormId `101251240115016110217762400`), all dispatched dynamically by `GenericProcedureCallServiceImpl.doGenericProcedureCall()`: BtnEventCancelZDDate (取消指定时间 — UPDATE tZdDate=NULL), BtnEventCompletion (加工完成 — sState=5, iComplete=1, bProductionPlanComplete=1; refuses paused/frozen with localised consts; propagates bProductionComplete=1 to mftworkorderprocess via sSrcSlaveId join + syslog 加工完成), BtnEventCompletionRelease (取消加工完成 — inverse: sState=2, iComplete=0, clears flags + syslog 取消加工完成), BtnEventConfirm (确认日报 — stamps bAffirm/sAffirm on mftproductionreportslave + recomputes dAjustReportPlanHour via Fun_get_ReportDateByPlanIdAndDate), BtnEventOutProcessing (工序发外加工 — pushes residual qty to mftworkorderprocess.bOutside/dOutsideQty + shrinks mftproductionplanslave.dProcessQty to reported qty + freezes + deletes slave row when no report dependency; 胶印-specific 切纸-hide special-case), BtnEventRecommendMachine (使用推荐机台 — copies sTjMachineId→sMachineId via INNER JOIN elemachine+sisworkcenter; auto-bumps sState from 0→2), BtnEventRelease (下达 — sState=2,iAutoOrder=0; refuses sState∉{1,3} with sIssueOnlyPcOrPause), BtnEventRepairStartDate (修改开始时间 — UPDATE tStartDate from $.changeValue.tStartDate + syslog 修改开始时间), BtnEventResume (恢复 — sState=2 if SysSystemSettings.CkxXd=1 else 1; inverse of Suspend), BtnEventReturn (返回重排 — sState=0, sMachineId='', sMachineName=''; warns on completed/frozen/locked with sCode=1), BtnEventSuspend (暂停 — sState=3; refuses sState∈{0,5,3} with sPauseOnlyXd; OEE-notification path commented out), BtnEventUrgent + BtnEventUnUrgent (加急/取消加急 — UPDATE bUrgent=1/0 + syslog), CopyPlan (复制排程 — INSERT-SELECT 140+ columns with NewId() PK; refuses sType≠'2' and frozen; clone inherits source progress flags), Sp_ProductionReport_BtnEventComplete (强制完工 on 内部报工/发外报工 form — branches on SysSystemSettings.CbxProductionReport ∈ {workorder, plan} to update either mftworkorderprocess.bProductionReportComplete or mftproductionplanslave.bProductionReportComplete + tProductionReportDate; writes syscomplete audit rows via Fun_Sis_GetConstNew('sForceComplete'/'sForceClearReport'); a code-comment sample JSON appears in Java `CalcProcedureServiceImpl.getAddSql()`), Sp_ProductionReport_BtnEventConfirm (确认 on 报工 form — joint UPDATE of bConfirm/tConfirmDate/sConfirmPerson on mftworkorderprocess+mftproductionplanslave via sSrcSlaveId; second standalone UPDATE on plan-slave covers no-join case). Disabled/orphan/anomaly (3): BtnEventUnChange (intent: clear machine assignment like Return, but body always rejects with hardcoded '不能操作' before the real loop runs — temporary kill-switch flagged for audit), BtnEventExamineDate (推算审核日期 — opens cursor over mftproductionplanslave with ISNULL(tExamineDate)=1 AND dProcessQty<dProductionReportQty, but inner block contains only commented-out logic — stub awaiting implementation), Sp_ProductProcess + Sp_ProductProcess_BtnEventProductProcess (identical bodies: resolves salsalesordermaster.sId by sBillNo, sets salsalesorderslave.bStockupComplete=1; neither has the generic-dispatcher signature so neither is reachable via BtnEvent dispatch + no other-routine or xly-src callers — both orphaned; likely an abandoned refactor pair). Flags: (1) **`Sp_productionPlanInfo_BtnEventExamineDate` is structurally alive but inert** — cursor opens, increments, closes, with no actual UPDATE; same pattern as `planScriptTmp` from session 10. Either intentional stub or unfinished work. (2) **`Sp_productionPlanInfo_BtnEventUnChange` has unconditional sCode=-1 + LEAVE top before the real loop** — looks like a temporary disablement; the dead code path is the canonical reset-machine-assignment shape that `BtnEventReturn` already implements. Audit for removal or re-enablement. (3) **`Sp_productionPlanInfo_BtnEventCompletion` does NOT validate that dProductionReportQty>=dProcessQty before forcing sState=5** — operators can mark complete with under-reported qty (companion BtnEventCompletionRelease has no such check either). Whether intentional (allow supervisor override) or a missing guard depends on business policy. (4) **`Sp_productionPlanInfo_BtnEventOutProcessing` 胶印 special-case hardcodes process sIds `'1691254111216986535514820'` (current 胶印) and `'1691254111216986535514800'` (切纸)** — tenant-baked GUIDs; if a deployment cloned these sIds the hide-切纸 logic silently breaks. (5) **`Sp_productionPlanInfo_BtnEventOutProcessing` then `DELETE FROM mftproductionplanslave` for rows not referenced by MftProductionReportSlave** — destructive; if a row had any reported qty the prior step froze it (bFrozen=1), but the DELETE filter doesn't include bFrozen=1 in its WHERE — relies on the NOT IN subquery alone. Edge case worth a maintainer test. (6) **`Sp_productionPlanInfo_BtnEventCompletion` writes `iFormState=2` and `dOldProductionReportQty=dProductionReportQty` on close** — snapshotting at close-time; understand this when interpreting historical reports that diff dProductionReportQty against dOldProductionReportQty. (7) **`Sp_productionPlanInfo_BtnEventOutProcessing` UPDATE on mftworkorderprocess sets `bExamine=0`, `tPlanDate=NOW()`, `bNewOld=0` in addition to bOutside/dOutsideQty** — re-opens the process for examine flow; downstream Sp_Apply_Flow_ProcessTest path may re-fire. (8) **`Sp_ProductionReport_BtnEventComplete` uses `SysSystemSettings.CbxProductionReport` to switch between two completely different audit models (workorder vs plan)** — config-driven branch with materially different schema writes; ensure tenant configs are consistent across environments. (9) **`Sp_productionPlanInfo_BtnEventCancelZDDate` ID parse uses dash-delimited multi-id parameter `p_sId`** — same convention as the rest of the family; UI may send either a single sId or a dash-joined list. (10) **The `mftproductionreportslave.dAjustReportPlanHour` recomputation in `Sp_productionPlanInfo_BtnEventConfirm`** uses Fun_get_ReportDateByPlanIdAndDate (joining sSrcSlaveId+sTeamId+sMachineId+tCreateDate) — confirming a report effectively snapshots the planned-hour to a deterministic recompute; later schedule edits won't drift the audited number. |
| 2026-05-12 | 20 | 0 | 359 | Pass 2 session 73 — `Sp_ProductProcessPack` → `Sp_QlyProductJudge` (all 20 procedures, alphabetic continuation). 8 substantive + 12 orphan/dormant. Substantive — `sp_btn_action`-style JSON handlers (dispatched by `GenericProcedureCallServiceImpl.doGenericProcedureCall()`): Sp_ProductProcessPack (per-package "+1" counter on salsalesorderslave.dReturnTrunkQty; auto-flips bStockupComplete=1 when remaining reaches 0), Sp_ProductProcessPackAll (bulk-finishes the same field), Sp_ProductProcessWorkOrder (promotes mftworkordermaster.sStockup='1' + back-writes bStockupComplete=1 to every SalSalesOrderSlave consumed via MftWorkOrderSlave.sSrcSlaveId join), Sp_ProductReceipt (flips salsalesordermaster.sStockup='3' + stamps sSend/tSend), Sp_purchase_BtnEventReturn ("撤销无需采购" — clears mftworkordermaterials.bComMaterials/bPurchaseComplete/bPurchaseApplyComplete + syslog with sFormId='101251240115016110217762400'). Form-master data sources (`gdsconfigformmaster.sSqlStr`): Sp_PurchasePrice (采购管理→采购分析报表→采购主材比例浮动报表 form 101251240115016204641682560 — dynamic-column pivot per (sMaterialsId,sParentId)×date over viw_purpurchaseorder filtered sMaterialsType='paper'; uses nested cursors + `ALTER TABLE DT ADD COLUMN 日期MMDD`), Sp_purpurchaseorder_ProgressOfImplementation (采购管理→采购分析报表→采购执行情况 form 19211681019715708471237620 — 50-column execution timeline temp `p_TmpTb` joined to viw_purpurchaseinstore_tmp/viw_purpurchasereject/purpurchasecheckingslave/PurPurchaseInvoiceSlave/Viw_cahpayment; inline paging not Sp_Outstanding_Query). Helper called via routine chain: Sp_ProductStoreVirtual (印件-虚拟库存明细 rebuilder — reads SysSystemSettings.CbxDeliverGoods + CbxDeliverGoodsNotify to pick source mode salesorder/workorder/productinstore/delivernotify; called by 8 audit procs Sp_Calc_sDevApply/sDgd/sDgdCL/sDgd_1226/sDgd_20250612/sDYDgd/sScd/sSod) and Sp_PurpurchaseOrder_CheckUpdate (采购订单保存校验 — snapshots dOldMaterialsPrice/Money on purpurchaseorderslave; called by Sp_Check_sPod the save-validator for 采购订单 module 192116810113315217757747140). Orphan/dormant (12): SP_ProductStoreNowJN (江南-customer fork of Sp_ProductStoreNow — Tmp-table builder of multi-section product inventory snapshot; no caller in any channel), Sp_pur_purpurchaseorderOfSupply (per-supplier purchase summary; COMMENT '现金日记帐' is a copy-paste bug — body is purchase-order not cash-daybook), Sp_PurchasePriceChar (chart-JSON sibling of Sp_PurchasePrice emitting `{data:[...],xUnit,yUnit}` — sealed orphan; likely intended for gdsconfigcharmaster but no chart row references it), Sp_PurchasePriceChart (chart sibling — body **opens cursor over empty DT without populating it from T** — clearly broken; ALTER+UPDATE in the loop never fire; flag for deletion or repair), Sp_purpurchasearrive_CheckUpdate (采购到货 batch-number auto-fill keyed by SysSystemSettings.CbxMaterialsDefine — datenum/datetimenum/worknum/yearnum/yearmonthnum/createnownum branches; standard sSaveProNameBefore signature but binding missing on 采购到货(送检)单据 form 101251240115016068096930620), Sp_QlyComeMaterialsJudge (材料检验自动判断抽检及合格 — full AQL sample/judge with cursor over EleTestStandardItem; chains `CALL Sp_afterSave_sCmt`; no binding), Sp_QlyOutSideJudge (发外检验自动判断抽检及合格 — only fills sample/accept/reject thresholds, judging logic is commented out), Sp_QlyProcessTestJudge (工序检验自动判断抽检及合格 — **entire body commented out, no-op skeleton**), Sp_QlyProduct_BtnCalculate (成品检验 toolbar-button — generic-dispatcher JSON signature variant of Sp_QlyProductJudge; **leaves debug `SELECT p_sId,p_sSlaveId;` in body** which returns a stray result set), Sp_QlyProductJudge (成品检验自动判断抽检及合格 — single-row variant; fills sample/AC/RE + judges per-line 合格/不合格 + master roll-up), sp_Qlyoutsideproducttest_calculate (发外检验单据计算过程split — `sysbtncalctable`-style front-end-driven calc with sDropTableSql/sCreateTableSql/insertSql/selectSql; business block updates QlyOutSideProductTestSlave_calc_tmp via EleTestStandardItem band match). Flags: (1) **The Qly-Judge family (5 procs: ComeMaterials/OutSide/Process/Product/Product_BtnCalculate) all share the standard 自动判断 signature and reference EleTestStandardItem + per-target `*TestSlave/*TestMaster` tables but NONE has a gdsmodule binding** — strongly suggests dynamic-name dispatch from a Java handler that reads form metadata (not present in surveyed xly-src); audit candidate for the entire 5-proc cluster. (2) **`Sp_QlyProcessTestJudge` body is entirely commented out** — every UPDATE statement disabled with `-- `; effectively a stub for a deferred feature. (3) **`Sp_QlyOutSideJudge` and `Sp_QlyProductJudge` differ in completeness** — OutSide stopped after sample-band fill, Product continues with per-line 合格/不合格 set + master rollup; the two siblings look like incremental implementations of the same template. (4) **`Sp_PurchasePriceChart` is broken** — cursor opens over DT which is never populated from T (the missing `CREATE TEMPORARY TABLE DT Select Distinct…` from sibling `Sp_PurchasePriceChar`); the proc completes silently with no work done. (5) **`Sp_QlyProduct_BtnCalculate` ships a debug `SELECT p_sId,p_sSlaveId;`** that emits a stray result set to the caller — likely copy-paste during refactor from Sp_QlyProductJudge. (6) **`Sp_purpurchasearrive_CheckUpdate` writes `sCode=1, sReturn='保存成功！'` unconditionally** — even when no batch-number rule matched (no CbxMaterialsDefine row), so the success message is independent of whether any column was updated. (7) **`Sp_pur_purpurchaseorderOfSupply` COMMENT '现金日记帐' is a clear copy-paste bug** — body never touches any cash-daybook table; the proc is a per-supplier purchase summary. (8) **`Sp_ProductStoreVirtual` is the canonical virtual-stock rebuilder called by 8 Sp_Calc_s* procs** — its CbxDeliverGoods+CbxDeliverGoodsNotify two-tier SysSystemSettings branching is the source-of-truth for the 印件 delivery-flow source-mode logic; high-impact change point. (9) **`Sp_PurpurchaseOrder_CheckUpdate` has `_CheckUpdate` suffix and COMMENT '采购订单保存校验'** but the body is a back-write of dOldMaterialsPrice/dOldMaterialsMoney rather than validation — name vs body mismatch worth a doc note. (10) **`Sp_PurchasePrice` mutates the schema of temp `DT` at run-time** (`ALTER TABLE DT ADD COLUMN 日期MMDD`) — fragile under concurrent calls and against any column already present; flag for performance review. |
| 2026-05-12 | 20 | 0 | 259 | Pass 2 session 78 — `Sp_Sales_SalesAnalysiseOfCustomer` → `Sp_saleschanceToSop_BtnEventTodevelop` (all 20 procedures, alphabetic continuation). 13 substantive + 7 orphan/dormant. Substantive — form-master report data sources (`gdsconfigformmaster.sSqlStr` binding the literal proc name, no JOIN args): Sp_Sales_SalesAnalysiseOfCustomer (销售管理→销售分析(客户角度)→销售分析表(客户) form 101251240115015848397842351 — full sales-chain pivot per 客户: orders/instored/delivered/reconciled/invoiced/collected with no-tax-money columns; 7-sFormId 销售订单 whitelist), Sp_Sales_SalesAnalysiseOfCustomerClass (销售分析表(客户分类) form 101251240115015848398353901 — pivots by `siscustomerclassify`), Sp_Sales_SalesAnalysiseOfCustomerproperty (销售分析表(客户属性) form 101251240115015848399159370 — pivots by `siscustomerproperty`; carries known `group by EP.sParentId` mismatch in receipts subquery), Sp_Sales_SalesAnalysiseOfDay (销售分析(产品角度)→销售统计日报表 form 101251240115016215103304510 — daily pivot of sales/instore/delivery 不含税金额 by `eleproduct.sProductproperty` (`卡盒类`/`坑盒类`/`书刊类`/`胶片盒类`/`精品手工类`/`其他`); carton/box-industry taxonomy used as the standard 日报表), Sp_Sales_SalesAnalysiseOfMakePerson (销售分析(人员角度)→销售分析表(制单人员) form 192116811110216080102093540 — joins `sftlogininfo.sUserName` to `viw_salSalesOrder.sMakePerson` string), Sp_Sales_SalesAnalysiseOfProduct (销售分析(产品角度)→销售分析表(产品) form 101251240115015848397022101 — pivots by `eleproduct` + min/max `dProductPrice`), Sp_Sales_SalesAnalysiseOfProductClass (销售分析表(产品大类) form 101251240115015848407645250 — pivots by `sisproductclassify`), Sp_Sales_SalesAnalysiseOfProfit (成本管理→利润分析→销售利润分析-按客户 form 19211681019715708609753630 — three-layer profit (入库/送货/对账) per 客户; **swapped-target bug: in-store rate writes to `dDeliveryProfitRate` and delivery rate writes to `dInStoreProfitRate`**; marked `封存` 20210616), Sp_Sales_SalesAnalysiseOfProfit_Product (销售利润分析-按产品 form 101251240115016230550817050 — same shape but with extra `sProductId` axis; same target-swap bug), Sp_Sales_SalesAnalysiseOfSalesdepart (销售分析表(销售部门) form 101251240115015848401639221 — pivots by `sisdepart` via `sissalesman.sDepartId` lift), Sp_Sales_SalesAnalysiseOfSalesperson (销售分析表(业务人员) form 101251240115015848401113270 — pivots by `sissalesman.sSalesManId` with 订单/收款/对账/开票 columns; `COMMENT '现金日记帐'` is copy-paste artifact). Generic-dispatcher btn-event handlers (dispatched dynamically by `GenericProcedureCallServiceImpl.doGenericProcedureCall()` from the 商机机会/开发跟进 grid toolbar): Sp_saleschanceToSop_BtnEventTodevelop (转开发 — sets `salsaleschanceproduct.bDevelop=1, tDevelopDate=NOW(), sDevelopPerson, sDevelopMemo`; clears prior `sDevelopBackMemo`), Sp_saleschanceToSop_BtnEventDevelopBack (退回开发 — inverse: `bDevelop=0`, clears timestamp/person/memo, captures `sDevelopBackMemo` reason), Sp_saleschanceToSop_BtnEventDistribution (分配业务类型 — bulk-sets `sBussinessType` on selected lines; ships a debug `select p_changeValue,p_sBussinessType;` mid-flight). Orphan/dormant (7): Sp_Sales_SalesAnalysiseOfCustomer1old001 (predecessor of OfCustomer — tax-inclusive `dProductMoney` only; no `dProductNoTaxMoney` columns; the `1old001` suffix marks the snapshot; current form binds the newer no-tax variant), Sp_Sales_SalesAnalysiseOfMonth (generic monthly sales-pivot template with `iBillType`×`iClassifyType`×`iSum` switches across `Viw_MftWorkOrder`/`SalSalesOrderMaster`/`SalDeliverGoodsMaster`/`SalSalesInvoiceMaster`; no form-master binding, no proc caller — superseded by per-axis `Sp_Daysale*` procs), Sp_Sales_SalesAnalysiseProduct + Sp_Sales_SalesAnalysiseProduct1 (verbatim byte-for-byte duplicates — generic product-axis sales-pivot template with `iBillType`×`iClassify_type`×`iStatistics_type` switches; superseded by form-bound `Sp_Sales_SalesAnalysiseOfProduct`/`OfProductClass`), Sp_Sales_SalesAnalysiseProductOfMonth (generic product×month pivot template; carries typo `Set p_iStatisticsType = IFNULL(p_iStatisticsType, 0)` — references itself instead of input param, so `iStatisticsType` is effectively ignored), Sp_Sales_SalesDelivergoodsAnalysiseOfCustomer (per-customer 送货单 analysis hard-coded to single `sFormId='11811781131121915179924491520'`; never wired to a form; `COMMENT '现金日记帐'` is a copy-paste artifact). Flags: (1) **`Sp_Sales_SalesAnalysiseOfProfit` + `Sp_Sales_SalesAnalysiseOfProfit_Product` carry the same swapped-target bug** — `dInStoreProfitRate` and `dDeliveryProfitRate` are written by each other's UPDATE blocks. Marked `封存` in 2021-06 but still form-bound — user-visible numbers are wrong. (2) **The `Sp_Sales_SalesAnalysiseOf*` family hardcodes the same 7-sFormId 销售订单 whitelist** (`11811781131121915179702987440`, `101251240115015878710737470`, `101251240115015923020662710`, `101251240115016036176643130`, `101251240115016086186007360`, `101251240115016119059929270`, `101251240115016255652064530`) across 7 procs — adding a new 销售订单 form requires editing every analysis proc body. Tenant-baked GUIDs. (3) **`Sp_Sales_SalesAnalysiseOfDay` is product-property-bound to specific Chinese category names** (`卡盒类`/`坑盒类`/`书刊类`/`胶片盒类`/`精品手工类`/`其他`) — these are not in `EleProduct.sProductproperty` master data anywhere I queried but are filtered by literal string match. If a tenant uses different `sProductproperty` values the report silently shows zeros. Carton/box-printing-industry taxonomy baked into the proc body. (4) **`Sp_Sales_SalesAnalysiseOfCustomerproperty` joins receipts by `EP.sParentId` instead of `EP.sCustomerPropertyId`** — `dPayMoney` for the property report uses the parent-customer category not the property; either bug or deliberate cross-axis lookup. (5) **`Sp_Sales_SalesAnalysiseOfMakePerson` matches operator by `sftlogininfo.sUserName ↔ viw_salSalesOrder.sMakePerson` string** — fragile if usernames change between order creation and report run. (6) **`Sp_Sales_SalesAnalysiseProduct` and `Sp_Sales_SalesAnalysiseProduct1` are verbatim byte-for-byte duplicates** — explicit per-wiki-convention backup pattern, but neither is form-bound; should clarify retention policy. (7) **`Sp_Sales_SalesDelivergoodsAnalysiseOfCustomer` hard-codes a single `sFormId='11811781131121915179924491520'`** — looks like an early-customer-line 送货单 form that was never generalised; the proc has zero callers, the form is bound to something else. (8) **`Sp_saleschanceToSop_BtnEventDistribution` emits a stray `select p_changeValue,p_sBussinessType;`** mid-body — debug residual returns an extra result set to the caller. |
| 2026-05-12 | 20 | 0 | 159 | Pass 2 session 83 — `Sp_saveReturn_sSdp` → `Sp_SingleReceipt_BtnEventFinished` (all 20 procedures, alphabetic continuation). 17 substantive + 3 orphan/dormant. Substantive — the full `Sp_saveReturn_<code>` quantity-back-write helper family (9 procs), each wrapped by `Sp_beforeSave_<code>(iTag=1)` / `Sp_afterSave_<code>(iTag=2)` siblings that the `BusinessBaseServiceImpl` save-flow names by convention, re-fired on invalidate/delete via `Sp_Invalid_backwriting` / `Sp_delete_backwriting`: Sp_saveReturn_sSdp (开发计划 `salsalesdevplanmaster`→`salsalesorderslave.dSalesdevplanQty`), Sp_saveReturn_sSfu (商机跟进 `salsalesFollowUpmaster`→source quotation/order slave qty+money+loss+proofing+plate+knife+freight+remainder+phase), Sp_saveReturn_sSiv (销售发票 `SalSalesInvoiceSlave`→`salsalesorderslave` invoiced/gifted/remainder; **bound on gdsmodule 15780358080007074056281633539000 销售发票单据 via `sSaveProNameBefore=Sp_beforeSave_sSiv`**), Sp_saveReturn_sSmi (半成品入库 `sgdsemigoodsinstoreslave`→`MftWorkOrderSlave`), Sp_saveReturn_sSod (销售订单 `salsalesorderslave`→`quoquotationslave`; **bound on 101251240115015878710737470 1/3 新增轮转销售订单 + 101251240115016086186007360 1/3 新增销售订单**), Sp_saveReturn_sWod (生产工单 `MftWorkOrderSlave`→source order slave; **bound on 101251240115015840916341460 轮转工单, 101251240115016002469445380 生产工单, 101251240115016098136660960 2/3 新增生产补单**), Sp_saveReturn_sWXKK (外协扣款 `opsoutsideinstorededslave`→`mftqualityaccidentmaster`), Sp_saveReturn_tice (回厂通知单 `eptmachinefixednoticeslave`→`eptmachinefixedorderslave`), Sp_saveReturn_tore (固定资产入库 `eptmachinefixedinstoreslave`→`eptmachinefixednoticeslave`). All share the same body shape: comma-split `sGuid`→`p_t_sId` temp, JOIN to find `sSrcSlaveId`, aggregate per-source through `p_MftworkOrderSlave_tmp` (qty/money/loss/proofing/plate/knife/freight/remainder buckets) with `iTag` toggling include/exclude of the current save-set, UPDATE upstream. Generic-dispatcher btn-event handlers (dispatched by `GenericProcedureCallServiceImpl.doGenericProcedureCall()`): Sp_SetUpSubjectAssociate (科目设置 → propagates `sissubject.sSubject1..6, sThirdNo` from a selected row to every other `sissubject` row sharing the same `sFormId` where the slot is empty), Sp_SingleReceipt_BtnEventFinished (移动端管理→现场→功能操作→送货回执 — 确认回执 → `UPDATE saldelivergoodsslave SET bSingleReceipt=1, tSingleReceipt=NOW(), sSingleReceipt=sMakePerson, dSingleReceiptQty=dProductQty`), Sp_SingleReceipt_BtnEventAbnormal (异常回执 sibling — dynamic UPDATE on `saldelivergoodsslave` driven by `$.changeValue.valueKey` field-list + `textareaValue` memo). Form-master + Java-dispatch hybrid (4 procs): the `Sp_share_*` 分摊 family on AR/AP forms — Sp_share_sPay (付款单(汇总)分摊 — `cahpaymentmaster/slave/sumslave`), Sp_share_sPay_One (付款单分摊 row variant — `cahpaymentmaster/slave`), Sp_share_sRcts (收款单(汇总)分摊 — `cahreceiptmaster/slave/sumslave`), Sp_share_sRcts_One (收款单分摊 row variant — `cahreceiptmaster/slave`), Sp_share_salsalesinvoices_One (发票分摊 — `salsalesinvoicemaster/slave`). All accept the 4-string dynamic-SQL contract (`sDropTableSql`/`sCreateTableSql`/`insertSql`/`selectSql`) + `sFormGuid`, materialise `<table>_calc_tmp` temps, perform share/round arithmetic, SELECT back. Dispatched dynamically by `CalcProcedureServiceImpl.calc()` (POST `/calcprocedure/calc`) reading `sProName` from the form-config. Orphan/stub/dormant (3): Sp_saveReturn_sStl (`COMMENT '客户审核反写'` — body only parses sGuid into temp then exits; no UPDATE, no wrapper, no caller — looks like an abandoned slot in the family), Sp_ScanPicking (`COMMENT '扫码入库'` — validates `pitproductbarcode` label and returns its derived `sSqlConditionId` for matching; no DB/Java caller found despite a 30100101 install script — likely mobile/scan endpoint that dispatches by string), Sp_sendEmail_before (`COMMENT '发送邮件模板'` — documentation example showing how to INSERT into `syssendemail` queue; ships hardcoded sample addresses + report id + work-order number `SZPM22070353`, no input params for caller customization, no caller found — should live in docs not as a callable proc). Flags: (1) **The `Sp_saveReturn_*` family is reached only by string-convention dispatch** — `BusinessBaseServiceImpl` composes `Sp_beforeSave_<sCode>` / `Sp_afterSave_<sCode>` per form `sCode`; only sSiv/sSod/sWod have explicit gdsmodule bindings to the wrappers, the other 6 (sSdp/sSfu/sSmi/sWXKK/tice/tore + the stub sStl) rely entirely on convention. Adding a new save-back-write requires both the proc and the form-code naming alignment. (2) **`Sp_saveReturn_sStl` is the only proc in this batch with no body work** — the standard family has nine working members + one empty stub; flag for deletion or completion. (3) **`Sp_sendEmail_before` is documentation shipped as a callable proc** — has zero input parameters, hardcoded sender/recipient/report-id, and lives in `script/标版/upgrade/更新WAR脚本/20230210_消息、工作流、定时 模块/` — any caller would email a fixed test address; should move to docs to prevent accidental invocation. (4) **The `Sp_share_*` 分摊 family relies entirely on Java building the four temp-table SQLs** (`sDropTableSql`/`sCreateTableSql`/`insertSql`/`selectSql`) via `CalcProcedureServiceImpl.getAddSql()` — the proc body assumes those SQLs reference `<table>_calc_tmp` literal table names; renaming any participating table requires touching both Java and proc. (5) **`Sp_SingleReceipt_BtnEventFinished` has a customer override** at `script/客户/千彩/Sp_SingleReceipt_BtnEventFinished.sql` — tenant-specific behaviour; check which deployment is using which version. (6) **`Sp_SingleReceipt_BtnEventFinished` accepts the full `dProductQty` as `dSingleReceiptQty` with no per-line override path** — confirms the entire delivery line, can't partially receive (the Abnormal variant uses `$.changeValue.valueKey` for per-field overrides which is the only way to record a partial). (7) **`Sp_share_sPay` references `INFORMATION_SCHEMA`** in its body — likely for column metadata lookup; performance-sensitive on schemas with many columns, worth confirming the query is filtered tightly. (8) **`Sp_ScanPicking`'s COMMENT '扫码入库' vs body** — the body doesn't actually do an in-store update, only validates the barcode and selects attributes; the COMMENT may misdescribe its role (it's a pre-validation step in a multi-call mobile flow, not the actual put-away). |
