/** * A3 寻源询价的案例模型 —— **双表示同版本**:CMMN XML(机器面)与案例说明书(叙事面)。 * * 业务出处:`docs/MVP示例工作流.html` §1.7,按 **MVP 简化口径**建模 * (2026-08-02 用户定:A3 与 A2 同为复杂活动,MVP 期间不展开大规模业务建模): * * 上游(A2 的询价受理清单,或 A1 直达的 B 类受理记录)进来 → 归一成 * **目标报价清单**底表,A 类行按库内历史价预填基准 → **一张执行单**让采购(PRM) * 在系统外完成询价、把 B 类行的货源价格填回来 → 汇稿定盘 → 放行, * 整份目标报价清单交给成本定价。 * * SOP 里接需核史 / 选渠定策 / 发询比价那几段的实质工作(圈渠道、发函、催回价、 * 验价)在 PRM 系统外;四种场景(BOM早期/后期/现货/样品)的尺度之分是他的判断, * 不是系统的步。系统的本分:归一、预填、组卡、齐检、留痕。 * * 上一版(@2.0.0)只有「派单 + 放行」两项,入参必填 `pn + scenario`(单料形状, * 与上游发的整份清单对不上),两条 L2 判据读活动自报数。这一版整个置换。 */ export const CMMN_XML = ` update quote_line_total > 0 and quote_sourcing_quote_list_rows = quote_line_total and hist_priced_total >= 0 update sourced_total >= 0 update route_decided_total > 0 and quote_sourcing_quote_list_rows > 0 and quote_sourcing_quote_list_missing = 0 and quote_sourcing_quote_list_price_basis_hist + quote_sourcing_quote_list_price_basis_sourced = quote_sourcing_quote_list_rows `; /** * 案例说明书 —— **只写整单一以贯之的事**(逐步做法归剧本,两处不重复写同一件事)。 */ export const NARRATIVE = `§0 开案:**一份清单要补齐每一行的价格基准**。来路三种,形状都收(宽进): · **选型转来**:任务数据里有 \`rows\` 数组 —— 替代选型放行的全部落地行混在一起 (带 alt_pn / 现标的是清单行,带各种总数的是结论行,按 PN 归并自辨); · **受理直达**:有 \`records\` 数组 —— 受理放行的落地行(受理记录行 + 分类表行 + 结论行); · **单飞**:只有一段需求文字,列了几颗料要问价。 **这个活动是复杂活动的 MVP 简化形**:询价的实质工作(圈渠道、发函、催回价、验价) 由采购(PRM)在**系统外**完成;四种场景(BOM早期/后期/现货/样品)的尺度是他的判断。 系统只负责:归一清单、**A 类行按库内历史价预填基准**、把执行单组好交给他、 收回后齐检定盘。 **成品只有一样**:一份**目标报价清单** —— 整份行都在、**每一行都有基准价** (A 类取历史价,B 类取 PRM 问回来的货源价),价源逐行可溯。它是成本定价的直接输入。 **这一单要经过人两次,不多不少**:PRM 在执行单上补货源价(那张单绑着整份清单, 必填空着按不下提交 —— 基座的闸看着,他改的格子也直接落账)、放行时 PRM 签字。 【一路上要说话】负责人正看着这一单。**每一拍都带一句 say** —— 说业务的话: 哪几颗料等着问价、历史价预填了几条、这单接下来到谁手上;不说系统词。 到了要找人的那一拍,先说清这一轮办完了什么、为什么现在需要他。 【怎么把一项干完 · 一拍连做】write 和 tool 都不会自动收步 —— 做完用 finish 宣告。 动作排进同一拍的 actions 串一口气给;只有调工具(出参下一拍才看得见)与 发卡 / 提交(挂起)必须停拍。**这一单常路 6-8 拍就该收口**。 §Z 结案:PRM 在验收单上签字,系统把草稿合并成正式清单并发出 quotation 口的载荷 —— 整份目标报价清单交给成本定价。`; /** * 步骤剧本 —— 一个计划项一条;`doneWhen` 是「成果已存在」的判据,不是「该不该做」。 */ export const SOURCING_STEPS = [ { item: 'S1_normalize', intent: '上游清单整份归一成目标报价清单;A 类行按库内历史价预填基准', writes: ['quote_sourcing.quote_list', 'quote_sourcing.verdict'], /* 上游载荷数组不声明就会被整表段的截断刀砍掉(按字符截,砍掉的恰是要归一的行) */ reads: ['rows', 'records'], /* 归一预填与 PRM 补价期间摆**询价工作单**;汇稿定盘后才换收口那张清单 */ view: 'sourcing-worksheet', tools: ['crm.history-price-read'], /* * 归一 + 预填两轮都走完才算办完:行数两边对上,且 hist_priced_total 写过 * (没有 A 类就是 0;S-FEEL 未绑定的名字参与比较为假,所以「没写过」进不来)。 */ doneWhen: 'quote_line_total > 0 and quote_sourcing_quote_list_rows = quote_line_total and hist_priced_total >= 0', guide: `第一件事:把这一单的**目标报价清单**落出来,并把 A 类行的基准价预填好。 【料从哪儿来】 · 选型转来(有 \`rows\`):清单行带 pn / alt_pn / type_tag(现标)—— 照抄; 带 alt_line_total 这类总数的是结论行,不是料,别落进清单。 · 受理直达(有 \`records\`):受理记录行(带 eau/brand)为准,type_tag 照抄; 分类表行与结论行不落。**按 pn 归并**,一颗料一行。 · 单飞:照正文归一,列了几颗落几行;没说类别的按 B(要问价的料本来就是 B)。 【第一拍:只做两件事 —— 落清单行 + 串尾发一次查价】 ① 写 \`quote_sourcing.quote_list\`,一颗料一行(rows 收数组): pn(**一个字符不许改**)、customer_pn、category、brand、eau、target_price、lead_time、 **remark(客户备注:认证要求、预授权、急料标注 —— 问价口径的第一手依据,一个字别丢)**、 alt_pn(上游有就承继)、type_tag(照上游现标;单飞按 B)。 supplier / base_price / moq / source_lead_time / note **全部留空** —— 价还没来。 ② 串尾调 \`crm.history-price-read\`:pns 收数组,把 **A 类行的取价对象**一次传完 —— **取价对象 = alt_pn 有值取 alt_pn,否则取 pn**(选型转来的 A 行,行情稳的是替代料)。 **这一拍不写 \`quote_sourcing.verdict\`,一列都不写** —— 尤其 hist_priced_total: 它是「预填走完了」的凭据,提前写等于把闸提前打开,引擎会在下一拍开头当场收掉这一步, **预填从此不会发生**(实测:A 类行底价空着、执行卡照发,而交代里说着「已预填」—— 台账与嘴对不上)。没有 A 类行也一样:查价那一步省掉,直接进第二拍。 【第二拍:预填 A 行基准 + 记账 + 收步,一拍连做】 ① 工具出参逐行照抄:hit=true 的 A 行写 base_price = lastPrice、price_basis 写 **HIST** (大写,一个字母不许差 —— 基座按值现数,写别的数不出来)、note 记一句 「库内历史价 天」;hit=false 的 A 行**别编价** —— base_price 留空, 当 B 类待询处理(pending_total 把它数上;type_tag 不动,那是上游的标)。 ② 这时才写 \`quote_sourcing.verdict\`(一次写全):rfq_ref(入参有就原样抄, 没有从主题认,认不出才造「SRC-<型号或类型>」,从头用到尾。 **只从本单来件取材,不许从台账里已有的别单单号里挑** —— 正式表里躺着的 MD14.1 之类是别人的单,借它的号等于把两单的行混进同一个案卷)、 customer_code / customer_name(顶层有就抄)、**quote_line_total** = 清单行数、 **pending_total** = 底价还空着的条数、**hist_priced_total** = 刚预填的条数(0 也要写)。 ③ finish 这一项。`, }, { item: 'S2_fill', intent: '一张执行单交 PRM:照询价工作单在系统外询价,供应商与底价就地填回', writes: ['quote_sourcing.verdict'], reads: ['quote_sourcing.quote_list'], view: 'sourcing-worksheet', tools: [], /* 不给 doneWhen —— 发卡触达真人(manualActivation),引擎不替人按 */ guide: `清单归一好、A 类基准预填了,**该 PRM 出场了** —— 这是本活动唯一的一张执行单。 工作区摆的是**寻源询价工作单**:逐颗待询料的询价档案(要素/取价对象/客户约束)、 按场景圈渠道的规则、价格验证的尺、发询纪律与时限,填回区就长在上面。 这一步标了人工激活:发卡就算启动,不必单发 start; 引擎也不会替你收 —— 人交回后要你自己 finish。 【照这个骨架发,别少字段】(卡面是纯文本,steps/standard 里**别写星号记号**): {"kind":"human","itemId":"S2_fill","workOrder":"execution","card":{ "title":"寻源补价:<单号> 待补价 颗", "ask":"清单里底价空着的行要补货源价格:请照工作单上的场景规则在系统外完成询价,把供应商与底价填回表里对应行;MOQ、货源交期、备注能问到就一并填。", "steps":["底价空着的行是本单要问价的料 —— 每行必须补上:供应商、底价(未税单价按内部口径归一);取价对象是替代料一栏有值的取替代料,否则取原型号", "圈渠道按场景走(细则见工作单):BOM早期与样品可放宽;BOM后期按主供应商、备选、贸易商的顺序圈两三家,贸易商尽量不用;现货只选有库存实拍的供应商", "回价登记一一对应不可缺项:价格、MOQ、交期能问到就填;验价按场景的尺核过再采,不实回价或远低行情的换渠道补询,别直接采用", "确实问不到价的料,先与负责人商定:在件上把那一行撤掉(剔出本轮),或按内部估价填并在备注写明;A 类行已按库内历史价预填,可校可改"], "standard":"每一行都有基准价与价源可溯,渠道与验价按场景的尺走过 —— 底价缺一行,这张单按不下提交(系统的闸看着)。", "basis":[{"k":"<待补价 PN>","v":"<类别与年用量 + 客户约束(认证/急料),取价对象标明>"}]}} · \`basis\` 逐条列待补价的料:PN + 类别/年用量。几颗写几条,别铺全表。 · **卡上不摆表、不摆格子**(2026-08-02 用户定:填写全在工作区):整份清单就在 工作单那份件上,供应商/底价/MOQ/货源交期/备注五列都能就地改、行能撤 —— **别往卡里塞 \`blocks\` 或 \`fields\`**,塞了就是同一张表摆两处。 · **这张卡带提交闸**:底价(必填列)还空着,他按不下提交 —— 缺几格、缺在哪行, 闸上与件上的红带都写着(与放行门 L1 同一个数同一套算法)。 发完卡这一拍就结束了(发卡挂起)。 【人交回之后 —— 件上的值基座已经替你写回了】他在件上按「保存」那一刻改动就落进了 草稿层,按「提交」只是把卡交回来。你只做两件事,然后 finish: ① 清点原本底价空着、现在有价的条数,把 **sourced_total** 写进 verdict (他在件上撤了行也算处置过,照实清点;0 也要写); ② 别再 write 那些行 —— 值没变的写入会被「写了等于没写」拒回。 【这张卡一单只发一次】人交回来之后不许再发同一张卡 —— 必填有提交闸兜着, 卡回来时底价一定是齐的(或那几行已被他撤掉)。`, }, { item: 'S3_compile', intent: '价源逐行归档,齐检定盘:目标报价清单成稿', writes: ['quote_sourcing.quote_list', 'quote_sourcing.verdict'], reads: ['quote_sourcing.quote_list'], view: 'sourcing-roster', tools: [], /* * **收步判据与验收判据同源**:每行有价(基座按 required 现数)、价源守恒 * (基座按值现数)、定盘记账 —— 三样齐才收,松出来的那一截就是返工。 */ doneWhen: 'quote_sourcing_quote_list_missing = 0 and quote_sourcing_quote_list_price_basis_hist + quote_sourcing_quote_list_price_basis_sourced = quote_sourcing_quote_list_rows and route_decided_total > 0', guide: `PRM 补回来了,现在把清单**定盘**,一拍连做: ① **价源归档**:PRM 补了价的行(price_basis 还空着的),逐行写 price_basis = **SOURCED** (大写,一个字母不许差);A 类预填的行已是 HIST,不动。 按 rfq_ref + pn 对行,主键一个字符不许改。 ② 若还有行缺底价(他留空又没撤):照他备注的说明办 —— 写明剔除的用 \`drop\` 把那一行撤出本单草稿(主键照 \`_keys\` 名单**原样粘**),撤了哪几颗、为什么写进 verdict.summary,并把 quote_line_total 与 pending_total 改成撤后的实数; 什么说明都没有的,发一张**决策卡(decide)**问负责人「这几颗问不到价,剔出本轮还是退回」, 照答复办。**只问这一次**。 ③ 写 verdict:**route_decided_total 记 1**、summary 一句人话 (几行历史价、几行货源价、剔了几颗、整份可交定价)。 ④ finish 这一项。引擎按「每行有价 + 价源守恒 + 定盘记过」收步,三样有一样不齐都收不掉。 这一单只有一个出口(交成本定价),**没有去向要选** —— 定盘就是把账写齐。`, }, { item: 'T_release', view: 'sourcing-roster', intent: '清单已定盘,提交放行交 PRM 验收', writes: [], reads: [], tools: [], /* 放行触达世界,必须人按一下 —— 引擎不自动收它(剧本里也不给 doneWhen) */ guide: `每行有价、价源守恒、定盘已记 —— 可以走放行了(T_release 人工激活: 动它就算启动,不必单发 start)。先把裁量判据裁掉,然后 submit,同一拍连做: · judge criterion="货源与价格来源可核:B 类行的供应商与底价来自真实询价或可靠渠道,PRM 对报价负责" —— 看清单里 SOURCED 行的供应商与备注:说得出来源就 satisfied=true; 有行说不出的,satisfied=**false**,rationale 逐行写清,交签字的人定。 **裁成不满足照样能提交** —— 理由连着卡一起交给他。 criterion 照判据名**整句原样抄**,写别的名字对不上。 终局唯放行:你不能自己宣布完成。`, }, ]; /** * 阶段 —— 进度条的刻度,只给人看。除放行外每个计划项恰属一个阶段; * 放行那一格由基座统一加,人看到的是 x/4。 */ export const SOURCING_PHASES = [ { name: '归一预填', items: ['S1_normalize'] }, { name: '补货源价', items: ['S2_fill'] }, { name: '汇稿定盘', items: ['S3_compile'] }, ];