Jelajahi Sumber

merge: 保留本地版本号 Web 2.4.178 / Server 1.0.149

Pengxy 1 Minggu lalu
induk
melakukan
5d4541ded9
52 mengubah file dengan 8431 tambahan dan 376 penghapusan
  1. 1 1
      Web/package.json
  2. 2 2
      Web/src/views/aidop/s0/sales/CustomerList.vue
  3. 2 2
      Web/src/views/aidop/s0/sales/MaterialList.vue
  4. 178 309
      Web/src/views/aidop/s0/sales/OrderPriorityRuleList.vue
  5. 62 0
      Web/src/views/aidop/s8/api/s8OrderFlowDomainApi.ts
  6. 70 4
      Web/src/views/aidop/s8/monitoring/OrderChainOverviewPage.vue
  7. 205 49
      Web/src/views/aidop/s8/monitoring/components/order-execution/ManufacturingDetailPanel.vue
  8. 172 0
      Web/src/views/aidop/s8/monitoring/data/order-execution/stage-detail.ts
  9. 10 0
      doc/README.md
  10. 230 0
      doc/plan/S1-S4全局UAT场景测试数据生成方案.md
  11. 467 0
      doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md
  12. 270 0
      doc/plan/S1/S1产销协同UAT数据生成执行任务书.md
  13. 271 0
      doc/plan/S1/S1产销协同UAT测试数据抽取与导入方案.md
  14. 222 0
      doc/plan/S1S2S3_UAT测试指南.md
  15. 70 0
      doc/plan/S1S4_UAT_FULL_执行记录_20260605.md
  16. 94 0
      doc/plan/S1S4_UAT_P0_冒烟验收报告_20260605.md
  17. 174 0
      doc/plan/S1S4_UAT_P0_只读检查报告_20260604.md
  18. 106 0
      doc/plan/S1S4_UAT_P0_抽数记录_20260604.md
  19. 126 0
      doc/plan/S2/S2制造协同UAT数据生成执行任务书.md
  20. 149 0
      doc/plan/S2/S2制造协同UAT测试数据生成方案.md
  21. 124 0
      doc/plan/S3/S3供应协同UAT数据生成执行任务书.md
  22. 147 0
      doc/plan/S3/S3供应协同UAT测试数据生成方案.md
  23. 131 0
      doc/plan/S4/S4采购执行UAT数据生成执行任务书.md
  24. 155 0
      doc/plan/S4/S4采购执行UAT测试数据生成方案.md
  25. 1346 0
      doc/plan/sql/S1S4_UAT_FULL_execute_write.sql
  26. 300 0
      doc/plan/sql/S1S4_UAT_P0_execute_write.sql
  27. 402 0
      doc/plan/sql/S1S4_UAT_P0_试导SQL草案_20260604.sql
  28. 271 0
      doc/plan/sql/S1S4_UAT_P0_试导数据填充_20260604.sql
  29. 22 0
      doc/plan/sql/S1S4_UAT_P0补发货_PO04_PO05.sql
  30. 27 0
      doc/plan/sql/S1S4_UAT_S1_mdp_entity_product_design_20260605.sql
  31. 105 0
      doc/plan/sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql
  32. 629 0
      doc/plan/sql/_extract_full.tsv
  33. 24 0
      doc/plan/sql/_extract_p0.tsv
  34. 233 0
      doc/plan/sql/tools/Generate-S1S4FullUatSql.ps1
  35. 69 0
      doc/plan/sql/tools/S1S4_FULL_bill_list.txt
  36. 39 0
      doc/plan/sql/tools/extract_full_from_dopdemorq.sql
  37. 1 1
      doc/plan/数据库迁移/S1/S1-任务交接记忆.md
  38. 360 0
      server/Admin.NET.Web.Entry/UpdateScripts/1.0.150.sql
  39. 15 0
      server/Admin.NET.Web.Entry/UpdateScripts/1.0.151.sql
  40. 24 0
      server/Admin.NET.Web.Entry/UpdateScripts/1.0.152.sql
  41. 10 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/S8/AdoS8OrderFlowController.cs
  42. 68 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Dto/S8/OrderFlow/AdoS8OrderFlowDtos.cs
  43. 2 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S0/Manufacturing/AdoS0ProductStructure.cs
  44. 75 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowManufacturingLossFactor.cs
  45. 70 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowManufacturingOperator.cs
  46. 91 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowManufacturingProcess.cs
  47. 18 0
      server/Plugins/Admin.NET.Plugin.AiDOP/Order/S1MdpSyncTransformService.cs
  48. 423 0
      server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/S8OrderFlowManufacturingSeedData.cs
  49. 6 6
      server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/SysMenuSeedData.cs
  50. 341 1
      server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/OrderFlow/S8OrderFlowService.cs
  51. 0 1
      server/Plugins/Admin.NET.Plugin.AiDOP/Startup.cs
  52. 22 0
      server/deploy/winsw/AiDOPBackendService.xml

+ 1 - 1
Web/package.json

@@ -1,7 +1,7 @@
 {
 	"name": "admin.net",
 	"type": "module",
-	"version": "2.4.178"
+	"version": "2.4.178",
 	"packageManager": "pnpm@10.32.1",
 	"lastBuildTime": "2026.03.15",
 	"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",

+ 2 - 2
Web/src/views/aidop/s0/sales/CustomerList.vue

@@ -1,5 +1,5 @@
 <template>
-	<AidopDemoShell :title="pageTitle" subtitle="S0 / Sales / 客户管理">
+	<AidopDemoShell :title="pageTitle" subtitle="S0 / Sales / 客户信息维护">
 		<el-form :inline="true" :model="query" class="mb12" @submit.prevent>
 			<el-form-item label="关键字">
 				<el-input v-model="query.keyword" placeholder="客户编码/简称/全称" clearable style="width: 180px" />
@@ -229,7 +229,7 @@ import {
 } from '../api/s0SalesApi';
 
 const route = useRoute();
-const pageTitle = computed(() => (route.meta?.title as string) || '客户管理');
+const pageTitle = computed(() => (route.meta?.title as string) || '客户信息维护');
 
 const query = reactive({
 	keyword: '',

+ 2 - 2
Web/src/views/aidop/s0/sales/MaterialList.vue

@@ -1,5 +1,5 @@
 <template>
-	<AidopDemoShell :title="pageTitle" subtitle="S0 / Sales / 物料管理">
+	<AidopDemoShell :title="pageTitle" subtitle="S0 / Sales / 物料维护列表">
 		<el-form :inline="true" :model="query" class="mb12" @submit.prevent>
 			<el-form-item label="关键字">
 				<el-input v-model="query.keyword" placeholder="编码/名称" clearable style="width: 140px" />
@@ -256,7 +256,7 @@ import {
 } from '../api/s0SalesApi';
 
 const route = useRoute();
-const pageTitle = computed(() => (route.meta?.title as string) || '物料管理');
+const pageTitle = computed(() => (route.meta?.title as string) || '物料维护列表');
 
 const activeTab = ref('owner');
 const query = reactive({

+ 178 - 309
Web/src/views/aidop/s0/sales/OrderPriorityRuleList.vue

@@ -1,12 +1,12 @@
 <template>
-	<AidopDemoShell :title="pageTitle" subtitle="S0 / Sales / 订单优先级">
+	<AidopDemoShell :title="pageTitle" subtitle="S0 / Sales / 订单优先级配置">
 		<!-- ── 查询栏 ── -->
 		<el-form :inline="true" :model="query" class="mb12" @submit.prevent>
 			<el-form-item label="关键字">
-				<el-input v-model="query.keyword" placeholder="规则名称/编码" clearable style="width: 180px" />
+				<el-input v-model="query.keyword" placeholder="名称/来源表/工单字段" clearable style="width: 200px" />
 			</el-form-item>
-			<el-form-item label="生效">
-				<el-select v-model="query.isEnabled" clearable placeholder="全部" style="width: 100px">
+			<el-form-item label="是否生效">
+				<el-select v-model="query.isActive" clearable placeholder="全部" style="width: 100px">
 					<el-option label="是" :value="true" />
 					<el-option label="否" :value="false" />
 				</el-select>
@@ -14,36 +14,41 @@
 			<el-form-item>
 				<el-button type="primary" @click="loadList">查询</el-button>
 				<el-button @click="resetQuery">重置</el-button>
-				<el-button type="success" @click="openCreate">新增规则</el-button>
-				<el-button @click="configDialogVisible = true">配置维护</el-button>
+				<el-button type="success" @click="openCreate">新增配置</el-button>
 			</el-form-item>
 		</el-form>
 
 		<!-- ── 主列表 ── -->
 		<el-table :data="rows" v-loading="loading" border stripe style="width: 100%" max-height="calc(100vh - 260px)">
-			<el-table-column prop="name" label="规则名称" min-width="160" show-overflow-tooltip />
-			<el-table-column label="客户类型" width="120" show-overflow-tooltip>
-				<template #default="{ row }">{{ row.customerTypeLabel || '—' }}</template>
+			<el-table-column prop="descr" label="名称" min-width="150" show-overflow-tooltip>
+				<template #default="{ row }">{{ row.descr || '—' }}</template>
 			</el-table-column>
-			<el-table-column label="订单类型" width="120" show-overflow-tooltip>
-				<template #default="{ row }">{{ row.orderTypeLabel || '—' }}</template>
+			<el-table-column prop="value" label="工单字段" width="130" show-overflow-tooltip>
+				<template #default="{ row }">{{ row.value || '—' }}</template>
 			</el-table-column>
-			<el-table-column label="交期条件" width="100" show-overflow-tooltip>
-				<template #default="{ row }">{{ row.dueStatusLabel || '—' }}</template>
+			<el-table-column prop="priority" label="优先级" width="80" align="center" />
+			<el-table-column prop="sourceTable" label="来源表" width="140" show-overflow-tooltip>
+				<template #default="{ row }">{{ row.sourceTable || '—' }}</template>
+			</el-table-column>
+			<el-table-column prop="sourceColumn" label="来源字段" width="130" show-overflow-tooltip>
+				<template #default="{ row }">{{ row.sourceColumn || '—' }}</template>
+			</el-table-column>
+			<el-table-column label="排序" width="80" align="center">
+				<template #default="{ row }">{{ orderByDisplay(row) }}</template>
 			</el-table-column>
-			<el-table-column prop="priorityLevel" label="优先级" width="80" align="center" />
-			<el-table-column prop="sortDirection" label="排序方向" width="88" align="center" />
 			<el-table-column label="是否生效" width="88" align="center">
 				<template #default="{ row }">
-					<el-tag :type="row.isEnabled ? 'success' : 'info'" size="small">{{ row.isEnabled ? '是' : '否' }}</el-tag>
+					<el-tag :type="row.isActive ? 'success' : 'info'" size="small">{{ row.isActive ? '是' : '否' }}</el-tag>
 				</template>
 			</el-table-column>
-			<el-table-column prop="remark" label="备注" min-width="140" show-overflow-tooltip />
+			<el-table-column prop="domainCode" label="工厂域" width="100" show-overflow-tooltip>
+				<template #default="{ row }">{{ row.domainCode || '—' }}</template>
+			</el-table-column>
 			<el-table-column label="操作" width="200" fixed="right" align="center">
 				<template #default="{ row }">
 					<el-button link type="primary" @click="openEdit(row)">编辑</el-button>
-					<el-button link :type="row.isEnabled ? 'warning' : 'success'" @click="toggleEnabled(row)">
-						{{ row.isEnabled ? '停用' : '生效' }}
+					<el-button link :type="row.isActive ? 'warning' : 'success'" @click="toggleActive(row)">
+						{{ row.isActive ? '停用' : '生效' }}
 					</el-button>
 					<el-button link type="danger" @click="onDelete(row)">删除</el-button>
 				</template>
@@ -62,201 +67,129 @@
 			/>
 		</div>
 
-		<!-- ── 新增/编辑规则弹窗 ── -->
+		<!-- ── 新增/编辑配置弹窗 ── -->
 		<el-dialog
-			v-model="ruleDialogVisible"
-			:title="ruleDialogTitle"
-			width="680px"
+			v-model="formDialogVisible"
+			:title="formDialogTitle"
+			width="720px"
 			destroy-on-close
-			@closed="resetRuleForm"
+			@closed="resetForm"
 		>
-			<el-form ref="ruleFormRef" :model="ruleForm" :rules="ruleFormRules" label-width="110px">
+			<el-form ref="formRef" :model="form" :rules="formRules" label-width="110px">
 				<el-row :gutter="16">
 					<el-col :span="12">
-						<el-form-item label="规则编码" prop="code">
-							<el-input v-model="ruleForm.code" placeholder="可自动填充或手动输入" />
+						<el-form-item label="名称" prop="descr">
+							<el-input v-model="form.descr" placeholder="优先级配置名称" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="规则名称" prop="name">
-							<el-input v-model="ruleForm.name" />
+						<el-form-item label="工单字段">
+							<el-input v-model="form.value" placeholder="工单表字段(Value)" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="客户类型">
-							<el-select v-model="ruleForm.customerType" clearable placeholder="不限" style="width: 100%">
-								<el-option
-									v-for="opt in dictOptions.customerType"
-									:key="opt.value"
-									:label="opt.label"
-									:value="opt.value"
-								/>
-							</el-select>
+						<el-form-item label="优先级" prop="priority">
+							<el-input-number v-model="form.priority" :min="0" style="width: 100%" controls-position="right" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="订单类型">
-							<el-select v-model="ruleForm.orderType" clearable placeholder="不限" style="width: 100%">
-								<el-option
-									v-for="opt in dictOptions.orderType"
-									:key="opt.value"
-									:label="opt.label"
-									:value="opt.value"
-								/>
+						<el-form-item label="排序方向">
+							<el-select v-model="form.orderBy" clearable placeholder="未设置" style="width: 100%">
+								<el-option label="正序" :value="true" />
+								<el-option label="倒序" :value="false" />
 							</el-select>
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="交期条件">
-							<el-select v-model="ruleForm.dueStatus" clearable placeholder="不限" style="width: 100%">
-								<el-option
-									v-for="opt in dictOptions.dueStatus"
-									:key="opt.value"
-									:label="opt.label"
-									:value="opt.value"
-								/>
-							</el-select>
+						<el-form-item label="来源表">
+							<el-input v-model="form.sourceTable" placeholder="来源表" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="优先级" prop="priorityLevel">
-							<el-input-number v-model="ruleForm.priorityLevel" :min="1" style="width: 100%" controls-position="right" />
+						<el-form-item label="来源字段">
+							<el-input v-model="form.sourceColumn" placeholder="来源表字段" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="排序方向">
-							<el-select v-model="ruleForm.sortDirection" style="width: 100%">
-								<el-option label="升序 ASC" value="asc" />
-								<el-option label="降序 DESC" value="desc" />
-							</el-select>
+						<el-form-item label="来源字段类型">
+							<el-input v-model="form.sourceType" placeholder="来源字段类型" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="是否生效">
-							<el-switch v-model="ruleForm.isEnabled" />
+						<el-form-item label="来源关联字段">
+							<el-input v-model="form.sourceId" placeholder="来源表关联字段" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="工单字段类型">
+							<el-input v-model="form.valueType" placeholder="工单字段类型" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="工单关联字段">
+							<el-input v-model="form.valueId" placeholder="工单表关联字段" />
 						</el-form-item>
 					</el-col>
-					<el-col :span="24">
-						<el-form-item label="备注">
-							<el-input v-model="ruleForm.remark" type="textarea" :rows="2" />
+					<el-col :span="12">
+						<el-form-item label="工厂域">
+							<el-input v-model="form.domainCode" placeholder="工厂域编码(Domain)" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="是否生效">
+							<el-switch v-model="form.isActive" />
 						</el-form-item>
 					</el-col>
 				</el-row>
 			</el-form>
 			<template #footer>
-				<el-button @click="ruleDialogVisible = false">取消</el-button>
-				<el-button type="primary" :loading="ruleSaving" @click="submitRuleForm">保存</el-button>
+				<el-button @click="formDialogVisible = false">取消</el-button>
+				<el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
 			</template>
 		</el-dialog>
-
-		<!-- ── 配置维护弹窗 ── -->
-		<el-dialog
-			v-model="configDialogVisible"
-			title="订单优先级配置维护"
-			width="860px"
-			destroy-on-close
-			@open="loadFieldMapping"
-		>
-			<el-tabs v-model="configActiveTab">
-				<!-- Tab 1: 客户类型 -->
-				<el-tab-pane label="客户类型" name="customerType">
-					<DictDataMaintainPanel
-						dict-code="s0_order_priority_customer_type"
-						@changed="loadDictSelects"
-					/>
-				</el-tab-pane>
-
-				<!-- Tab 2: 订单类型 -->
-				<el-tab-pane label="订单类型" name="orderType">
-					<DictDataMaintainPanel
-						dict-code="s0_order_type"
-						@changed="loadDictSelects"
-					/>
-				</el-tab-pane>
-
-				<!-- Tab 3: 交期规则 -->
-				<el-tab-pane label="交期规则" name="dueStatus">
-					<DictDataMaintainPanel
-						dict-code="s0_due_status"
-						:allow-delete="false"
-						@changed="loadDictSelects"
-					/>
-				</el-tab-pane>
-
-				<!-- Tab 4: 字段映射 -->
-				<el-tab-pane label="字段映射" name="fieldMapping">
-					<div class="field-mapping-panel">
-						<el-alert
-							type="info"
-							:closable="false"
-							title="字段映射来源于现有优先级规则字段配置"
-							description="来源实体、来源字段、工单字段等字段映射信息在各条业务规则中独立维护,请通过「编辑规则」进行调整。"
-						/>
-						<el-table
-							:data="fieldMappingRows"
-							v-loading="fieldMappingLoading"
-							border
-							stripe
-							size="small"
-							style="width: 100%; margin-top: 12px"
-							max-height="320px"
-						>
-							<el-table-column prop="name" label="规则名称" min-width="130" show-overflow-tooltip />
-							<el-table-column prop="sourceEntity" label="来源实体" width="130" show-overflow-tooltip />
-							<el-table-column prop="sourceField" label="来源字段" width="130" show-overflow-tooltip />
-							<el-table-column prop="workOrderField" label="工单字段" width="130" show-overflow-tooltip />
-							<el-table-column prop="workOrderFieldType" label="工单字段类型" width="120" show-overflow-tooltip />
-						</el-table>
-						<div v-if="!fieldMappingLoading && fieldMappingRows.length === 0" class="empty-hint">
-							当前未维护字段映射
-						</div>
-					</div>
-				</el-tab-pane>
-			</el-tabs>
-		</el-dialog>
 	</AidopDemoShell>
 </template>
 
 <script setup lang="ts" name="aidopS0SalesOrderPriorityRule">
-import { computed, onMounted, reactive, ref, watch } from 'vue';
+import { computed, onMounted, reactive, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
 import AidopDemoShell from '../../components/AidopDemoShell.vue';
 import {
-	s0PriorityRulesApi,
-	type S0PriorityRuleRow,
-	type S0PriorityRuleUpsert,
-	loadDictOptions,
-	type OptionItem,
+	s0OrderPriorityRulesApi,
+	type S0PriorityCodeRow,
+	type S0PriorityCodeUpsert,
 } from '../api/s0SalesApi';
-import DictDataMaintainPanel from './components/DictDataMaintainPanel.vue';
-
-// ── 旧 API 保留(不删除,不作为主列表数据源)──────────────────────────────
-// s0OrderPriorityRulesApi 仍在 s0SalesApi.ts 中导出,此处不需引用
 
 const route = useRoute();
-const pageTitle = computed(() => (route.meta?.title as string) || '订单优先规则');
+const pageTitle = computed(() => (route.meta?.title as string) || '订单优先级配置');
 
 // ── 查询 ──────────────────────────────────────────────────────────────────
 const query = reactive({
 	keyword: '',
-	isEnabled: undefined as boolean | undefined,
+	isActive: undefined as boolean | undefined,
 	page: 1,
 	pageSize: 20,
 });
 
 const loading = ref(false);
-const rows = ref<S0PriorityRuleRow[]>([]);
+const rows = ref<S0PriorityCodeRow[]>([]);
 const total = ref(0);
 
+/** 列表排序展示:优先 orderByText;缺失时按 orderBy 映射(false=倒序,其余=正序)。 */
+function orderByDisplay(row: S0PriorityCodeRow): string {
+	if (row.orderByText) return row.orderByText;
+	return row.orderBy === false ? '倒序' : '正序';
+}
+
 async function loadList() {
 	loading.value = true;
 	try {
-		const data = await s0PriorityRulesApi.list({
+		const data = await s0OrderPriorityRulesApi.list({
 			page: query.page,
 			pageSize: query.pageSize,
 			keyword: query.keyword || undefined,
-			isEnabled: query.isEnabled,
+			isActive: query.isActive,
 		});
 		rows.value = data.list;
 		total.value = data.total;
@@ -269,207 +202,152 @@ async function loadList() {
 }
 
 function resetQuery() {
-	Object.assign(query, { keyword: '', isEnabled: undefined, page: 1 });
+	Object.assign(query, { keyword: '', isActive: undefined, page: 1 });
 	void loadList();
 }
 
-// ── 字典选项 ──────────────────────────────────────────────────────────────
-const dictOptions = reactive({
-	customerType: [] as OptionItem[],
-	orderType: [] as OptionItem[],
-	dueStatus: [] as OptionItem[],
-});
-
-async function loadDictSelects() {
-	const [ct, ot, ds] = await Promise.all([
-		loadDictOptions('s0_order_priority_customer_type'),
-		loadDictOptions('s0_order_type'),
-		loadDictOptions('s0_due_status'),
-	]);
-	dictOptions.customerType = ct;
-	dictOptions.orderType = ot;
-	dictOptions.dueStatus = ds;
+// ── 配置表单 ──────────────────────────────────────────────────────────────
+const formDialogVisible = ref(false);
+const formDialogTitle = ref('新增配置');
+const editingId = ref<string | null>(null);
+const saving = ref(false);
+const formRef = ref<FormInstance>();
+
+interface PriorityCodeForm {
+	descr: string;
+	value: string;
+	priority: number;
+	orderBy: boolean | null;
+	sourceTable: string;
+	sourceColumn: string;
+	sourceType: string;
+	sourceId: string;
+	valueType: string;
+	valueId: string;
+	domainCode: string;
+	isActive: boolean;
 }
 
-// ── 规则表单 ──────────────────────────────────────────────────────────────
-const ruleDialogVisible = ref(false);
-const ruleDialogTitle = ref('新增规则');
-const editingId = ref<number | null>(null);
-const ruleSaving = ref(false);
-const ruleFormRef = ref<FormInstance>();
-
-function emptyRuleForm(): S0PriorityRuleUpsert & { customerType?: string; orderType?: string; dueStatus?: string } {
+function emptyForm(): PriorityCodeForm {
 	return {
-		companyRefId: 0,
-		factoryRefId: 0,
-		code: '',
-		name: '',
-		priorityLevel: 1,
-		sortDirection: 'asc',
-		customerType: undefined,
-		orderType: undefined,
-		dueStatus: undefined,
-		isEnabled: true,
-		remark: '',
+		descr: '',
+		value: '',
+		priority: 1,
+		orderBy: null,
+		sourceTable: '',
+		sourceColumn: '',
+		sourceType: '',
+		sourceId: '',
+		valueType: '',
+		valueId: '',
+		domainCode: '',
+		isActive: true,
 	};
 }
 
-const ruleForm = reactive(emptyRuleForm());
+const form = reactive<PriorityCodeForm>(emptyForm());
 
-const ruleFormRules: FormRules = {
-	code: [{ required: true, message: '请填写规则编码', trigger: 'blur' }],
-	name: [{ required: true, message: '请填写规则名称', trigger: 'blur' }],
-	priorityLevel: [{ required: true, message: '请填写优先级', trigger: 'change' }],
+const formRules: FormRules = {
+	descr: [{ required: true, message: '请填写名称', trigger: 'blur' }],
+	priority: [{ required: true, message: '请填写优先级', trigger: 'change' }],
 };
 
-function resetRuleForm() {
+function resetForm() {
 	editingId.value = null;
-	Object.assign(ruleForm, emptyRuleForm());
-	ruleFormRef.value?.clearValidate();
+	Object.assign(form, emptyForm());
+	formRef.value?.clearValidate();
 }
 
 function openCreate() {
-	resetRuleForm();
-	ruleDialogTitle.value = '新增规则';
-	ruleDialogVisible.value = true;
-}
-
-function parseRuleExpr(row: S0PriorityRuleRow): { customerType?: string; orderType?: string; dueStatus?: string } {
-	// 后端 IsIgnore 标签字段优先;fallback 解析 ruleExpr JSON
-	if (row.customerTypeLabel !== undefined || row.orderTypeLabel !== undefined || row.dueStatusLabel !== undefined) {
-		// 标签字段是展示用的,实际 value 需从 ruleExpr 解析
-	}
-	if (!row.ruleExpr) return {};
-	try {
-		const parsed = JSON.parse(row.ruleExpr) as Record<string, unknown>;
-		return {
-			customerType: typeof parsed.customerType === 'string' ? parsed.customerType : undefined,
-			orderType: typeof parsed.orderType === 'string' ? parsed.orderType : undefined,
-			dueStatus: typeof parsed.dueStatus === 'string' ? parsed.dueStatus : undefined,
-		};
-	} catch {
-		return {};
-	}
+	resetForm();
+	formDialogTitle.value = '新增配置';
+	formDialogVisible.value = true;
 }
 
-function openEdit(row: S0PriorityRuleRow) {
-	resetRuleForm();
+function openEdit(row: S0PriorityCodeRow) {
+	resetForm();
 	editingId.value = row.id;
-	ruleDialogTitle.value = `编辑规则 ${row.name}`;
-	const expr = parseRuleExpr(row);
-	Object.assign(ruleForm, {
-		companyRefId: row.companyRefId,
-		factoryRefId: row.factoryRefId,
-		code: row.code,
-		name: row.name,
-		priorityLevel: row.priorityLevel,
-		sortDirection: row.sortDirection,
-		customerType: expr.customerType,
-		orderType: expr.orderType,
-		dueStatus: expr.dueStatus,
-		sourceEntity: row.sourceEntity,
-		sourceField: row.sourceField,
-		sourceFieldType: row.sourceFieldType,
-		sourceLinkField: row.sourceLinkField,
-		workOrderField: row.workOrderField,
-		workOrderFieldType: row.workOrderFieldType,
-		workOrderLinkField: row.workOrderLinkField,
-		isEnabled: row.isEnabled,
-		remark: row.remark ?? '',
+	formDialogTitle.value = `编辑配置 ${row.descr || ''}`.trim();
+	Object.assign(form, {
+		descr: row.descr ?? '',
+		value: row.value ?? '',
+		priority: row.priority,
+		orderBy: row.orderBy ?? null,
+		sourceTable: row.sourceTable ?? '',
+		sourceColumn: row.sourceColumn ?? '',
+		sourceType: row.sourceType ?? '',
+		sourceId: row.sourceId ?? '',
+		valueType: row.valueType ?? '',
+		valueId: row.valueId ?? '',
+		domainCode: row.domainCode ?? '',
+		isActive: row.isActive,
 	});
-	ruleDialogVisible.value = true;
+	formDialogVisible.value = true;
+}
+
+/** 空字符串归一为 undefined,避免把空值写库。 */
+function blankToUndefined(v: string): string | undefined {
+	return v.trim() === '' ? undefined : v;
 }
 
-async function submitRuleForm() {
-	await ruleFormRef.value?.validate();
-	ruleSaving.value = true;
+async function submitForm() {
+	await formRef.value?.validate();
+	saving.value = true;
 	try {
-		const payload: S0PriorityRuleUpsert = {
-			companyRefId: ruleForm.companyRefId,
-			factoryRefId: ruleForm.factoryRefId,
-			code: ruleForm.code,
-			name: ruleForm.name,
-			priorityLevel: ruleForm.priorityLevel,
-			sortDirection: ruleForm.sortDirection,
-			customerType: (ruleForm as any).customerType || undefined,
-			orderType: (ruleForm as any).orderType || undefined,
-			dueStatus: (ruleForm as any).dueStatus || undefined,
-			sourceEntity: ruleForm.sourceEntity,
-			sourceField: ruleForm.sourceField,
-			sourceFieldType: ruleForm.sourceFieldType,
-			sourceLinkField: ruleForm.sourceLinkField,
-			workOrderField: ruleForm.workOrderField,
-			workOrderFieldType: ruleForm.workOrderFieldType,
-			workOrderLinkField: ruleForm.workOrderLinkField,
-			isEnabled: ruleForm.isEnabled,
-			remark: ruleForm.remark,
+		const payload: S0PriorityCodeUpsert = {
+			descr: form.descr,
+			value: blankToUndefined(form.value),
+			priority: form.priority,
+			orderBy: form.orderBy,
+			sourceTable: blankToUndefined(form.sourceTable),
+			sourceColumn: blankToUndefined(form.sourceColumn),
+			sourceType: blankToUndefined(form.sourceType),
+			sourceId: blankToUndefined(form.sourceId),
+			valueType: blankToUndefined(form.valueType),
+			valueId: blankToUndefined(form.valueId),
+			domainCode: blankToUndefined(form.domainCode),
+			isActive: form.isActive,
 		};
 		if (editingId.value !== null) {
-			await s0PriorityRulesApi.update(editingId.value, payload);
+			await s0OrderPriorityRulesApi.update(editingId.value, payload);
 			ElMessage.success('已保存');
 		} else {
-			await s0PriorityRulesApi.create(payload);
+			await s0OrderPriorityRulesApi.create(payload);
 			ElMessage.success('已创建');
 		}
-		ruleDialogVisible.value = false;
+		formDialogVisible.value = false;
 		await loadList();
 	} catch {
-		ElMessage.error('保存订单优先规则失败,请检查填写内容后重试');
+		ElMessage.error('保存订单优先级配置失败,请检查填写内容后重试');
 	} finally {
-		ruleSaving.value = false;
+		saving.value = false;
 	}
 }
 
-function onDelete(row: S0PriorityRuleRow) {
-	ElMessageBox.confirm(`确定删除规则「${row.name}」?`, '确认', { type: 'warning' })
+function onDelete(row: S0PriorityCodeRow) {
+	ElMessageBox.confirm('确认删除该订单优先级配置吗?', '确认', { type: 'warning' })
 		.then(async () => {
-			await s0PriorityRulesApi.delete(row.id);
+			await s0OrderPriorityRulesApi.delete(row.id);
 			ElMessage.success('已删除');
 			await loadList();
 		})
 		.catch(() => {});
 }
 
-function toggleEnabled(row: S0PriorityRuleRow) {
-	const next = !row.isEnabled;
+function toggleActive(row: S0PriorityCodeRow) {
+	const next = !row.isActive;
 	const actionText = next ? '生效' : '停用';
-	ElMessageBox.confirm(`确定${actionText}规则「${row.name}」?`, '确认', { type: 'warning' })
+	ElMessageBox.confirm(`确定${actionText}该订单优先级配置「${row.descr || ''}」?`, '确认', { type: 'warning' })
 		.then(async () => {
-			await s0PriorityRulesApi.toggleEnabled(row.id, { isEnabled: next });
+			await s0OrderPriorityRulesApi.toggleEnabled(row.id, { isActive: next });
 			ElMessage.success(`${actionText}成功`);
 			await loadList();
 		})
 		.catch(() => {});
 }
 
-// ── 配置维护弹窗 ──────────────────────────────────────────────────────────
-const configDialogVisible = ref(false);
-const configActiveTab = ref('customerType');
-
-watch(configActiveTab, (tab) => {
-	if (tab === 'fieldMapping') void loadFieldMapping();
-});
-
-// 字段映射 Tab
-const fieldMappingRows = ref<S0PriorityRuleRow[]>([]);
-const fieldMappingLoading = ref(false);
-
-async function loadFieldMapping() {
-	fieldMappingLoading.value = true;
-	try {
-		const data = await s0PriorityRulesApi.list({ page: 1, pageSize: 200 });
-		fieldMappingRows.value = data.list.filter(
-			(r) => r.sourceEntity || r.sourceField || r.workOrderField,
-		);
-	} catch {
-		fieldMappingRows.value = [];
-	} finally {
-		fieldMappingLoading.value = false;
-	}
-}
-
 onMounted(async () => {
-	await Promise.all([loadList(), loadDictSelects()]);
+	await loadList();
 });
 </script>
 
@@ -485,13 +363,4 @@ onMounted(async () => {
 	display: flex;
 	justify-content: flex-end;
 }
-
-.field-mapping-panel {
-	.empty-hint {
-		text-align: center;
-		color: #909399;
-		padding: 24px 0;
-		font-size: 13px;
-	}
-}
 </style>

+ 62 - 0
Web/src/views/aidop/s8/api/s8OrderFlowDomainApi.ts

@@ -272,6 +272,61 @@ export interface OrderFlowProductDesignDrawings {
 	drawings: OrderFlowProductDesignDrawingItem[];
 }
 
+// ────────────────────────────────────────────────────────────
+// Manufacturing pivot (S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1)
+// 本体生产「工序明细 / 损失因素 / 操作员表现」三表透视。
+// scope=BASELINE_PPT 直接读 baseline;scope=CURRENT_FILTERED 走订单级行聚合。
+// ────────────────────────────────────────────────────────────
+
+export interface OrderFlowManufacturingPivotQuery {
+	tenantId?: number;
+	factoryId?: number;
+	/** BASELINE_PPT | CURRENT_FILTERED */
+	scope: string;
+	/**
+	 * 订单编码 CSV(与产品设计 drawings / 采购透视 API 对齐):
+	 * 单订单 "SO-2026-001";多订单 "SO-2026-001,SO-2026-002,SO-2026-006"。
+	 * 不使用数组以避免 axios 默认 brackets 序列化与 ASP.NET Core List 绑定二义性。
+	 */
+	orderCodes?: string;
+}
+
+export interface OrderFlowManufacturingProcess {
+	processCode: string;
+	processName: string;
+	piDays: number;
+	actualDays: number;
+	cycleStatus: string;
+	planQty: number | null;
+	achievementRate: number | null;
+	achievementStatus: string;
+	sortNo: number;
+}
+
+export interface OrderFlowManufacturingLossFactor {
+	factorCode: string;
+	factorName: string;
+	countValue: number | null;
+	ratioPct: number | null;
+	lossHours: number | null;
+	sortNo: number;
+}
+
+export interface OrderFlowManufacturingOperator {
+	operatorCode: string;
+	operatorName: string;
+	avgHours: number;
+	status: string;
+	sortNo: number;
+}
+
+export interface OrderFlowManufacturingPivot {
+	scope: string;
+	processes: OrderFlowManufacturingProcess[];
+	lossFactors: OrderFlowManufacturingLossFactor[];
+	operators: OrderFlowManufacturingOperator[];
+}
+
 // ────────────────────────────────────────────────────────────
 // API methods
 // ────────────────────────────────────────────────────────────
@@ -318,6 +373,12 @@ export function getOrderFlowProductDesignDrawings(query: OrderFlowProductDesignD
 		.then(unwrap);
 }
 
+export function getOrderFlowManufacturingPivot(query: OrderFlowManufacturingPivotQuery) {
+	return service
+		.get<OrderFlowManufacturingPivot>(`${BASE}/manufacturing-pivot`, { params: query })
+		.then(unwrap);
+}
+
 export const s8OrderFlowDomainApi = {
 	getOrderFlowOrders,
 	getOrderFlowOrder,
@@ -325,4 +386,5 @@ export const s8OrderFlowDomainApi = {
 	getOrderFlowAggregate,
 	getOrderFlowProcurementPivot,
 	getOrderFlowProductDesignDrawings,
+	getOrderFlowManufacturingPivot,
 };

+ 70 - 4
Web/src/views/aidop/s8/monitoring/OrderChainOverviewPage.vue

@@ -21,13 +21,17 @@ import ProcurementDetailPanel from './components/order-execution/ProcurementDeta
 import ManufacturingDetailPanel from './components/order-execution/ManufacturingDetailPanel.vue';
 import FinalAssemblyCollabPanel from './components/order-execution/FinalAssemblyCollabPanel.vue';
 import {
-	MANUFACTURING_DETAIL_FIXTURE,
 	adaptProcurementPivotFromApi,
+	adaptManufacturingPivotFromApi,
 	type ProcurementDetailFromApi,
+	type ManufacturingDetailFromApi,
 } from '/@/views/aidop/s8/monitoring/data/order-execution/stage-detail';
 // S8-ORDER-CHAIN-PRODUCT-DESIGN-PPT-STATIC-AND-SINGLE-ORDER-ALIGN-1:默认不勾选态产品设计业务基线数据。
 import { PRODUCT_DESIGN_BASELINE_DETAIL } from '/@/views/aidop/s8/monitoring/data/order-execution/product-design-baseline';
-import { getOrderFlowProcurementPivot } from '/@/views/aidop/s8/api/s8OrderFlowDomainApi';
+import {
+	getOrderFlowProcurementPivot,
+	getOrderFlowManufacturingPivot,
+} from '/@/views/aidop/s8/api/s8OrderFlowDomainApi';
 // ORDER-FLOW-CHAIN-PAGE2-ORIGINAL-LOGIC-RESTORE-1:baseline (isUnfiltered) 态下 L2/L3 使用 PPT 常量。
 import {
 	PPT_REVIEW_SUBSTEPS,
@@ -404,6 +408,58 @@ watch(
 	{ immediate: true },
 );
 
+// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:本体生产矩阵按订单粒度二态加载。
+//   默认(isUnfiltered=true)→ scope=BASELINE_PPT,不传 orderCodes,显示 baseline (5 工序 + 5 损失 + 3 操作员)。
+//   单订单态 → scope=CURRENT_FILTERED,orderCodes=[detailOrder.soNo]:
+//     - 非 pending 单:显示该订单 13 行订单级数据。
+//     - pending 单(016/017/018/019):返回空骨架 → 面板展示「暂无本体生产数据」。
+//   多订单态 → scope=CURRENT_FILTERED,orderCodes=filteredChainOrders.map(soNo),
+//     后端按工序/因素/操作员聚合(actual_days AVG / plan_qty SUM / loss count SUM / 操作员 AVG)。
+//   不使用全局 load-once guard;每次 isUnfiltered / filteredChainOrders / showManufacturingDetail 任一变化重新拉取。
+//   in-flight 请求用 seq 去重,防止旧响应覆盖新响应;失败仅显示错误态,不静默回退 fixture / baseline。
+const manufacturingApiDetail = ref<ManufacturingDetailFromApi | null>(null);
+const manufacturingApiLoading = ref(false);
+const manufacturingApiError = ref<string | null>(null);
+let manufacturingRequestSeq = 0;
+
+async function loadManufacturingPivot() {
+	const mySeq = ++manufacturingRequestSeq;
+	const isBaseline = isUnfiltered.value;
+	const scope = isBaseline ? 'BASELINE_PPT' : 'CURRENT_FILTERED';
+	// CSV 字符串与产品设计 drawings / 采购透视 API 一致。
+	const orderCodes = isBaseline
+		? undefined
+		: filteredChainOrders.value.map((o) => o.soNo).join(',');
+
+	manufacturingApiLoading.value = true;
+	manufacturingApiError.value = null;
+	try {
+		const pivot = await getOrderFlowManufacturingPivot({ scope, orderCodes });
+		if (mySeq !== manufacturingRequestSeq) return;
+		manufacturingApiDetail.value = adaptManufacturingPivotFromApi(pivot);
+	} catch (e) {
+		if (mySeq !== manufacturingRequestSeq) return;
+		manufacturingApiError.value = '本体生产数据加载失败,请稍后重试';
+		manufacturingApiDetail.value = null;
+	} finally {
+		if (mySeq === manufacturingRequestSeq) {
+			manufacturingApiLoading.value = false;
+		}
+	}
+}
+
+watch(
+	[
+		() => showManufacturingDetail.value,
+		() => isUnfiltered.value,
+		() => filteredChainOrders.value,
+	],
+	([active]) => {
+		if (active) void loadManufacturingPivot();
+	},
+	{ immediate: true },
+);
+
 // S8-ORDER-CHAIN-PRODUCT-DESIGN-PPT-STATIC-AND-SINGLE-ORDER-ALIGN-1:产品设计阶段二态数据源。
 // 默认不勾选态(isUnfiltered=true)→ 直接使用前端业务基线数据 PRODUCT_DESIGN_BASELINE_DETAIL,
 //   不调用 /api/aidop/s8/order-flow/product-design/drawings 接口。
@@ -530,7 +586,12 @@ watch(
 				:loading="procurementApiLoading"
 				:error-message="procurementApiError"
 			/>
-			<ManufacturingDetailPanel v-if="showManufacturingDetail" :detail="MANUFACTURING_DETAIL_FIXTURE" />
+			<ManufacturingDetailPanel
+				v-if="showManufacturingDetail"
+				:api-detail="manufacturingApiDetail"
+				:loading="manufacturingApiLoading"
+				:error-message="manufacturingApiError"
+			/>
 			<FinalAssemblyCollabPanel
 				v-if="showFinalAssemblyCollab"
 				:aggregate-final="finalStageSnapshot"
@@ -596,7 +657,12 @@ watch(
 				:loading="procurementApiLoading"
 				:error-message="procurementApiError"
 			/>
-			<ManufacturingDetailPanel v-if="showManufacturingDetail" :detail="MANUFACTURING_DETAIL_FIXTURE" />
+			<ManufacturingDetailPanel
+				v-if="showManufacturingDetail"
+				:api-detail="manufacturingApiDetail"
+				:loading="manufacturingApiLoading"
+				:error-message="manufacturingApiError"
+			/>
 			<FinalAssemblyCollabPanel
 				v-if="showFinalAssemblyCollab"
 				:aggregate-final="finalStageSnapshot"

+ 205 - 49
Web/src/views/aidop/s8/monitoring/components/order-execution/ManufacturingDetailPanel.vue

@@ -1,17 +1,66 @@
 <script setup lang="ts" name="ManufacturingDetailPanel">
-// ORDER-FLOW-CHAIN-STAGE-DETAIL-MIGRATE-1:设备制造(本体生产)阶段结构化详情。fixture 来源 ecc-sandbox 硬编码;非真实数据。
+// ORDER-FLOW-CHAIN-STAGE-DETAIL-MIGRATE-1:设备制造(本体生产)阶段结构化详情。
+// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:默认走真实 API(apiDetail),
+// fixture 仅在 demoMode=true 时显示;与 ProcurementDetailPanel 一致的双模式。
+import { computed } from 'vue';
 import type {
 	ManufacturingDetail,
+	ManufacturingDetailFromApi,
+	ProcurementApiStatusTone,
 	StageDetailStatus,
 } from '/@/views/aidop/s8/monitoring/data/order-execution/stage-detail';
 
-defineProps<{ detail: ManufacturingDetail }>();
+type PanelMode = 'api' | 'fixture';
 
-function statusColor(s: StageDetailStatus): string {
+const props = defineProps<{
+	/** API 模式:真实数据;优先使用。 */
+	apiDetail?: ManufacturingDetailFromApi | null;
+	/** 显式演示数据模式:仅当 demoMode=true 时使用 fixture,否则 fixture 不进入渲染。 */
+	detail?: ManufacturingDetail;
+	/** 显式演示数据模式开关;默认 false。 */
+	demoMode?: boolean;
+	/** API 加载中。 */
+	loading?: boolean;
+	/** API 加载失败时的错误信息(任意非空字符串触发错误态)。 */
+	errorMessage?: string | null;
+}>();
+
+const mode = computed<PanelMode>(() => (props.demoMode && props.detail ? 'fixture' : 'api'));
+
+// ────────────────────────────────────────────────────────────
+// fixture 模式(演示数据;非默认)
+// ────────────────────────────────────────────────────────────
+function fixtureStatusColor(s: StageDetailStatus): string {
 	if (s === 'red') return '#ff4d4f';
 	if (s === 'yellow') return '#ffc107';
 	return '#88fd54';
 }
+
+// ────────────────────────────────────────────────────────────
+// API 模式(真实数据;默认)
+// ────────────────────────────────────────────────────────────
+function apiToneColor(tone: ProcurementApiStatusTone): string {
+	if (tone === 'red') return '#ff4d4f';
+	if (tone === 'yellow') return '#ffc107';
+	if (tone === 'green') return '#88fd54';
+	return '#909097';
+}
+
+const isApiLoading = computed(() => mode.value === 'api' && !!props.loading);
+const apiErrorText = computed(() => (mode.value === 'api' ? (props.errorMessage ?? '').trim() : ''));
+const isApiError = computed(() => apiErrorText.value.length > 0);
+const isApiEmpty = computed(() => {
+	if (mode.value !== 'api') return false;
+	if (isApiLoading.value || isApiError.value) return false;
+	const d = props.apiDetail;
+	if (!d) return true;
+	return d.processes.length === 0 && d.lossFactors.length === 0 && d.operators.length === 0;
+});
+
+// 「作业效率损失」高亮:与 fixture 视觉一致;用 factorCode 而非 factorName 判定,避免后端名称变更打破样式。
+function highlightLossRow(factorCode: string): boolean {
+	return factorCode === 'EFFICIENCY';
+}
 </script>
 
 <template>
@@ -19,61 +68,155 @@ function statusColor(s: StageDetailStatus): string {
 		<header class="mfg-panel__head">
 			<span class="mfg-panel__bar" />
 			<h2 class="mfg-panel__title">设备制造(本体生产) · 阶段详情</h2>
+			<span v-if="mode === 'fixture'" class="mfg-panel__demo">演示数据</span>
 		</header>
 
-		<div class="mfg-panel__block">
-			<div class="mfg-panel__caption">工序明细</div>
-			<table class="mfg-panel__table">
-				<thead>
-					<tr><th>工序</th><th>PI</th><th>平均周期</th><th>周期状态</th><th>影响台次</th><th>计划达成率</th><th>计划状态</th></tr>
-				</thead>
-				<tbody>
-					<tr v-for="row in detail.processRows" :key="row.process">
-						<td>{{ row.process }}</td>
-						<td>{{ row.pi }}</td>
-						<td :style="{ color: statusColor(row.cycleStatus), fontWeight: 600 }">{{ row.avgCycle }}</td>
-						<td><span class="mfg-panel__dot" :style="{ background: statusColor(row.cycleStatus) }" /></td>
-						<td>{{ row.impactCount ?? '—' }}</td>
-						<td :style="{ color: statusColor(row.planRateStatus), fontWeight: 600 }">{{ row.planRate }}</td>
-						<td><span class="mfg-panel__dot" :style="{ background: statusColor(row.planRateStatus) }" /></td>
-					</tr>
-				</tbody>
-			</table>
-		</div>
-
-		<div class="mfg-panel__split">
-			<div class="mfg-panel__block mfg-panel__block--half">
-				<div class="mfg-panel__caption">10 工序 · 操作员表现</div>
+		<!-- fixture 模式(演示数据;非默认) -->
+		<template v-if="mode === 'fixture' && detail">
+			<div class="mfg-panel__block">
+				<div class="mfg-panel__caption">工序明细</div>
 				<table class="mfg-panel__table">
-					<thead><tr><th>操作员</th><th>平均工时</th><th>达标</th></tr></thead>
+					<thead>
+						<tr><th>工序</th><th>PI</th><th>平均周期</th><th>周期状态</th><th>影响台次</th><th>计划达成率</th><th>计划状态</th></tr>
+					</thead>
 					<tbody>
-						<tr v-for="row in detail.operators" :key="row.name">
-							<td>{{ row.name }}</td>
-							<td :style="{ color: statusColor(row.status), fontWeight: 600 }">{{ row.avgHours }}</td>
-							<td><span class="mfg-panel__dot" :style="{ background: statusColor(row.status) }" /></td>
+						<tr v-for="row in detail.processRows" :key="row.process">
+							<td>{{ row.process }}</td>
+							<td>{{ row.pi }}</td>
+							<td :style="{ color: fixtureStatusColor(row.cycleStatus), fontWeight: 600 }">{{ row.avgCycle }}</td>
+							<td><span class="mfg-panel__dot" :style="{ background: fixtureStatusColor(row.cycleStatus) }" /></td>
+							<td>{{ row.impactCount ?? '—' }}</td>
+							<td :style="{ color: fixtureStatusColor(row.planRateStatus), fontWeight: 600 }">{{ row.planRate }}</td>
+							<td><span class="mfg-panel__dot" :style="{ background: fixtureStatusColor(row.planRateStatus) }" /></td>
 						</tr>
 					</tbody>
 				</table>
 			</div>
-			<div class="mfg-panel__block mfg-panel__block--half">
-				<div class="mfg-panel__caption">10 工序 · 损失因素</div>
-				<table class="mfg-panel__table">
-					<thead><tr><th>因素</th><th>件数</th><th>占比</th><th>损失工时</th></tr></thead>
-					<tbody>
-						<tr
-							v-for="row in detail.lossFactors"
-							:key="row.factor"
-							:style="row.factor === '作业效率损失' ? { color: '#ff4d4f', fontWeight: 700 } : undefined"
-						>
-							<td>{{ row.factor }}</td>
-							<td>{{ row.count }}</td>
-							<td>{{ row.ratio }}</td>
-							<td>{{ row.lossHours }}</td>
-						</tr>
-					</tbody>
-				</table>
+
+			<div class="mfg-panel__split">
+				<div class="mfg-panel__block mfg-panel__block--half">
+					<div class="mfg-panel__caption">10 工序 · 操作员表现</div>
+					<table class="mfg-panel__table">
+						<thead><tr><th>操作员</th><th>平均工时</th><th>达标</th></tr></thead>
+						<tbody>
+							<tr v-for="row in detail.operators" :key="row.name">
+								<td>{{ row.name }}</td>
+								<td :style="{ color: fixtureStatusColor(row.status), fontWeight: 600 }">{{ row.avgHours }}</td>
+								<td><span class="mfg-panel__dot" :style="{ background: fixtureStatusColor(row.status) }" /></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+				<div class="mfg-panel__block mfg-panel__block--half">
+					<div class="mfg-panel__caption">10 工序 · 损失因素</div>
+					<table class="mfg-panel__table">
+						<thead><tr><th>因素</th><th>件数</th><th>占比</th><th>损失工时</th></tr></thead>
+						<tbody>
+							<tr
+								v-for="row in detail.lossFactors"
+								:key="row.factor"
+								:style="row.factor === '作业效率损失' ? { color: '#ff4d4f', fontWeight: 700 } : undefined"
+							>
+								<td>{{ row.factor }}</td>
+								<td>{{ row.count }}</td>
+								<td>{{ row.ratio }}</td>
+								<td>{{ row.lossHours }}</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+			</div>
+		</template>
+
+		<!-- API 模式(真实数据;默认) -->
+		<template v-else>
+			<div v-if="isApiLoading" class="mfg-panel__placeholder">本体生产数据加载中…</div>
+			<div v-else-if="isApiError" class="mfg-panel__placeholder mfg-panel__placeholder--error">
+				{{ apiErrorText || '本体生产数据加载失败,请稍后重试' }}
 			</div>
-		</div>
+			<div v-else-if="isApiEmpty" class="mfg-panel__placeholder">暂无本体生产数据</div>
+
+			<template v-else-if="apiDetail">
+				<div class="mfg-panel__block">
+					<div class="mfg-panel__caption">工序明细</div>
+					<table class="mfg-panel__table">
+						<thead>
+							<tr><th>工序</th><th>PI</th><th>平均周期</th><th>周期状态</th><th>计划台次</th><th>计划达成率</th><th>达成状态</th></tr>
+						</thead>
+						<tbody>
+							<tr v-if="apiDetail.processes.length === 0">
+								<td colspan="7" class="mfg-panel__cell-empty">暂无数据</td>
+							</tr>
+							<tr
+								v-for="row in apiDetail.processes"
+								:key="`api-proc-${row.processCode}`"
+								:style="{ fontWeight: row.isTotal ? 700 : 500 }"
+							>
+								<td>{{ row.processName }}</td>
+								<td>{{ row.pi || '—' }}</td>
+								<td :style="{ color: apiToneColor(row.cycleStatusTone), fontWeight: 600 }">
+									{{ row.avgCycle || '—' }}
+								</td>
+								<td><span class="mfg-panel__dot" :style="{ background: apiToneColor(row.cycleStatusTone) }" /></td>
+								<td>{{ row.planQty || '—' }}</td>
+								<td :style="{ color: apiToneColor(row.achievementStatusTone), fontWeight: 600 }">
+									{{ row.achievementRate || '—' }}
+								</td>
+								<td><span class="mfg-panel__dot" :style="{ background: apiToneColor(row.achievementStatusTone) }" /></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+
+				<div class="mfg-panel__split">
+					<div class="mfg-panel__block mfg-panel__block--half">
+						<div class="mfg-panel__caption">10 工序 · 操作员表现</div>
+						<table class="mfg-panel__table">
+							<thead><tr><th>操作员</th><th>平均工时</th><th>达标</th></tr></thead>
+							<tbody>
+								<tr v-if="apiDetail.operators.length === 0">
+									<td colspan="3" class="mfg-panel__cell-empty">暂无数据</td>
+								</tr>
+								<tr v-for="row in apiDetail.operators" :key="`api-op-${row.operatorCode}`">
+									<td>{{ row.operatorName }}</td>
+									<td :style="{ color: apiToneColor(row.statusTone), fontWeight: 600 }">
+										{{ row.avgHours || '—' }}
+									</td>
+									<td><span class="mfg-panel__dot" :style="{ background: apiToneColor(row.statusTone) }" /></td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+					<div class="mfg-panel__block mfg-panel__block--half">
+						<div class="mfg-panel__caption">10 工序 · 损失因素</div>
+						<table class="mfg-panel__table">
+							<thead><tr><th>因素</th><th>件数</th><th>占比</th><th>损失工时</th></tr></thead>
+							<tbody>
+								<tr v-if="apiDetail.lossFactors.length === 0">
+									<td colspan="4" class="mfg-panel__cell-empty">暂无数据</td>
+								</tr>
+								<tr
+									v-for="row in apiDetail.lossFactors"
+									:key="`api-loss-${row.factorCode}`"
+									:style="
+										highlightLossRow(row.factorCode)
+											? { color: '#ff4d4f', fontWeight: 700 }
+											: row.isSubtotal
+												? { fontWeight: 700 }
+												: undefined
+									"
+								>
+									<td>{{ row.factorName }}</td>
+									<td>{{ row.count || '—' }}</td>
+									<td>{{ row.ratio || '—' }}</td>
+									<td>{{ row.lossHours || '—' }}</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</template>
+		</template>
 	</section>
 </template>
 
@@ -82,6 +225,10 @@ function statusColor(s: StageDetailStatus): string {
 .mfg-panel__head { display: flex; align-items: center; gap: 10px; }
 .mfg-panel__bar { width: 5px; height: 18px; border-radius: 999px; background: var(--order-accent, #7bd0ff); }
 .mfg-panel__title { margin: 0; font-size: 16px; font-weight: 700; }
+.mfg-panel__demo {
+	margin-left: 6px; padding: 2px 10px; border-radius: 999px; font-size: 11px;
+	color: #ffc107; background: rgba(255,193,7,0.1); border: 1px solid rgba(255,193,7,0.32);
+}
 .mfg-panel__block { background: rgba(25, 28, 34, 0.55); border: 1px solid rgba(69, 70, 77, 0.28); border-radius: 10px; padding: 12px; overflow-x: auto; }
 .mfg-panel__split { display: flex; gap: 12px; }
 .mfg-panel__block--half { flex: 1; min-width: 0; }
@@ -94,4 +241,13 @@ function statusColor(s: StageDetailStatus): string {
 }
 .mfg-panel__table th { background: rgba(15, 19, 26, 0.7); font-weight: 600; font-family: 'PingFang SC', sans-serif; }
 .mfg-panel__dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; }
+.mfg-panel__cell-empty { color: var(--order-text-muted, #909097); font-style: italic; }
+.mfg-panel__placeholder {
+	padding: 24px; text-align: center; font-size: 13px;
+	color: var(--order-text-muted, #909097);
+	background: rgba(25, 28, 34, 0.55);
+	border: 1px solid rgba(69, 70, 77, 0.28);
+	border-radius: 10px;
+}
+.mfg-panel__placeholder--error { color: #ff4d4f; }
 </style>

+ 172 - 0
Web/src/views/aidop/s8/monitoring/data/order-execution/stage-detail.ts

@@ -386,3 +386,175 @@ export function isProcurementDetailEmpty(detail: ProcurementDetailFromApi | null
 	if (!detail) return true;
 	return detail.keyMaterials.length === 0 && detail.sections.length === 0;
 }
+
+// ============================================================
+// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:本体生产 API 适配层。
+// 把后端 OrderFlowManufacturingPivot 转换为 ManufacturingDetailPanel 可消费的视图结构。
+// 单位渲染:actualDays/piDays → "X天";achievementRate(0~1) → "XX%";avgHours → "XH";
+// lossHours → "X.XXH";ratioPct(0~100) → "XX%";TOTAL 占位统一展示为「合计」。
+// status tone 复用 procurement 的映射;未识别值返回 'pending'。
+// ============================================================
+
+import type {
+	OrderFlowManufacturingPivot,
+	OrderFlowManufacturingProcess,
+	OrderFlowManufacturingLossFactor,
+	OrderFlowManufacturingOperator,
+} from '/@/views/aidop/s8/api/s8OrderFlowDomainApi';
+
+/** 后端 process_code / factor_code 中的 TOTAL/SUBTOTAL 占位 */
+export const MANUFACTURING_PIVOT_TOTAL_PROCESS_CODE = 'TOTAL';
+export const MANUFACTURING_PIVOT_SUBTOTAL_FACTOR_CODE = 'SUBTOTAL';
+
+export interface ManufacturingApiProcessRow {
+	processCode: string;
+	processName: string;
+	pi: string;
+	avgCycle: string;
+	cycleStatus: string;
+	cycleStatusTone: ProcurementApiStatusTone;
+	planQty: string;
+	achievementRate: string;
+	achievementStatus: string;
+	achievementStatusTone: ProcurementApiStatusTone;
+	sortNo: number;
+	isTotal: boolean;
+}
+
+export interface ManufacturingApiLossFactorRow {
+	factorCode: string;
+	factorName: string;
+	count: string;
+	ratio: string;
+	lossHours: string;
+	sortNo: number;
+	isSubtotal: boolean;
+}
+
+export interface ManufacturingApiOperatorRow {
+	operatorCode: string;
+	operatorName: string;
+	avgHours: string;
+	status: string;
+	statusTone: ProcurementApiStatusTone;
+	sortNo: number;
+}
+
+export interface ManufacturingDetailFromApi {
+	processes: ManufacturingApiProcessRow[];
+	lossFactors: ManufacturingApiLossFactorRow[];
+	operators: ManufacturingApiOperatorRow[];
+}
+
+function formatDaysWithUnit(value: number | null | undefined): string {
+	if (value == null || Number.isNaN(value)) return '';
+	const num = typeof value === 'number' ? value : Number(value);
+	if (Number.isNaN(num)) return '';
+	// 保留至多 3 位小数;整数不带小数点;尾随 "天"。
+	const rounded = Math.round(num * 1000) / 1000;
+	const text = Number.isInteger(rounded) ? String(rounded) : String(rounded);
+	return `${text}天`;
+}
+
+function formatHoursWithUnit(value: number | null | undefined, decimals: number = 2): string {
+	if (value == null || Number.isNaN(value)) return '';
+	const num = typeof value === 'number' ? value : Number(value);
+	if (Number.isNaN(num)) return '';
+	const factor = Math.pow(10, decimals);
+	const rounded = Math.round(num * factor) / factor;
+	if (Number.isInteger(rounded)) return `${rounded}H`;
+	return `${rounded}H`;
+}
+
+function formatPercentRate01(value: number | null | undefined): string {
+	if (value == null || Number.isNaN(value)) return '';
+	const num = typeof value === 'number' ? value : Number(value);
+	if (Number.isNaN(num)) return '';
+	const pct = num <= 1 ? num * 100 : num;
+	return `${Math.round(pct)}%`;
+}
+
+function formatPercentPct(value: number | null | undefined): string {
+	if (value == null || Number.isNaN(value)) return '';
+	const num = typeof value === 'number' ? value : Number(value);
+	if (Number.isNaN(num)) return '';
+	// ratio_pct 已经是 0~100 范围;不再 *100。
+	return `${Math.round(num)}%`;
+}
+
+function formatIntegerOrEmpty(value: number | null | undefined): string {
+	if (value == null || Number.isNaN(value)) return '';
+	return String(value);
+}
+
+function adaptManufacturingProcessRow(row: OrderFlowManufacturingProcess): ManufacturingApiProcessRow {
+	const isTotal = row.processCode === MANUFACTURING_PIVOT_TOTAL_PROCESS_CODE;
+	return {
+		processCode: row.processCode,
+		processName: row.processName,
+		pi: formatDaysWithUnit(row.piDays),
+		avgCycle: formatDaysWithUnit(row.actualDays),
+		cycleStatus: row.cycleStatus ?? '',
+		cycleStatusTone: mapProcurementStatusTone(row.cycleStatus),
+		planQty: isTotal ? '' : formatIntegerOrEmpty(row.planQty),
+		achievementRate: formatPercentRate01(row.achievementRate),
+		achievementStatus: row.achievementStatus ?? '',
+		achievementStatusTone: mapProcurementStatusTone(row.achievementStatus),
+		sortNo: row.sortNo,
+		isTotal,
+	};
+}
+
+function adaptManufacturingLossRow(row: OrderFlowManufacturingLossFactor): ManufacturingApiLossFactorRow {
+	const isSubtotal = row.factorCode === MANUFACTURING_PIVOT_SUBTOTAL_FACTOR_CODE;
+	return {
+		factorCode: row.factorCode,
+		factorName: row.factorName,
+		count: formatIntegerOrEmpty(row.countValue),
+		ratio: formatPercentPct(row.ratioPct),
+		lossHours: formatHoursWithUnit(row.lossHours),
+		sortNo: row.sortNo,
+		isSubtotal,
+	};
+}
+
+function adaptManufacturingOperatorRow(row: OrderFlowManufacturingOperator): ManufacturingApiOperatorRow {
+	return {
+		operatorCode: row.operatorCode,
+		operatorName: row.operatorName,
+		avgHours: formatHoursWithUnit(row.avgHours, 2),
+		status: row.status ?? '',
+		statusTone: mapProcurementStatusTone(row.status),
+		sortNo: row.sortNo,
+	};
+}
+
+export function adaptManufacturingPivotFromApi(
+	pivot: OrderFlowManufacturingPivot | null | undefined,
+): ManufacturingDetailFromApi | null {
+	if (!pivot) return null;
+	const processes = (pivot.processes ?? [])
+		.slice()
+		.sort((a, b) => a.sortNo - b.sortNo)
+		.map(adaptManufacturingProcessRow);
+	const lossFactors = (pivot.lossFactors ?? [])
+		.slice()
+		.sort((a, b) => a.sortNo - b.sortNo)
+		.map(adaptManufacturingLossRow);
+	const operators = (pivot.operators ?? [])
+		.slice()
+		.sort((a, b) => a.sortNo - b.sortNo)
+		.map(adaptManufacturingOperatorRow);
+	return { processes, lossFactors, operators };
+}
+
+export function isManufacturingDetailEmpty(
+	detail: ManufacturingDetailFromApi | null | undefined,
+): boolean {
+	if (!detail) return true;
+	return (
+		detail.processes.length === 0 &&
+		detail.lossFactors.length === 0 &&
+		detail.operators.length === 0
+	);
+}

+ 10 - 0
doc/README.md

@@ -47,6 +47,16 @@
 | [Windows后端WinSW守护重启方案.md](./Windows后端WinSW守护重启方案.md) | Windows 服务器上使用 WinSW 守护后端服务、自动重启与日志落盘 |
 | [plan/S1/S1-订单管理-审批流程实施方案.md](./plan/S1/S1-订单管理-审批流程实施方案.md) | S1 订单审批实施方案 |
 | [plan/S1-S3业务逻辑测试与数据准备方案.md](./plan/S1-S3业务逻辑测试与数据准备方案.md) | S1-S3 完整业务逻辑测试 case 与测试数据准备方案 |
+| [plan/S1-S4全局UAT场景测试数据生成方案.md](./plan/S1-S4全局UAT场景测试数据生成方案.md) | S1-S4 全局 UAT 场景测试数据主线,要求订单、工单、物料、采购、交货跨模块串联 |
+| [plan/S1/S1产销协同UAT测试数据抽取与导入方案.md](./plan/S1/S1产销协同UAT测试数据抽取与导入方案.md) | S1 UAT 场景化测试数据抽取范围、AIDOP 租户归属、导入顺序与验收 SQL |
+| [plan/S1/S1产销协同UAT候选数据清单与导入映射.md](./plan/S1/S1产销协同UAT候选数据清单与导入映射.md) | S1 UAT 首批候选单号、场景化造数原则、目标表映射、批次标记与 SQL 草案 |
+| [plan/S1/S1产销协同UAT数据生成执行任务书.md](./plan/S1/S1产销协同UAT数据生成执行任务书.md) | 给其它大模型或协作者执行 S1 UAT 数据生成的阶段任务、约束、确认点与验收标准 |
+| [plan/S2/S2制造协同UAT测试数据生成方案.md](./plan/S2/S2制造协同UAT测试数据生成方案.md) | S2 制造协同 UAT 测试数据包、工单排程、产线日历、日计划、看板与验收方向 |
+| [plan/S2/S2制造协同UAT数据生成执行任务书.md](./plan/S2/S2制造协同UAT数据生成执行任务书.md) | 给其它大模型或协作者执行 S2 UAT 数据生成的阶段任务、约束、确认点与验收标准 |
+| [plan/S3/S3供应协同UAT测试数据生成方案.md](./plan/S3/S3供应协同UAT测试数据生成方案.md) | S3 供应协同 UAT 测试数据包、物料需求、交货计划、采购、委外外协与看板验收方向 |
+| [plan/S3/S3供应协同UAT数据生成执行任务书.md](./plan/S3/S3供应协同UAT数据生成执行任务书.md) | 给其它大模型或协作者执行 S3 UAT 数据生成的阶段任务、约束、确认点与验收标准 |
+| [plan/S4/S4采购执行UAT测试数据生成方案.md](./plan/S4/S4采购执行UAT测试数据生成方案.md) | S4 采购执行 UAT 测试数据包,当前以测试报告驱动,覆盖交货、发货、退货、IQC 与欠料看板 |
+| [plan/S4/S4采购执行UAT数据生成执行任务书.md](./plan/S4/S4采购执行UAT数据生成执行任务书.md) | 给其它大模型或协作者执行 S4 UAT 数据生成的阶段任务、约束、确认点与验收标准 |
 | [plan/S0-CodeFirst启动异常与BOM历史数据治理方案.md](./plan/S0-CodeFirst启动异常与BOM历史数据治理方案.md) | S0 legacy BOM 表 CodeFirst 启动异常、根因与彻底治理步骤 |
 | [plan/S8/S8数据库处理优化方案.md](./plan/S8/S8数据库处理优化方案.md) | S8 调度、检测日志、通知扫描与数据库写入压力优化方案 |
 | [plan/新系统数据库简明介绍与S1数据流.md](./plan/新系统数据库简明介绍与S1数据流.md) | 新系统数据库简明说明,并以 S1 为例说明数据中台流转 |

+ 230 - 0
doc/plan/S1-S4全局UAT场景测试数据生成方案.md

@@ -0,0 +1,230 @@
+# S1-S4 全局 UAT 场景测试数据生成方案
+
+## 1. 目标
+
+S1-S4 的 UAT 测试数据不能各模块独立造数,必须围绕同一批业务主线构造,形成可端到端验证的全局场景测试包。
+
+全局主线:
+
+```text
+S1 销售订单/交付需求
+  -> S2 工单/工序排程/日计划
+  -> S3 物料需求/采购申请/采购订单/齐套上线
+  -> S4 供应商交货/发货/IQC/退货/欠料
+  -> 回写 S3/S2/S1 看板、DWD、KPI
+```
+
+本方案不是生产迁移,不要求照搬旧库全字段和旧主键。旧 DOP 数据库仅作为真实业务素材库,最终目标是构造一套归属 AIDOP 租户、跨模块可串联、可演示、可反复测试的数据包。
+
+## 2. 核心约束
+
+| 项 | 值 |
+|----|----|
+| AIDOP 租户 ID | `797403760988229`(组织名 AIDOP;登录账号 `AIDOPDemo`) |
+| Demo 租户 ID | `1300000000888` |
+| 全局批次号 | `S1S4_UAT_20260604_RQ_V1` |
+| 旧库主素材 | SQL Server `dopdemorq` |
+| 目标库 | MySQL `aidopdev` |
+
+约束:
+
+- 所有数据必须写入 AIDOP 租户(`tenant_id = 797403760988229`),不得写入 Demo 租户(`1300000000888`)。勿与框架种子租户 `1300000000001`(系统默认)混淆。
+- S2/S3/S4 的 P0 数据优先复用 S1 的候选订单、订单明细、物料和客户。
+- S2 工单必须能追溯到 S1 订单明细。
+- S3 物料需求必须能追溯到 S2 工单或 S1 订单需求。
+- S4 交货、发货、退货必须能追溯到 S3 采购订单或交货计划。
+- 所有数据需带批次标记,便于人工识别、复查和必要时清理。
+- 不要求复杂回滚脚本。
+
+## 3. 全局 P0 场景包
+
+建议首轮 P0 只做 5-10 条完整链路订单,验证通过后再扩展到完整冗余包。
+
+### 3.1 主闭环样例
+
+| 链路节点 | 数据要求 |
+|----------|----------|
+| S1 销售订单 | 5-10 张销售订单,每单不少于 2 行订单明细 |
+| 客户/物料 | 每张订单能关联客户、成品物料、BOM 或关键半成品 |
+| S2 工单 | 每个订单明细至少生成或关联 1 个工单 |
+| S2 工序 | 每个工单不少于 2 道工序 |
+| S2 日计划 | 每个工单至少 1 条可执行日计划 |
+| S3 物料需求 | 每个工单至少 2 条物料需求 |
+| S3 采购申请 | 缺料物料生成采购申请 |
+| S3 采购订单 | 采购申请生成采购订单,每单不少于 2 行 |
+| S4 供应商交货 | 采购订单生成供应商交货记录 |
+| S4 供应商发货 | 部分交货记录生成发货单 |
+| S4 IQC/退货 | 至少 1 条 IQC 退货或采购退货样例 |
+| 看板/KPI | S1-S4 均有可统计指标和异常样例 |
+
+### 3.2 状态覆盖样例
+
+| 状态类型 | 数据要求 |
+|----------|----------|
+| 正常完成 | 订单、工单、采购、交货、发货完整闭环 |
+| 部分完成 | 订单部分发货、采购部分到货、工单部分完工 |
+| 异常延期 | 供应商延期导致 S3/S4 风险,并影响 S1 交付 |
+| 缺料风险 | S2 工单物料不足,S3 齐套上线看板显示缺料 |
+| 质量退货 | S4 IQC 不合格退货,影响 S3 供应风险 |
+| 空状态 | 某些跟踪子表为空,但主链路页面可正常展示 |
+
+## 4. 全局字段关联
+
+| 关联对象 | 全局关联键 | 说明 |
+|----------|------------|------|
+| 销售订单 | `order_no` / `bill_no` | S1 主线起点 |
+| 订单明细 | `order_line_id` / `item_code` | 关联成品、工单和需求 |
+| 工单 | `work_order_no` | S2 主线,需引用 S1 订单明细 |
+| 工序 | `work_order_no + operation_code` | 排程、外协、执行进度使用 |
+| 物料需求 | `work_order_no + item_code` | S3 需求计划与齐套 |
+| 采购申请 | `pr_no` | 来源于缺料需求 |
+| 采购订单 | `po_no` | S3/S4 共用主线 |
+| 采购订单行 | `po_no + line_no + item_code` | 关联交货、发货、退货 |
+| 供应商 | `supplier_code` | S3/S4 供应商维度 |
+| 交货计划 | `delivery_plan_no` | S3 交货计划,S4 交货管理来源 |
+| 供应商发货单 | `ship_no` | S4 发货、标签、IQC |
+| IQC/退货 | `inspection_no` / `return_no` | 质量退货和采购退货 |
+
+## 5. 模块职责边界
+
+### 5.1 S1 产销协同
+
+S1 是全局链路起点,负责提供:
+
+- 销售订单和订单明细。
+- 客户和成品物料。
+- 交付日期和交付状态。
+- 订单交付看板和 S1 KPI。
+
+### 5.2 S2 制造协同
+
+S2 必须基于 S1 订单明细生成或关联:
+
+- 工单。
+- 工序排程。
+- 可执行日计划。
+- 产线日历、休息、节假日、加班。
+- 工单执行进度。
+- S2 看板和 KPI。
+
+### 5.3 S3 供应协同
+
+S3 必须基于 S2 工单和物料缺口生成或关联:
+
+- 物料需求计划。
+- 采购申请。
+- 采购订单。
+- 交货计划。
+- 委外/外协订单。
+- 齐套上线看板。
+- S3 看板和 KPI。
+
+### 5.4 S4 采购执行
+
+S4 必须基于 S3 采购订单和交货计划生成或关联:
+
+- 供应商交货记录。
+- 供应商发货单。
+- 标签、送货单、质检附件。
+- 采购退货单。
+- IQC 退货查询。
+- 供应商欠料看板。
+- S4 看板和 KPI。
+
+S4 尚未完全完成开发,当前先按测试报告设计全局链路占位。待功能完成后需补做页面/API/表结构/数据中台链路交叉校验。
+
+## 6. 数据规模建议
+
+### 6.1 P0 试导
+
+| 数据类型 | 建议数量 |
+|----------|----------|
+| S1 销售订单 | 5-10 张 |
+| S1 订单明细 | 10-30 行 |
+| S2 工单 | 10-20 个 |
+| S2 工序 | 20-60 行 |
+| S2 日计划 | 10-30 行 |
+| S3 物料需求 | 20-80 行 |
+| S3 采购申请 | 5-15 张 |
+| S3/S4 采购订单 | 5-15 张 |
+| S4 交货记录 | 10-30 行 |
+| S4 发货单 | 3-10 张 |
+| S4 IQC/退货 | 2-5 张 |
+
+### 6.2 完整 UAT 包
+
+| 数据类型 | 建议数量 |
+|----------|----------|
+| S1 销售订单 | 50 张左右 |
+| S1 订单明细 | 150-300 行 |
+| S2 工单 | 80-150 个 |
+| S2 工序 | 200-500 行 |
+| S3 物料需求 | 300-1,000 行 |
+| 采购订单 | 50-150 张 |
+| 供应商 | 20-50 个 |
+| S4 发货/退货/IQC | 50-150 张 |
+
+## 7. 生成顺序
+
+1. 选定 S1 全局订单样本。
+2. 基于 S1 订单明细生成 S2 工单和工序。
+3. 基于 S2 工单生成物料需求和缺料样例。
+4. 基于 S3 物料需求生成采购申请和采购订单。
+5. 基于采购订单生成 S4 供应商交货和发货。
+6. 基于发货/收货生成 IQC、退货和欠料样例。
+7. 补造各模块异常、空状态和看板 KPI。
+8. 执行 S1-S4 MDP/DWD/KPI 验收。
+
+## 8. 验收顺序
+
+1. 验证所有业务表 `tenant_id = 797403760988229`。
+2. 验证 S1 订单能找到 S2 工单。
+3. 验证 S2 工单能找到 S3 物料需求。
+4. 验证 S3 物料需求能找到采购申请和采购订单。
+5. 验证 S3 采购订单能找到 S4 交货和发货。
+6. 验证 S4 IQC/退货能回写供应风险和欠料。
+7. 验证 S1-S4 页面和看板均能查询同一批主线数据。
+8. 验证 S1-S4 KPI 均有数据。
+
+## 9. 给执行模型的提示词
+
+```text
+你要为 Ai-DOP 新系统 UAT 环境生成 S1-S4 全局场景测试数据。
+
+请严格阅读:
+1. doc/plan/S1-S4全局UAT场景测试数据生成方案.md
+2. doc/plan/S1/S1产销协同UAT测试数据抽取与导入方案.md
+3. doc/plan/S2/S2制造协同UAT测试数据生成方案.md
+4. doc/plan/S3/S3供应协同UAT测试数据生成方案.md
+5. doc/plan/S4/S4采购执行UAT测试数据生成方案.md
+
+核心要求:
+- S1-S4 数据必须围绕同一批订单、工单、物料、供应商、采购订单串起来。
+- S2 工单必须来源于 S1 订单明细。
+- S3 物料需求必须来源于 S2 工单或 S1 订单需求。
+- S4 交货/发货/退货必须来源于 S3 采购订单。
+- 所有数据必须写入 AIDOP 租户 tenant_id = 797403760988229。
+- 不得写入 Demo 租户 tenant_id = 1300000000888。
+- 第一阶段只允许只读检查和生成 P0 SQL,未经人工确认不得写库。
+```
+
+## 10. 注意事项
+
+- 不要让 S2/S3/S4 独立造一批互不相关的数据。
+- 不要只满足单页面查询,必须满足跨模块下钻和看板统计。
+- 不要全量导入旧库。
+- S4 当前以测试报告驱动,待开发完成后必须复核字段和接口。
+- 不要把数据库密码写入脚本、日志或 Git。
+
+## 11. 相关文档与脚本(索引)
+
+| 用途 | 路径 |
+|------|------|
+| 测试人员指南 | [S1S2S3_UAT测试指南.md](./S1S2S3_UAT测试指南.md) |
+| P0 执行 / 抽数 | [sql/S1S4_UAT_P0_execute_write.sql](./sql/S1S4_UAT_P0_execute_write.sql)、[S1S4_UAT_P0_抽数记录_20260604.md](./S1S4_UAT_P0_抽数记录_20260604.md) |
+| 完整包(50 单) | [sql/S1S4_UAT_FULL_execute_write.sql](./sql/S1S4_UAT_FULL_execute_write.sql)、[S1S4_UAT_FULL_执行记录_20260605.md](./S1S4_UAT_FULL_执行记录_20260605.md) |
+| 租户迁正(曾误写系统默认) | [sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql](./sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql) |
+| P0 冒烟 / 只读检查 | [S1S4_UAT_P0_冒烟验收报告_20260605.md](./S1S4_UAT_P0_冒烟验收报告_20260605.md)、[S1S4_UAT_P0_只读检查报告_20260604.md](./S1S4_UAT_P0_只读检查报告_20260604.md) |
+| S1 候选与映射 | [S1/S1产销协同UAT候选数据清单与导入映射.md](./S1/S1产销协同UAT候选数据清单与导入映射.md) |
+
+**登录验收**:租户 **AIDOP** `797403760988229`,账号 **`AIDOPDemo`** / `1234567890dop`;列表检索 `MPO482024102300001` 应 ≥1 条。

+ 467 - 0
doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md

@@ -0,0 +1,467 @@
+# S1 产销协同 UAT 候选数据清单与导入映射
+
+## 1. 文档目的
+
+本文记录 S1 产销协同 UAT 首批测试数据的候选样本、场景化造数原则、目标表映射、导入顺序和 SQL 草案。
+
+本轮目标不是将旧 DOP 数据原样迁移到新系统,而是基于旧库真实业务样本,构造一套归属 AIDOP 租户、能在新系统完整串联的 UAT 测试数据。
+
+## 2. 执行原则
+
+- 旧库 `dopdemorq` 仅作为真实业务素材库,用于参考订单、客户、物料、数量、交期、工单、核验、排程、发货和 ASN 的真实取值。
+- UAT 新系统数据以场景闭环为目标,可以生成新 ID、补齐缺失字段、补造缺失环节。
+- 所有导入数据统一归属 AIDOP 租户:`tenant_id = 797403760988229`。
+- 不写入 Demo 租户:`tenant_id = 1300000000888`。
+- 每次导入必须带批次标记,推荐批次号:`S1_UAT_20260604_RQ_V1`。
+- 优先小批量试导 5-10 单,验证页面、MDP、DWD、KPI 后再扩大到完整数据包。
+- 本轮仅用于 UAT 测试数据准备,不要求复杂回滚脚本;重点是避免覆盖现有数据、批次可识别、必要时可人工清理。
+
+## 3. 已确认环境信息
+
+| 项 | 值 |
+|----|----|
+| 旧库来源 | SQL Server `dopdemorq`,瑞奇生产备份脱敏库 |
+| UAT 目标库 | MySQL `aidopdev` |
+| AIDOP 租户 ID | `797403760988229` |
+| Demo 租户 ID | `1300000000888` |
+| 建议批次号 | `S1_UAT_20260604_RQ_V1` |
+| 首批候选单号数量 | 52 |
+| 旧库候选销售订单 | 27 |
+| 旧库候选销售订单明细 | 305 |
+| 旧库候选需求核验单 | 391 |
+| 旧库候选需求核验明细 | 18,736 |
+| 旧库候选工单 | 320 |
+| 旧库候选排程明细 | 76 |
+| 旧库候选排程结果 | 69 |
+| 旧库候选发货计划明细 | 22 |
+| 旧库候选 ASN 主单 | 20 |
+
+## 4. 首批候选单号
+
+### 4.1 P0 完整闭环优先样例
+
+这些单号优先用于 5-10 单试导,重点验证 S1 主链路。
+
+| 单号 | 建议用途 | 说明 |
+|------|----------|------|
+| `MPO482024102300001` | 完整闭环主样例 | 覆盖销售订单、工单、排程、排程结果、需求核验 |
+| `MPO482025010900002` | 小体量闭环样例 | 覆盖链路较完整,适合冒烟测试 |
+| `MPO482025012100001` | 订单 + 核验 + 工单 + 发货 | 可验证交付侧衔接 |
+| `MPO482024120200003` | 需求核验样例 | 需求核验明细丰富 |
+| `MPO482025010800003` | 核验 + 发货 + ASN | 适合发货计划与 ASN 验证 |
+| `MPO482025011300004` | 工单排程样例 | 覆盖工单、排程和排程结果 |
+| `MPO482025042800001` | 发货计划样例 | 发货计划明细较多 |
+| `SO241020241018001` | 客户订单样例 | 客户为 `CUST0005 / ET0005` |
+| `SO241020241015003` | 客户订单样例 | 客户为 `CUST0005 / ET0005` |
+| `SO241020241021002` | ASN 冗余样例 | 可用于发货侧重复测试 |
+
+### 4.2 P1 冗余测试样例
+
+这些单号用于扩大测试覆盖,便于多轮演示、查询、筛选和统计。
+
+```text
+10014153
+10015150
+10015151
+MPO482025043000001
+MPO482025012000003
+MPO482025042800002
+15002336
+MPO482024041100002
+10014130
+MPO482024121400001
+MPO482024060400002
+MPO482024052700001
+MPO482024053100002
+MPO482024091800004
+15002337
+MPO482024052900002
+MPO482024061500001
+MPO482024051600003
+MPO482024120200004
+MPO482024082800001
+15002328
+MPO482024081900004
+MPO482023121900001
+10014160
+MPO482025081500002
+MPO482025091900001
+SO241020241219001
+MPO482025081500001
+MPO482025041300001
+MPO482025062100003
+SO241020240923001
+MPO482025062100002
+MPO482024102400001
+MPO482025051800001
+SO241020250114003
+MPO482025092200002
+MPO482025022100001
+MPO482025032900001
+MPO482025091800003
+MPO482025082900002
+MPO482025062600003
+MPO482025090400005
+```
+
+## 5. 目标表与场景映射
+
+| 场景 | 目标业务表 | 后续平台层 | 处理策略 |
+|------|------------|------------|----------|
+| 销售订单 | `crm_seorder`、`crm_seorderentry` | `mdp_stg_so`、`mdp_std_so`、`ado_s1_sales_order`、`ado_s1_sales_order_line` | 以旧库订单为蓝本,生成新系统 ID,保留单号和业务字段 |
+| 需求核验 | `b_order_examine_result`、`b_order_detail` | `dwd_requirement_examine_detail` | 可按旧库核验明细抽样,不要求全部 18,736 行一次导入 |
+| 工单 | `mes_morder`、`mes_moentry` | `dwd_order_schedule_trans`、S2 相关看板 | 以订单明细为主线生成工单,保持订单明细到工单关联 |
+| 排程 | `PeriodSequenceDet`、`ScheduleResultOpMaster` | `mdp_std_operation_schedule`、`dwd_order_schedule_trans` | 可保留真实排程日期和工序,也可补齐缺失状态 |
+| 发货计划 | `ShippingPlan`、`ShippingPlanDetail` | `mdp_stg_ship_trans`、`mdp_std_ship_trans`、`dwd_ship_trans` | 保留发货数量、交期、客户信息 |
+| ASN | `ASNBOLShipperMaster`、`ASNBOLShipperDetail` | `dwd_ship_trans` | 可按订单补造明细,支撑发货确认和交付追踪 |
+| 交付承诺/变更 | `ado_s1_delivery_promise`、`ado_s1_delivery_change` | S1 页面与 KPI | 旧库无完整链路时,按订单补造 |
+| 计划联动 | 新系统计划联动表 | S1/S2 联动页面 | 旧库未发现 `LinkagePlan`,应在新系统侧生成样例 |
+
+## 6. 主键与关联策略
+
+### 6.1 不保留旧库主键作为强约束
+
+旧库销售订单、核验、工单多为雪花 ID;发货、ASN、排程部分表为 `RecID` 小整数或业务系统序号。为了避免 UAT 已有数据冲突,建议统一采用新系统 ID 生成策略。
+
+### 6.2 建议使用临时映射表
+
+导入脚本执行期建议维护临时映射表,不长期保留到业务库。
+
+```sql
+CREATE TEMPORARY TABLE tmp_s1_uat_id_map (
+  batch_no varchar(64) NOT NULL,
+  entity_name varchar(64) NOT NULL,
+  source_key varchar(128) NOT NULL,
+  target_id bigint NOT NULL,
+  ref_key varchar(128) NULL,
+  PRIMARY KEY (batch_no, entity_name, source_key)
+);
+```
+
+映射示例:
+
+| entity_name | source_key | target_id | ref_key |
+|-------------|------------|-----------|---------|
+| `crm_seorder` | 旧库 `crm_seorder.Id` | 新生成订单 ID | `bill_no` |
+| `crm_seorderentry` | 旧库 `crm_seorderentry.Id` | 新生成订单明细 ID | 新订单 ID |
+| `b_order_examine_result` | 旧库 `b_examine_result.Id` | 新生成核验 ID | `bill_no` |
+| `b_order_detail` | 旧库 `b_bom_child_examine.Id` | 新生成核验明细 ID | 新核验 ID |
+| `mes_morder` | 旧库 `mes_morder.Id` | 新生成工单 ID | `morder_no` |
+| `mes_moentry` | 旧库 `mes_moentry.Id` | 新生成工单明细 ID | 新工单 ID |
+
+## 7. 字段处理原则
+
+### 7.1 必须保留或生成的字段
+
+- `tenant_id`:固定为 `797403760988229`。
+- `batch_no` 或可承载批次的备注字段:建议写入 `S1_UAT_20260604_RQ_V1`。
+- 订单号、工单号、客户编码、客户名称、物料编码、物料名称、数量、计划日期、交付日期:优先取旧库真实值。
+- `create_time`、`update_time`:可统一设置为导入时间。
+- `IsDeleted` / `is_deleted`:统一未删除。
+
+### 7.2 可补造字段
+
+- `factory_id`、`org_id`、`company_id`:优先使用 AIDOP 租户默认组织;若无法确认,先置空或使用现有 AIDOP 示例数据同值。
+- `create_by`、`create_by_name`:可使用 UAT 测试账号或系统导入账号。
+- 合同评审、设计任务、计划联动、交付承诺、交付变更:旧库链路缺失时按订单补造。
+
+### 7.3 可抽样字段
+
+需求核验明细旧库候选量为 18,736 行,首批不建议全量导入。建议:
+
+- P0 试导:每个核验单保留 10-30 行关键明细,覆盖缺料、齐套、自制、采购、替代料等状态。
+- 完整 UAT 包:保留 2,000-5,000 行核验明细即可,避免页面和转换任务过重。
+
+## 8. 建议导入顺序
+
+1. 基础租户与组织确认:`SysTenant`、`SysOrg`、`SysUser`。
+2. 销售订单主表:`crm_seorder`。
+3. 销售订单明细:`crm_seorderentry`。
+4. 需求核验主表:`b_order_examine_result`。
+5. 需求核验明细:`b_order_detail`。
+6. 工单主表:`mes_morder`。
+7. 工单关联明细:`mes_moentry`。
+8. 排程明细:`PeriodSequenceDet`。
+9. 排程结果:`ScheduleResultOpMaster`。
+10. 发货计划:`ShippingPlan`、`ShippingPlanDetail`。
+11. ASN:`ASNBOLShipperMaster`、`ASNBOLShipperDetail`。
+12. 新系统补造数据:交付承诺、交付变更、计划联动、合同评审、设计任务。
+13. 运行 S1 MDP 转换任务。
+14. 验证 DWD、KPI、S1 页面和主要 Tab。
+
+## 9. SQL 草案
+
+以下 SQL 是执行草案,正式执行前需要根据 ID 生成函数、组织 ID、用户 ID 和目标表最新字段再做一次核对。
+
+### 9.1 导入批次变量
+
+```sql
+SET @tenant_id = 797403760988229;
+SET @batch_no = 'S1_UAT_20260604_RQ_V1';
+SET @operator_id = 1300000000111;
+SET @operator_name = 'UAT数据导入';
+SET @now = NOW();
+```
+
+### 9.2 导入前重复检查
+
+```sql
+SELECT bill_no, tenant_id, COUNT(*) AS rows_count
+FROM crm_seorder
+WHERE bill_no IN (
+  'MPO482024102300001',
+  'MPO482025010900002',
+  'MPO482025012100001',
+  'MPO482024120200003',
+  'MPO482025010800003',
+  'MPO482025011300004',
+  'MPO482025042800001',
+  'SO241020241018001',
+  'SO241020241015003',
+  'SO241020241021002'
+)
+GROUP BY bill_no, tenant_id;
+```
+
+预期:首次试导前返回空结果。
+
+### 9.3 销售订单导入模板
+
+推荐先从旧库抽取候选订单为中间 CSV 或临时表,再导入 MySQL。临时表字段只保留新系统需要的业务字段。
+
+```sql
+CREATE TEMPORARY TABLE tmp_s1_uat_so (
+  source_id varchar(128) NOT NULL,
+  target_id bigint NOT NULL,
+  bill_no varchar(64) NOT NULL,
+  custom_no varchar(64) NULL,
+  custom_name varchar(128) NULL,
+  order_date datetime NULL,
+  delivery_date datetime NULL,
+  urgent int NULL,
+  status int NULL,
+  PRIMARY KEY (source_id)
+);
+
+INSERT INTO crm_seorder (
+  Id, bill_no, custom_no, custom_name, date, rdate, urgent, status,
+  bill_from, create_by, create_by_name, create_time,
+  update_by, update_by_name, update_time,
+  tenant_id, IsDeleted
+)
+SELECT
+  target_id,
+  bill_no,
+  custom_no,
+  custom_name,
+  order_date,
+  delivery_date,
+  COALESCE(urgent, 0),
+  COALESCE(status, 1),
+  CONCAT('UAT导入:', @batch_no),
+  @operator_id,
+  @operator_name,
+  @now,
+  @operator_id,
+  @operator_name,
+  @now,
+  @tenant_id,
+  0
+FROM tmp_s1_uat_so;
+```
+
+### 9.4 销售订单明细导入模板
+
+```sql
+CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
+  source_id varchar(128) NOT NULL,
+  target_id bigint NOT NULL,
+  source_order_id varchar(128) NOT NULL,
+  entry_seq int NULL,
+  item_number varchar(64) NULL,
+  item_name varchar(128) NULL,
+  specification varchar(256) NULL,
+  unit varchar(32) NULL,
+  qty decimal(18,4) NULL,
+  plan_date datetime NULL,
+  PRIMARY KEY (source_id)
+);
+
+INSERT INTO crm_seorderentry (
+  Id, seorder_id, bill_no, entry_seq, item_number, item_name,
+  specification, unit, qty, plan_date, date,
+  create_by, create_by_name, create_time,
+  update_by, update_by_name, update_time,
+  tenant_id, IsDeleted, seorderentry_id
+)
+SELECT
+  l.target_id,
+  so.target_id,
+  so.bill_no,
+  l.entry_seq,
+  l.item_number,
+  l.item_name,
+  l.specification,
+  l.unit,
+  COALESCE(l.qty, 0),
+  l.plan_date,
+  so.order_date,
+  @operator_id,
+  @operator_name,
+  @now,
+  @operator_id,
+  @operator_name,
+  @now,
+  @tenant_id,
+  0,
+  l.target_id
+FROM tmp_s1_uat_so_line l
+JOIN tmp_s1_uat_so so ON so.source_id = l.source_order_id;
+```
+
+### 9.5 需求核验导入模板
+
+```sql
+CREATE TEMPORARY TABLE tmp_s1_uat_examine (
+  source_id varchar(128) NOT NULL,
+  target_id bigint NOT NULL,
+  bill_no varchar(64) NOT NULL,
+  bom_number varchar(450) NULL,
+  need_qty decimal(23,10) NULL,
+  examine_time datetime NULL,
+  PRIMARY KEY (source_id)
+);
+
+INSERT INTO b_order_examine_result (
+  Id, orderid, order_no, type, time, ketting_time, bom_number, need_qty,
+  create_by, create_by_name, create_time,
+  update_by, update_by_name, update_time,
+  tenant_id, IsDeleted
+)
+SELECT
+  e.target_id,
+  so.target_id,
+  e.bill_no,
+  1,
+  e.examine_time,
+  e.examine_time,
+  e.bom_number,
+  COALESCE(e.need_qty, 0),
+  @operator_id,
+  @operator_name,
+  @now,
+  @operator_id,
+  @operator_name,
+  @now,
+  @tenant_id,
+  b'0'
+FROM tmp_s1_uat_examine e
+JOIN tmp_s1_uat_so so ON so.bill_no = e.bill_no;
+```
+
+### 9.6 需求核验明细抽样模板
+
+```sql
+CREATE TEMPORARY TABLE tmp_s1_uat_examine_detail (
+  source_id varchar(128) NOT NULL,
+  target_id bigint NOT NULL,
+  source_examine_id varchar(128) NOT NULL,
+  item_number varchar(450) NULL,
+  item_name text NULL,
+  qty decimal(23,10) NULL,
+  self_lack_qty decimal(23,10) NULL,
+  make_qty decimal(23,10) NULL,
+  purchase_qty decimal(23,10) NULL,
+  PRIMARY KEY (source_id)
+);
+
+INSERT INTO b_order_detail (
+  Id, order_examine_id, fid, item_number, item_name,
+  qty, self_lack_qty, make_qty, purchase_qty,
+  create_by, create_by_name, create_time,
+  update_by, update_by_name, update_time,
+  tenant_id, IsDeleted
+)
+SELECT
+  d.target_id,
+  e.target_id,
+  e.target_id,
+  d.item_number,
+  d.item_name,
+  COALESCE(d.qty, 0),
+  COALESCE(d.self_lack_qty, 0),
+  COALESCE(d.make_qty, 0),
+  COALESCE(d.purchase_qty, 0),
+  @operator_id,
+  @operator_name,
+  @now,
+  @operator_id,
+  @operator_name,
+  @now,
+  @tenant_id,
+  b'0'
+FROM tmp_s1_uat_examine_detail d
+JOIN tmp_s1_uat_examine e ON e.source_id = d.source_examine_id;
+```
+
+### 9.7 验收 SQL
+
+```sql
+SELECT tenant_id, COUNT(*) AS orders_count
+FROM crm_seorder
+WHERE tenant_id = 797403760988229
+  AND bill_from LIKE 'UAT导入:S1_UAT_20260604_RQ_V1%'
+GROUP BY tenant_id;
+
+SELECT tenant_id, COUNT(*) AS lines_count
+FROM crm_seorderentry
+WHERE tenant_id = 797403760988229
+  AND bill_no IN (
+    SELECT bill_no
+    FROM crm_seorder
+    WHERE tenant_id = 797403760988229
+      AND bill_from LIKE 'UAT导入:S1_UAT_20260604_RQ_V1%'
+  )
+GROUP BY tenant_id;
+
+SELECT tenant_id, COUNT(*) AS examine_count
+FROM b_order_examine_result
+WHERE tenant_id = 797403760988229
+  AND order_no IN (
+    SELECT bill_no
+    FROM crm_seorder
+    WHERE tenant_id = 797403760988229
+      AND bill_from LIKE 'UAT导入:S1_UAT_20260604_RQ_V1%'
+  )
+GROUP BY tenant_id;
+```
+
+## 10. 旧库抽取建议
+
+旧库抽取建议先生成中间文件或临时表,不直接跨库写入 UAT:
+
+1. 从 SQL Server `dopdemorq` 抽取候选单号对应的订单、明细、核验、工单、排程、发货、ASN。
+2. 在本地生成 `source_id -> target_id` 映射。
+3. 对缺失链路补造一致数据,例如交付承诺、交付变更、计划联动。
+4. 生成 MySQL 可执行导入 SQL。
+5. 在 UAT MySQL 先导入 P0 试导样例。
+6. 验证通过后再导入完整 52 单数据包。
+
+## 11. 不建议做的事
+
+- 不建议把旧库 18,736 行核验明细一次性全导入首轮试导。
+- 不建议把旧库主键作为必须保留的约束。
+- 不建议全表导入 `ASNBOLShipperMaster`、`PeriodSequenceDet`、`ScheduleResultOpMaster` 等大表。
+- 不建议混用瑞奇 `dopdemorq` 与瑞贝 `dopdemorb` 数据。
+- 不建议写入 Demo 租户或其它历史租户。
+- 不建议为本轮 UAT 数据准备投入复杂事务级回滚方案;如需清理,优先按租户、批次标记和候选单号范围人工处理。
+
+## 12. 下一步
+
+1. 用 P0 的 10 个单号生成本地中间数据。
+2. 生成 `source_id -> target_id` 映射。
+3. 输出 P0 试导 SQL。
+4. 导入 UAT AIDOP 租户。
+5. 执行 S1 MDP 转换。
+6. 验证 S1 页面、DWD、KPI。
+7. 通过后扩大到完整 52 单数据包。

+ 270 - 0
doc/plan/S1/S1产销协同UAT数据生成执行任务书.md

@@ -0,0 +1,270 @@
+# S1 产销协同 UAT 数据生成执行任务书
+
+## 1. 任务目标
+
+基于旧 DOP 瑞奇库 `dopdemorq` 的真实业务样本,为新系统 UAT 环境 `aidopdev` 生成一套 S1 产销协同测试数据。
+
+本任务不是生产迁移,不要求照搬旧库全部字段、主键和历史记录。最终目标是让新系统能够完整串联以下场景:
+
+- 销售订单与订单明细
+- 需求核验与核验明细
+- 工单与订单明细关联
+- 工单排程与排程结果
+- 发货计划与 ASN
+- S1 MDP 分层转换
+- S1 DWD 与 KPI 验收
+- S1 页面主要 Tab 查询、筛选、统计和演示
+
+## 2. 核心约束
+
+- 所有写入 UAT MySQL 的数据必须归属 AIDOP 租户:`tenant_id = 797403760988229`。
+- 不得写入 Demo 租户:`tenant_id = 1300000000888`。
+- 推荐批次号:`S1_UAT_20260604_RQ_V1`。
+- 旧库仅作为素材库,可参考旧库订单、客户、物料、工单、排程、核验、发货和 ASN。
+- 可以生成新系统 ID,不要求保留旧库原始主键。
+- 可以补造旧库缺失环节,但补造数据必须能和候选订单、物料、工单串起来。
+- 不要求复杂回滚脚本。UAT 数据只要求批次可识别、可人工复查、必要时可按租户和批次清理。
+
+## 3. 禁止事项
+
+- 不得全量导入旧库。
+- 不得把瑞奇 `dopdemorq` 和瑞贝 `dopdemorb` 数据混在同一批次。
+- 不得覆盖 UAT 既有数据。
+- 不得把凭据、截图、连接串明文写入脚本或提交到 Git。
+- 不得在未完成只读检查和人工确认前执行写入。
+- 不得把 `tenant_id` 留空或写成其它租户。
+- 不得一次性导入全部 18,736 行需求核验明细作为首轮试导。
+
+## 4. 输入资料
+
+- 主方案:`doc/plan/S1/S1产销协同UAT测试数据抽取与导入方案.md`
+- 候选清单与映射:`doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md`
+- 数据库资源信息:`doc/plan/aidop项目服务器数据库相关资源信息.md`
+- 旧库来源:SQL Server `dopdemorq`
+- 目标库:MySQL `aidopdev`
+
+## 5. 推荐执行阶段
+
+### 阶段 1:只读确认
+
+只允许执行 SELECT 或元数据查询。
+
+必须确认:
+
+- `SysTenant` 中 AIDOP 租户 ID 是否仍为 `797403760988229`。
+- P0 候选单号在 UAT 目标表中是否不存在。
+- 目标表结构是否包含所需字段。
+- AIDOP 租户下现有 S1 数据量,避免和已有演示或历史测试数据混淆。
+
+输出物:
+
+- 只读检查结果摘要。
+- P0 试导单号最终列表。
+- 字段差异或阻塞项。
+
+### 阶段 2:生成中间数据
+
+从旧库读取 P0 候选单号相关数据,生成本地中间数据,不直接写 UAT。
+
+建议 P0 单号:
+
+```text
+MPO482024102300001
+MPO482025010900002
+MPO482025012100001
+MPO482024120200003
+MPO482025010800003
+MPO482025011300004
+MPO482025042800001
+SO241020241018001
+SO241020241015003
+SO241020241021002
+```
+
+中间数据至少包括:
+
+- 销售订单主表数据
+- 销售订单明细数据
+- 需求核验主表数据
+- 需求核验明细抽样数据
+- 工单主表数据
+- 工单关联明细数据
+- 排程明细数据
+- 排程结果数据
+- 发货计划数据
+- ASN 数据
+
+输出物:
+
+- 中间数据文件或临时表定义。
+- `source_id -> target_id` 映射。
+- 抽样规则说明。
+
+### 阶段 3:补造闭环数据
+
+根据新系统功能现状补造旧库缺失但 UAT 需要的数据。
+
+优先补造:
+
+- 交付承诺:`ado_s1_delivery_promise`
+- 交付变更:`ado_s1_delivery_change`
+- 计划联动样例
+- 合同评审样例
+- 产品设计或 BOM 相关样例
+- 异常状态样例,例如延期、缺料、部分发货、已完成
+
+补造规则:
+
+- 必须和候选订单号、物料编码、工单号关联。
+- 日期要形成合理链路:订单日期 <= 计划日期 <= 排程日期 <= 发货日期。
+- 数量要形成合理链路:订单数量、工单数量、发货数量不能明显矛盾。
+- 所有补造数据仍使用 `tenant_id = 797403760988229`。
+
+### 阶段 4:生成 P0 试导 SQL
+
+生成可人工审查的 MySQL SQL 文件。
+
+SQL 文件必须包含:
+
+- 批次变量。
+- 重复数据检查。
+- 临时映射表或等价映射逻辑。
+- P0 数据写入语句。
+- 写入后验收 SQL。
+- 明确提示:执行前需要人工确认。
+
+不要求包含复杂回滚脚本。
+
+### 阶段 5:人工确认
+
+执行写入前必须由负责人确认:
+
+- P0 单号范围。
+- 写入目标库为 UAT `aidopdev`。
+- 租户 ID 为 `797403760988229`。
+- SQL 未包含凭据明文。
+- SQL 未包含全表删除、全库更新、无条件覆盖。
+- SQL 不写入 Demo 租户。
+
+### 阶段 6:P0 试导
+
+只导入 P0 5-10 单。
+
+导入后立即验证:
+
+- 订单和明细数量。
+- 核验和核验明细数量。
+- 工单和排程数量。
+- 发货计划和 ASN 数量。
+- S1 页面能查询到数据。
+- MDP 转换可运行。
+- DWD 和 KPI 有结果。
+
+### 阶段 7:扩展完整 UAT 包
+
+P0 验证通过后,再扩展到 52 个候选单号。
+
+扩展时可以调整:
+
+- 需求核验明细抽样数量。
+- 异常状态比例。
+- 发货与 ASN 覆盖比例。
+- 交付承诺和交付变更数量。
+- 计划联动和合同评审样例数量。
+
+## 6. ID 生成要求
+
+执行脚本必须明确 ID 生成方式,不能临时手填。
+
+可选方式:
+
+- 使用新系统一致的雪花 ID 生成函数或脚本。
+- 使用本地脚本生成不冲突的大整数 ID。
+- 使用数据库已有最大 ID 加偏移的方式,但必须先检查不冲突。
+
+无论采用哪种方式,都必须维护映射:
+
+```text
+source_entity + source_id -> target_id
+```
+
+## 7. 批次标记要求
+
+本轮不要求复杂回滚,但必须便于识别本批测试数据。
+
+优先使用:
+
+- 业务表已有备注字段,例如 `bill_from`、`remark`、`Remark`。
+- 创建人字段,例如 `create_by_name = 'UAT数据导入'`。
+- 固定单号范围和候选单号清单。
+- `tenant_id = 797403760988229`。
+
+建议标记值:
+
+```text
+S1_UAT_20260604_RQ_V1
+```
+
+## 8. 验收 SQL 要求
+
+验收 SQL 必须包含租户过滤。
+
+至少验证:
+
+- `crm_seorder`
+- `crm_seorderentry`
+- `b_order_examine_result`
+- `b_order_detail`
+- `mes_morder`
+- `mes_moentry`
+- `PeriodSequenceDet`
+- `ScheduleResultOpMaster`
+- `ShippingPlanDetail`
+- `ASNBOLShipperMaster`
+- `mdp_stg_so`
+- `mdp_std_so`
+- `dwd_requirement_examine_detail`
+- `dwd_order_schedule_trans`
+- `dwd_ship_trans`
+- `ado_s9_kpi_value_l1_day`
+
+## 9. 给执行模型的提示词
+
+可以将以下内容作为其它大模型的执行提示词:
+
+```text
+你要为 Ai-DOP 新系统 UAT 环境生成 S1 产销协同测试数据。
+
+请严格阅读并遵守:
+1. doc/plan/S1/S1产销协同UAT测试数据抽取与导入方案.md
+2. doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md
+3. doc/plan/S1/S1产销协同UAT数据生成执行任务书.md
+4. doc/plan/aidop项目服务器数据库相关资源信息.md
+
+重要约束:
+- 旧 SQL Server 库 dopdemorq 只是素材库,不是生产迁移源。
+- 所有 UAT 数据必须写入 AIDOP 租户 tenant_id = 797403760988229。
+- 不得写入 Demo 租户 tenant_id = 1300000000888。
+- 先做只读检查和 P0 试导 SQL,未经人工确认不得写入 UAT MySQL。
+- 不要求复杂回滚脚本,但必须有批次标记 S1_UAT_20260604_RQ_V1。
+- 不要全量导入旧库,不要覆盖现有数据,不要提交明文凭据。
+
+你的第一步只允许做只读检查,并输出:
+1. AIDOP 租户确认结果
+2. P0 单号是否已存在
+3. 目标表字段缺口
+4. P0 试导 SQL 生成计划
+```
+
+## 10. 完成标准
+
+任务完成时应满足:
+
+- P0 试导数据能在 S1 页面查询。
+- S1 MDP 转换能运行。
+- DWD 表能产出对应数据。
+- KPI 表能产出 S1 指标。
+- 数据全部归属 AIDOP 租户。
+- Demo 租户无新增测试数据。
+- 批次标记可识别。
+- 负责人确认可以扩展到完整 52 单数据包。

+ 271 - 0
doc/plan/S1/S1产销协同UAT测试数据抽取与导入方案.md

@@ -0,0 +1,271 @@
+# S1 产销协同 UAT 测试数据抽取与导入方案
+
+## 1. 目标
+
+为新系统正式 UAT 测试准备 S1 产销协同业务数据。旧 DOP 瑞奇库 `dopdemorq` 仅作为真实业务素材库,目标是构造一套归属 AIDOP 租户、能在新系统完整串联的测试数据。
+
+本方案不是生产迁移,不要求逐表、逐字段、逐主键照搬旧库数据。执行重点是适度冗余、可反复测试、可演示、可覆盖主流程和异常场景。
+
+本方案同时作为 S1-S4 全局 UAT 场景测试的起点。S1 订单、订单明细、客户和物料应优先被 S2 工单、S3 物料需求、S4 采购执行复用,避免 S2/S3/S4 各自独立造一批无法串联的数据。全局链路要求见 `doc/plan/S1-S4全局UAT场景测试数据生成方案.md`。
+
+## 2. 数据来源与目标
+
+| 类型 | 数据库 | 用途 |
+|------|--------|------|
+| 旧 DOP 瑞奇库 | SQL Server `dopdemorq` | S1 UAT 主素材来源 |
+| 旧 DOP 瑞贝库 | SQL Server `dopdemorb` | 备用增强来源,不与瑞奇主样本混用 |
+| UAT 新系统库 | MySQL `aidopdev` | 目标导入库 |
+
+S1 首批 UAT 数据优先使用 `dopdemorq`。如确需使用 `dopdemorb`,应单独标记批次。
+
+## 3. 租户归属规则
+
+所有导入到 UAT MySQL 的测试数据必须统一归属 AIDOP 租户,便于区分测试数据、演示数据和正式生产数据。
+
+| 项 | 值 |
+|----|----|
+| AIDOP 租户 ID | `797403760988229`(组织名 AIDOP) |
+| UAT 登录账号 | `AIDOPDemo` / `1234567890dop` |
+| Demo 租户 ID | `1300000000888` |
+| 推荐批次号 | `S1_UAT_20260604_RQ_V1` |
+
+导入要求:
+
+- 目标表如有 `tenant_id`,统一写入 `797403760988229`。
+- 不得写入 Demo 租户或其它历史租户。
+- 目标表如有 `factory_id`、`org_id`、`company_id`,按 AIDOP UAT 默认组织口径统一映射;无法确认时先置空或沿用 AIDOP 现有样例值。
+- 验收 SQL 必须带租户过滤。
+- 本轮是 UAT 测试数据准备,不要求复杂回滚脚本;但数据必须有批次标记,便于必要时人工识别和清理。
+
+## 4. UAT 覆盖范围
+
+S1 UAT 数据需要支撑以下业务场景:
+
+| 序号 | 场景 | 数据要求 |
+|------|------|----------|
+| 1 | 合同评审 | 客户、产品、订单或合同评审样例 |
+| 2 | 产品设计 | 产品、BOM、工艺路线、产线、工作中心 |
+| 3 | 订单评审 | 销售订单、订单明细、订单状态、变更样例 |
+| 4 | 订单交付 | 销售订单、需求核验、工单、排程、发货、联动 |
+| 5 | 订单发货 | 发货计划、发货明细、ASN |
+| 6 | 工单下达 | 工单、工单明细、工艺路线、排程结果 |
+| 7 | 指标看板 | S1 MDP、DWD、KPI |
+| 8 | 需求明细核验 | 需求核验主表、BOM 明细 |
+| 9 | 计划联动看板 | 计划联动样例,可在新系统侧补造 |
+
+## 5. 四类场景化数据包
+
+### 5.1 主流程闭环数据包
+
+用于验证从订单到交付、从业务表到 MDP/DWD/KPI 的完整链路。
+
+链路要求:
+
+```text
+销售订单 -> 订单明细 -> 客户/物料 -> BOM/工艺 -> 工单 -> 排程 -> 需求核验 -> 发货/ASN -> S1 MDP -> DWD/KPI
+```
+
+### 5.2 业务状态与异常数据包
+
+用于验证筛选、异常提示、边界状态和重复测试。
+
+建议覆盖:
+
+- 新建、评审中、已确认、已完成订单。
+- 无需求核验订单。
+- 无排程订单。
+- 未发货、部分发货、已发货订单。
+- 缺料、延期、采购未完成样例。
+- 重复单号校验样例。
+- 筛选无结果样例。
+
+### 5.3 跨模块联动数据包
+
+用于验证 S1 页面中依赖 S2/S3/S4/S6/S7 的数据展示。
+
+建议覆盖:
+
+- S2 工单与排程。
+- S3/S4 采购与供应交付。
+- S6/S7 库存、发货、质量或 ASN 相关数据。
+- 计划联动、交付承诺、交付变更。
+
+### 5.4 基础配置与权限数据包
+
+用于保证 UAT 用户能操作页面和查看数据。
+
+建议确认:
+
+- AIDOP 租户、组织、工厂。
+- UAT 测试账号、角色、菜单权限。
+- 客户、物料、BOM、工艺、产线、工作中心。
+- 单号规则和基础字典。
+
+## 6. 首批候选数据结论
+
+已从 `dopdemorq` 只读筛选出首批 52 个候选业务单号,建议先以 P0 的 5-10 单做试导。
+
+首批只读统计:
+
+| 数据项 | 数量 |
+|--------|------|
+| 候选单号 | 52 |
+| 匹配销售订单 | 27 |
+| 销售订单明细 | 305 |
+| 需求核验单 | 391 |
+| 需求核验明细 | 18,736 |
+| 工单 | 320 |
+| 排程明细 | 76 |
+| 排程结果 | 69 |
+| 发货计划明细 | 22 |
+| ASN 主单 | 20 |
+
+P0 优先样例见 `doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md`。
+
+## 7. 必导与建议导入数据
+
+### 7.1 P0 必导
+
+- `crm_seorder`
+- `crm_seorderentry`
+- `b_order_examine_result`
+- `b_order_detail`
+- `mes_morder`
+- `mes_moentry`
+- `ShippingPlan`
+- `ShippingPlanDetail`
+- `ASNBOLShipperMaster`
+- `ASNBOLShipperDetail`
+
+### 7.2 P1 建议同步导入
+
+- `PeriodSequenceDet`
+- `ScheduleResultOpMaster`
+- `ProductStructureMaster`
+- `ProductStructureOp`
+- `RoutingOpDetail`
+- `WorkOrdMaster`
+- `WorkOrdDetail`
+- `WorkOrdRouting`
+
+### 7.3 P2 增强数据
+
+- `srm_pr_main`
+- `PurOrdMaster`
+- `PurOrdDetail`
+- `srm_polist_ds`
+- `NbrMaster`
+- `NbrDetail`
+- `OpTransEmployee`
+
+## 8. 造数与导入原则
+
+1. 旧库只作为素材库,不要求保留旧库原始主键。
+2. 导入 UAT 时可统一生成新系统 ID,并通过临时映射表维护关联关系。
+3. 不要求导入旧库全字段,只填新系统页面、接口、MDP、DWD、KPI 所需字段。
+4. 可补造旧库缺失环节,例如计划联动、交付承诺、合同评审、设计任务和异常状态。
+5. 日期要形成合理链路:订单日期 <= 计划日期 <= 排程日期 <= 发货日期。
+6. 数量要形成合理链路:订单数量、工单数量、发货数量不能明显矛盾。
+7. 大表必须按订单、工单、物料、发货单、采购单等业务键过滤。
+8. 需求核验明细首轮建议抽样,不一次性导入全部 18,736 行。
+9. 导入完成后执行 S1 MDP 刷新。
+10. 刷新后执行 DWD/KPI 验收 SQL。
+
+## 9. 新系统功能现状交叉校验要求
+
+数据准备不能只参考 UAT Excel 测试用例,还必须与新系统当前功能现状交叉验证。
+
+必须核对:
+
+- 新系统菜单和页面实际入口。
+- 后端 API / Service 实际读取的表。
+- S1 MDP 数据流是否覆盖导入数据。
+- DWD/KPI 是否能产出结果。
+- S1/S2/S3 已完成验收文档中的已实现能力。
+- UAT 数据库现有 AIDOP 租户数据量。
+
+差异处理:
+
+- 测试用例缺失但新系统已有功能:补测试数据和测试点。
+- 测试用例与新系统实现不一致:标注为需产品确认。
+- 旧库缺失但新系统需要:按同一批订单和物料补造一致样例。
+
+## 10. 建议导入顺序
+
+1. 基础租户、组织、账号和权限确认。
+2. 销售订单主表。
+3. 销售订单明细。
+4. 需求核验主表。
+5. 需求核验明细。
+6. 工单主表。
+7. 工单关联明细。
+8. 排程明细与排程结果。
+9. 发货计划与 ASN。
+10. 新系统补造数据:交付承诺、交付变更、计划联动、合同评审、设计任务。
+11. 运行 S1 MDP 转换任务。
+12. 验证 DWD、KPI、S1 页面和主要 Tab。
+
+## 11. 建议验收 SQL
+
+```sql
+-- 1. S1 MDP 最近批次
+SELECT job_code, batch_id, status, stage_rows, standard_rows, dwd_rows, start_time, end_time, error_message
+FROM mdp_transform_run_log
+WHERE job_code = 'S1_MDP_SYNC_TRANSFORM'
+ORDER BY start_time DESC, id DESC
+LIMIT 5;
+
+-- 2. 订单主表和明细
+SELECT COUNT(*) AS order_count
+FROM crm_seorder
+WHERE tenant_id = <AIDOP_TENANT_ID>;
+
+SELECT COUNT(*) AS order_entry_count
+FROM crm_seorderentry
+WHERE tenant_id = <AIDOP_TENANT_ID>;
+
+-- 3. S1 标准层
+SELECT COUNT(*) AS std_so_count
+FROM mdp_std_so
+WHERE tenant_id = <AIDOP_TENANT_ID>;
+
+-- 4. 订单交付 DWD
+SELECT COUNT(*) AS dwd_ship_count
+FROM dwd_ship_trans
+WHERE tenant_id = <AIDOP_TENANT_ID>;
+
+-- 5. 需求核验 DWD
+SELECT COUNT(*) AS requirement_count
+FROM dwd_requirement_examine_detail
+WHERE tenant_id = <AIDOP_TENANT_ID>;
+
+-- 6. KPI 写入
+SELECT module_code, metric_code, COUNT(*) AS rows_count, MAX(biz_date) AS latest_biz_date
+FROM ado_s9_kpi_value_l1_day
+WHERE module_code = 'S1'
+  AND is_deleted = 0
+GROUP BY module_code, metric_code
+ORDER BY metric_code;
+```
+
+## 12. 风险与注意事项
+
+- 不要全量导入 `b_bom_child_examine`、`ScheduleResultOpMaster`、`OpTransEmployee` 等大表。
+- 不要按表随机抽样,必须按订单主线带出上下游关联数据。
+- 不要只导主表不导明细。
+- 不要混用瑞奇、瑞贝两个库的订单和主数据。
+- 合同评审、产品设计建议通过新系统 UAT 页面新建或补造样例。
+- 导入测试数据不得覆盖 UAT 既有演示数据或正式生产样例。
+- 密码、连接串、截图不写入脚本和 Git。
+
+## 13. 下一步建议
+
+1. 先按四类场景化测试数据包生成候选清单。
+2. 生成 P0 试导 SQL,不直接写库。
+3. 人工确认 P0 单号、租户 ID、目标库和 SQL 安全性。
+4. 小批量导入 5-10 条完整闭环订单做试跑。
+5. 验证 S1 页面、S1 MDP、DWD、KPI 和主要交付跟踪 Tab。
+6. 再扩大到完整 UAT 数据包。
+7. 保留批次号用于人工识别、复查和必要时清理。
+
+对应的首批候选清单、导入映射和 SQL 草案见:`doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md`。

+ 222 - 0
doc/plan/S1S2S3_UAT测试指南.md

@@ -0,0 +1,222 @@
+# S1 / S2 / S3 UAT 测试指南(测试人员版)
+
+> 适用环境:AIDOP UAT(租户 **`797403760988229`**,组织名 AIDOP)  
+> 数据批次:`S1S4_UAT_20260604_RQ_V1`(P0)+ `S1S4_UAT_FULL_20260605_V1`(完整包)  
+> 数据说明:[S1S4_UAT_FULL_执行记录_20260605.md](./S1S4_UAT_FULL_执行记录_20260605.md)  
+> 方案与脚本索引:[S1-S4全局UAT场景测试数据生成方案.md](./S1-S4全局UAT场景测试数据生成方案.md) §11
+
+---
+
+## 1. 环境与登录
+
+| 项 | 说明 |
+|----|------|
+| 前端地址 | `http://<UAT主机>:8888`(本机 UAT 为 `http://127.0.0.1:8888`) |
+| 后端 API | `http://<UAT主机>:5005` |
+
+### 1.1 租户与账号(重要)
+
+本批 S1–S4 UAT 数据(P0 + 完整包共 **50 张销售订单**)已全部落在 **AIDOP 租户**:
+
+| 登录时选租户 | `tenant_id` | 组织名 | 推荐账号 |
+|--------------|-------------|--------|----------|
+| **AIDOP** | `797403760988229` | AIDOP | **`AIDOPDemo`** |
+
+| 账号 | 密码 | 登录时选租户 |
+|------|------|----------------|
+| **`AIDOPDemo`** | `1234567890dop` | **AIDOP**(`797403760988229`) |
+
+登录后在销售订单列表搜索 `MPO482024102300001`,能查到 1 条即环境正确。
+
+说明:勿与框架种子租户 **系统默认**(`1300000000001`,账号 `Admin.NET`)混淆——该租户下 **没有** 本批 UAT 50 单。亦勿使用 Demo 租户 `1300000000888` / `DemoAdmin`。
+
+---
+
+## 2. 测试数据总览(测什么)
+
+本批数据是 **同一套全局主线**,不是各模块各造各的:
+
+```text
+S1 销售订单/订单交付
+  → S2 工单/排程/执行进度
+  → S3 采购申请/采购订单/交货计划
+  → (S4 发货在 scm_shd,本指南侧重 S1–S3)
+```
+
+| 规模 | 数量 | 如何识别 |
+|------|------|----------|
+| 销售订单 | **50 张** | 订单来源含 `UAT导入:S1S4_UAT_…` |
+| 其中 P0 冒烟样例 | **5 张** | 批次 `S1S4_UAT_20260604_RQ_V1` |
+| 完整包扩充 | **45 张** | 批次 `S1S4_UAT_FULL_20260605_V1` |
+| 采购订单 PO | **50 张** | P0:`PO-UAT-20260604-01`~`05`;FULL:`PO-UAT-FULL-20260605-001`~`045` |
+| 工单 | 多数订单明细有对应工单 | 工单号多为旧库真实号,如 `M500029406` |
+
+**识别 UAT 数据的简便方法**:在 S1「订单评审」或「订单交付」里用下表 **订单号** 搜索;能搜到且客户多为 `WKQXGFYXGE` / `CUST0005` 即为本批数据。
+
+---
+
+## 3. 推荐测试单号(优先用这些)
+
+### 3.1 P0 五单(端到端冒烟,单量少、链路最清晰)
+
+| 用途 | 销售订单号 | 工单号(示例) | 采购订单 PO |
+|------|------------|----------------|-------------|
+| 主样例 | `MPO482024102300001` | `M500029406`、`M500029407` | `PO-UAT-20260604-01` |
+| 小单 | `MPO482025010900002` | `M500067189`、`M500067190` | `PO-UAT-20260604-02` |
+| 单行单 | `MPO482024120200003` | `M500053856` | `PO-UAT-20260604-03` |
+| 发货/交付 | `MPO482025012100001` | `M500077552`、`M500077553` | `PO-UAT-20260604-04` |
+| 排程样例 | `MPO482025011300004` | `M500070779`、`M500070780` | `PO-UAT-20260604-05` |
+
+### 3.2 完整包抽查(多行、大列表)
+
+| 场景 | 销售订单号 | 说明 |
+|------|------------|------|
+| 多行明细 | `MPO482025081500002` | 约 62 行明细,适合测分页/筛选 |
+| 客户订单 SO | `SO241020241018001` | 客户订单口径 |
+| 较新 MPO | `MPO482026020300001` | FULL 批新增 |
+
+FULL 批 PO 规则:`PO-UAT-FULL-20260605-NNN`(`NNN` 为导入序号 001–045),**与销售订单一一对应**;不确定时 **用销售订单号反查**,不要死记 PO 编号。
+
+---
+
+## 4. 模块测试路径与检查点
+
+### 4.1 S1 产销协同
+
+| 菜单(路径) | 测什么 | 推荐操作 |
+|--------------|--------|----------|
+| 订单管理 → 订单评审 `/aidop/s1/order-mgmt/order` | 销售订单主数据 | 搜 `MPO482024102300001`,应 **1 条** |
+| 订单管理 → 订单交付 `/aidop/s1/order-mgmt/orderDelivery` | 交付视图(走 MDP/DWD) | 同上订单号,P0 应 **2 行**(2 条明细) |
+| 订单管理 → ASN 发货 `/aidop/s1/order-mgmt/asnShipper` | 发货侧(若有数据) | P0 以 scm 发货为主,ASN 可能为空,**空表不记缺陷** 除非产品要求必有 |
+| 产销协同看板 → 指标看板 `/aidop/s1/SalesKanBan/kanban` | S1 KPI | 应有指标块,非全空 |
+| 产销协同看板 → 计划联动 `/aidop/s1/SalesKanBan/linkage-plan` | 计划联动 | 列表可打开;可点「刷新」类操作(会触发 MDP,需后端正常) |
+| 产销协同看板 → 需求明细核验 `/aidop/s1/SalesKanBan/requirement-examine-detail` | 需求核验 | **本轮未批量导入核验明细**,可能无数据或很少,见 §6 |
+| 智能运营 → S1 看板 `/aidop/smart-ops/s1` | 汇总 KPI | 与指标看板对照,应有数 |
+
+**S1 通过标准(单号 `MPO482024102300001`)**:
+
+- [ ] 订单评审能查到订单,明细 2 行  
+- [ ] 订单交付能查到 2 行,物料 `3121C0035`、`1A0C885`  
+- [ ] 指标看板有 KPI 展示(不要求具体数值与生产一致)
+
+---
+
+### 4.2 S2 制造协同
+
+| 菜单(路径) | 测什么 | 推荐操作 |
+|--------------|--------|----------|
+| 生产排程 → 工单排程 `/aidop/s2/production-scheduling/work-order-scheduling` | 工单排程 | 用 P0 工单 `M500029406` 或订单号关联查询 |
+| 作业计划 → 可执行日计划 `/aidop/s2/operation-plan/executable-daily-plan` | 日计划 | 打开列表,有数据即可(本轮未专门批量造日计划样例) |
+| 制造协同看板 → 工单执行进度 `/aidop/s2/collaboration-kanban/work-order-progress` | 工单进度 | 搜 `M500029406` 或 `MPO482024102300001` 相关工单 |
+| 智能运营 → S2 看板 `/aidop/smart-ops/s2` | S2 KPI | 应有 L2/L3 指标 |
+
+**S2 通过标准(衔接 P0)**:
+
+- [ ] 工单 `M500029406` 能在进度/排程相关页查到  
+- [ ] 该工单能关联到销售订单 `MPO482024102300001`(详情或字段 SalesOrd 类)  
+- [ ] S2 看板非全空
+
+---
+
+### 4.3 S3 供应协同
+
+| 菜单(路径) | 测什么 | 推荐操作 |
+|--------------|--------|----------|
+| 物料计划 → 物料需求计划 `/aidop/s3/material-plan/demand-schedule` | MRP/需求计划 | 打开列表,筛选/分页正常 |
+| 物料计划 → 交货计划 `/aidop/s3/material-plan/delivery-schedule` | 交货计划 | 列表可打开 |
+| 物料计划 → 交货异常 `/aidop/s3/material-plan/delivery-exception` | 异常 | 可为空或少量 |
+| 采购管理 → 采购申请 `/aidop/s3/procurement/purchase-request` | PR | 搜 `PR-UAT-20260604` 或 `PR-UAT-FULL` |
+| 采购管理 → 物料采购订单 `/aidop/s3/procurement/purchase-order` | PO | 搜 `PO-UAT-20260604-01` 或 `PO-UAT-FULL-20260605-001` |
+| 采购管理 → 委外/工序外协等 | 扩展 | 有菜单则点通即可,不强制有 UAT 行 |
+| 智能运营 → S3 看板 `/aidop/smart-ops/s3` | S3 KPI / 告警 | 应有指标;可能有告警条数 |
+| 供应协同看板 → MDP 监控(若有) `/aidop/s3/supply-kanban/mdp-monitor` | S3 MDP 状态 | 最近运行 SUCCESS |
+
+**S3 通过标准(衔接 P0)**:
+
+- [ ] `PO-UAT-20260604-01` 能查到,且关联销售订单 `MPO482024102300001`  
+- [ ] 对应 PR(`PR-UAT-20260604-01`)存在  
+- [ ] S3 看板有 KPI
+
+---
+
+## 5. 跨模块串联测试(建议测 1 遍)
+
+用 **P0 主样例** `MPO482024102300001` 按顺序走:
+
+| 步骤 | 模块 | 查什么 | 预期 |
+|------|------|--------|------|
+| 1 | S1 订单评审 | 订单 + 2 行明细 | 有数据 |
+| 2 | S1 订单交付 | 同单 2 行交付 | 有数据 |
+| 3 | S2 工单进度 | 工单 `M500029406`、`M500029407` | 能查到 |
+| 4 | S3 采购订单 | `PO-UAT-20260604-01` | 关联该销售订单 |
+| 5 | S3 采购申请 | `PR-UAT-20260604-01` | 关联工单 `M500029406` |
+| 6 | 看板 S1/S2/S3 | 三个智能运营看板 | 均有 KPI |
+
+记录单号与截图时,在缺陷里 **务必写销售订单号 + 租户 AIDOP**。
+
+---
+
+## 6. 已知限制(测到这些不算“数据没导入”)
+
+| 现象 | 原因 | 测试建议 |
+|------|------|----------|
+| 需求明细核验无数据 | 未批量导入 `b_bom_child_examine` | 记为「待补数据」或测页面空态 |
+| 部分 SO 订单工单数少于明细行 | 旧库本身无工单挂接 | 只验证有工单的行能串到 S2/S3 |
+| S2 日计划/排程明细很少 | 未从旧库批量导入 `PeriodSequenceDet` | 以工单进度看板为主 |
+| S4 供应商发货列表为空 | 发货在 `scm_shd`(`SH-UAT-*`),不一定进 S4 发货单表 | S1–S3 测试可不看 S4;要测发货用 PO 查 `scm` 或后续补 S4 样例 |
+| 无「延期/缺料/IQC 退货」样例 | 完整包只做了主链路,未造异常场景 | 异常流需另批数据或记 enhancement |
+| 登录后列表全空 | 租户选错(如选了系统默认) | 登录租户选 **AIDOP**(`797403760988229`),账号 **`AIDOPDemo`** |
+| `AIDOPDemo` 登录失败 | 选错租户或密码 | 租户 **AIDOP**,密码 `1234567890dop` |
+
+---
+
+## 7. 数据中台 / MDP(测试负责人可选)
+
+| 菜单 | 路径 | 用途 |
+|------|------|------|
+| MDP 运行监控 | `/aidop/data-platform/mdp-monitor` | 选模块 S1/S2/S3,最近记录应为 **SUCCESS** |
+
+参考批次(2026-06-05 导入后):
+
+- S1:`S1_MDP_FULL_20260605004738`
+- S2:`S2_MDP_FULL_20260605004739`
+- S3:`S3_MDP_FULL_20260605004739`
+
+若业务列表有数但看板长期为空,先让开发确认 MDP 是否 SUCCESS,再提缺陷。
+
+---
+
+## 8. 缺陷提交模板(复制使用)
+
+```text
+【模块】S1 / S2 / S3
+【环境】UAT,租户 797403760988229(AIDOP),账号 AIDOPDemo
+【数据】销售订单:________  工单:________  PO:________
+【菜单路径】/aidop/...
+【步骤】1… 2…
+【预期】
+【实际】
+【截图/接口】
+```
+
+---
+
+## 9. 快速对照表(打印用)
+
+| 单号类型 | 示例 |
+|----------|------|
+| P0 订单 ×5 | `MPO482024102300001`、`MPO482025010900002`、`MPO482024120200003`、`MPO482025012100001`、`MPO482025011300004` |
+| P0 PO ×5 | `PO-UAT-20260604-01` … `05` |
+| FULL 订单 | 另 45 张 `MPO*` / `SO*`,来源含 `S1S4_UAT_FULL_20260605_V1` |
+| FULL PO | `PO-UAT-FULL-20260605-001` … `045` |
+| 供应商(合成) | `VEN00060` |
+| 客户 | `CUST0005` / `WKQXGFYXGE` |
+
+---
+
+## 10. 相关文档
+
+- 全局方案:[S1-S4全局UAT场景测试数据生成方案.md](./S1-S4全局UAT场景测试数据生成方案.md)
+- P0 明细:[S1S4_UAT_P0_抽数记录_20260604.md](./S1S4_UAT_P0_抽数记录_20260604.md)
+- 完整包执行:[S1S4_UAT_FULL_执行记录_20260605.md](./S1S4_UAT_FULL_执行记录_20260605.md)
+- API 冒烟:[S1S4_UAT_P0_冒烟验收报告_20260605.md](./S1S4_UAT_P0_冒烟验收报告_20260605.md)

+ 70 - 0
doc/plan/S1S4_UAT_FULL_执行记录_20260605.md

@@ -0,0 +1,70 @@
+# S1-S4 完整 UAT 包执行记录
+
+> 批次:`S1S4_UAT_FULL_20260605_V1`(叠加既有 P0 `S1S4_UAT_20260604_RQ_V1`)  
+> 租户:`797403760988229`(AIDOP)| 目标库:`aidopdev` | 素材库:`dopdemorq`
+
+## 1. 规模达成
+
+| 指标 | 方案 §6.2 建议 | 实际 |
+|------|----------------|------|
+| 销售订单 | ~50 张 | **50**(P0 5 + FULL 45) |
+| 采购订单 | 50–150 张 | **50**(每单 1 PO) |
+| 发货单 | 50–150 张 | **50**(`scm_shd` 每 PO 1 张) |
+| 订单明细 | 150–300 行 | **约 400+ 行**(随旧库实抽,未截断) |
+
+## 2. 数据来源
+
+- 候选清单:`doc/plan/S1/S1产销协同UAT候选数据清单与导入映射.md` §4.1/4.2  
+- 旧库实抽:`dopdemorq`(`sqlcmd` + `extract_full_from_dopdemorq.sql`)  
+- 生成脚本:`doc/plan/sql/tools/Generate-S1S4FullUatSql.ps1`  
+- 写入脚本:`doc/plan/sql/S1S4_UAT_FULL_execute_write.sql`  
+- 原始导出:`doc/plan/sql/_extract_full.tsv`
+
+### 2.1 候选单号缺口
+
+清单中 **24** 个单号在 `dopdemorq` 不存在(多为 `10014xxx` / `15002xxx` 等),已从同库补充 **23** 张带工单链路的 `MPO*` / `SO*` 订单,使 FULL 批达到 45 张。
+
+## 3. 写入结果(2026-06-05)
+
+| 对象 | FULL 批次数量 |
+|------|---------------|
+| `crm_seorder` | 45 |
+| `PurOrdMaster` | 45 |
+| `scm_shd` | 45 |
+| 累计 UAT 订单(含 P0) | **50** |
+
+**租户**:导入脚本已统一 `tenant_id = 797403760988229`;若环境曾写入 `1300000000001`,执行 `doc/plan/sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql` 后验收 `crm_seorder` 在 AIDOP 租户 **50** 条。
+
+ID 段:`9106000500000001` 起(与 P0 `9106000400000001` 不重叠)。
+
+## 4. MDP
+
+| 模块 | 批次 | stage | standard | dwd |
+|------|------|-------|----------|-----|
+| S1 | `S1_MDP_FULL_20260605004738` | 549 | 375 | 449 |
+| S2 | `S2_MDP_FULL_20260605004739` | 267 | 294 | 233 |
+| S3 | `S3_MDP_FULL_20260605004739` | 25997 | 35474 | 4576 |
+
+## 5. 未纳入本轮(可后续迭代)
+
+| 项 | 说明 |
+|----|------|
+| 需求核验明细 2000–5000 行 | 旧库有 1.8 万+ 行,本轮未批量导入 `b_bom_child_examine` |
+| 排程 `PeriodSequenceDet` / 日计划 | 未从旧库批量拉取,S2 看板主要靠 MDP 与已有工单 |
+| S4 IQC/退货/欠料样例 | 主链路 PO/发货已齐;IQC 表样例可另开 `S1S4_UAT_FULL_S4_补样.sql` |
+| 状态覆盖(延期/缺料/退货) | 需按 §3.2 定向造异常,非本次批量导入范围 |
+
+## 6. 验收 SQL(示例)
+
+```sql
+SET @tid := 1300000000001;
+SELECT bill_from, COUNT(*) FROM crm_seorder
+WHERE tenant_id=@tid AND bill_from LIKE '%S1S4_UAT%'
+GROUP BY bill_from;
+```
+
+## 7. 登录与页面
+
+- 账号:`AIDOPDemo` / `1234567890dop` / 租户 **AIDOP**(`797403760988229`)  
+- 检索示例:`MPO482025081500002`(FULL,62 行明细)、`MPO482024102300001`(P0)  
+- 测试指南:[S1S2S3_UAT测试指南.md](./S1S2S3_UAT测试指南.md)

+ 94 - 0
doc/plan/S1S4_UAT_P0_冒烟验收报告_20260605.md

@@ -0,0 +1,94 @@
+# S1-S4 P0 UAT 冒烟验收报告
+
+> 环境:本机 UAT `127.0.0.1:3306` / `aidopdev`,后端 `http://127.0.0.1:5005`  
+> 批次:`S1S4_UAT_20260604_RQ_V1` | 租户:`797403760988229`(AIDOP)  
+> 验收时间:2026-06-05
+
+## 1. MDP 运行(S1–S3)
+
+| 模块 | 批次 | 状态 | stage | standard | dwd | 备注 |
+|------|------|------|-------|----------|-----|------|
+| S1 | `S1_MDP_FULL_20260605001442` | SUCCESS | 165 | 36 | 110 | 已补 `mdp_entity` 产品设计三实体 |
+| S2 | `S2_MDP_FULL_20260605000906` | SUCCESS | 47 | 43 | 13 | |
+| S3 | `S3_MDP_FULL_20260605000911` | SUCCESS | 24807 | 34589 | 4143 | |
+
+S1 实体补登记:`UpdateScripts/1.0.152.sql`(与 `doc/plan/sql/S1S4_UAT_S1_mdp_entity_product_design_20260605.sql` 同内容)。
+
+## 2. 业务表链路(SQL)
+
+| 检查项 | 结果 |
+|--------|------|
+| P0 销售订单 5 张 | PASS |
+| 每单:明细 + 工单 + PO | PASS(见下表) |
+| 5 张 PO 均有发货 `scm_shd` | PASS(各 `ship_cnt=1`) |
+| PO ↔ 销售订单 | PASS |
+
+| bill_no | line | 工单 | PO |
+|---------|------|------|-----|
+| MPO482024102300001 | 2 | 2 | 1 |
+| MPO482025010900002 | 2 | 2 | 1 |
+| MPO482024120200003 | 1 | 1 | 1 |
+| MPO482025012100001 | 2 | 2 | 1 |
+| MPO482025011300004 | 2 | 2 | 1 |
+
+| PurOrd | SalesOrd |
+|--------|----------|
+| PO-UAT-20260604-01 | MPO482024102300001 |
+| PO-UAT-20260604-02 | MPO482025010900002 |
+| PO-UAT-20260604-03 | MPO482024120200003 |
+| PO-UAT-20260604-04 | MPO482025012100001 |
+| PO-UAT-20260604-05 | MPO482025011300004 |
+
+## 3. 数据中台(SQL)
+
+| 检查项 | 结果 |
+|--------|------|
+| `dwd_ship_trans`(S1 最新 batch)含 5 张 P0 订单行 | PASS(13 行,含 9 条订单明细口径) |
+| `mdp_std_so` 含 P0 `order_no` | PASS,`sync_batch_id=S1_MDP_FULL_20260605001442` |
+| `dwd_order_schedule_trans` 工单挂销售订单 | PASS(如 M500029406 → MPO482024102300001) |
+| `ado_s9_kpi_value_l1_day` S1/S2/S3 | PASS(S1 159 / S2 122 / S3 122 条,calc_time 为 6/5 MDP 批次) |
+
+## 4. API / 看板冒烟
+
+| 场景 | 接口 | 结果 | 说明 |
+|------|------|------|------|
+| S1 看板 KPI | `GET /api/AidopKanban/module-detail?moduleCode=S1` | PASS | l2=30;匿名走框架默认租户,业务列表需 **AIDOP** 登录态 |
+| S2 看板 KPI | `...moduleCode=S2` | PASS | l2=30,l3=60 |
+| S3 看板 KPI | `...moduleCode=S3` | PASS | l2=30,alerts=10 |
+| S3 采购订单 | `GET /api/Supply/purchase-order/list?cgdd=PO-UAT-20260604-01` | PASS | total=2(主表+明细口径) |
+| S3 采购申请 | `GET /api/Supply/purchase-request/list` | PASS | total=10 |
+| S1 订单评审列表 | `GET /api/Order/seorder/list?billNo=MPO482024102300001` | **PASS** | 登录后 `total=1`,命中 P0 单 |
+| S1 订单交付列表 | `GET /api/Order/delivery/list?billNo=MPO482024102300001` | **PASS** | 登录后 `total=2`(2 行明细) |
+| S2 工单进度 | `GET /api/Production/work-order-progress/list?keyword=M500029406` | **PASS** | 登录后 `total=10` |
+| S4 供应商发货 | `GET /api/ProcurementExecution/supplier-shipment/list` | 已修复 | 原报错 `definer root@%` 不存在;已建 `root@'%'` 用户 |
+
+### 4.1 登录态 API 验收(2026-06-05 已跑通)
+
+| 项 | 值 |
+|----|-----|
+| 登录接口 | `POST /api/sysAuth/login` |
+| 账号 | `AIDOPDemo` |
+| 密码(明文) | `1234567890dop` |
+| 租户 | `797403760988229`(AIDOP) |
+| 密码传输 | 前端同款 SM2:`sm-crypto-v2` + `App.json` / `.env` 公钥 |
+
+说明:2026-06-05 已将首批写入 `1300000000001` 的数据迁至 AIDOP 租户(脚本 `doc/plan/sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql`)。`GET /api/Order/seorder/list?billNo=MPO482024102300001` 在 `AIDOPDemo` 登录态 **total=1**。
+
+## 5. 页面手工冒烟建议(8888 前端)
+
+| 模块 | 菜单路径(参考) | 检索关键字 |
+|------|------------------|------------|
+| S1 | 订单评审 / 订单交付 | `MPO482024102300001` |
+| S2 | 工单进度看板 | `M500029406` |
+| S3 | 物料采购订单 | `PO-UAT-20260604-01` |
+| S4 | 供应商发货 | `SH-UAT-20260604-04` 或 PO 号 |
+
+## 6. 遗留 / 非阻塞
+
+- **S4 全量 MDP Job**:无,采购页主要读业务表 + S3 指标。
+- **S1 列表 API**:需登录态租户;看板与 DWD 已验证。
+- **版本脚本**:`1.0.152.sql` 需随下次后端发布/启动由 AutoVersionUpdate 落库(本机已手工执行等价 SQL)。
+
+## 7. 结论
+
+**P0 试导数据 + S1–S3 MDP + 全局链路 SQL 验收通过**,可进行前端 UAT 场景走查。S4 发货列表 API 环境项(MySQL definer)已在本机修复。

+ 174 - 0
doc/plan/S1S4_UAT_P0_只读检查报告_20260604.md

@@ -0,0 +1,174 @@
+# S1-S4 全局 UAT P0 只读检查报告
+
+> 执行时间:2026-06-04  
+> 依据:`doc/plan/S1-S4全局UAT场景测试数据生成方案.md`  
+> 阶段:**第一阶段 — 只读检查**(未向 UAT 库写入任何数据)
+
+> **2026-06-05 更正**:当时将框架种子租户 `1300000000001`(系统默认)误当作 AIDOP 租户。真实 **AIDOP 租户** 为 `797403760988229`(组织名 AIDOP,账号 `AIDOPDemo`)。下文 §2.2 保留当日只读快照;导入与验收一律以 `797403760988229` 为准(见 `sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql`)。
+
+---
+
+## 1. 执行约束核对
+
+| 约束项 | 要求 | 检查结果 |
+|--------|------|----------|
+| 目标租户 | `tenant_id = 797403760988229`(AIDOP) | 2026-06-05 起草案/执行 SQL 已统一;当日曾误用 `1300000000001` |
+| 禁止租户 | `tenant_id = 1300000000888`(Demo) | AIDOP 业务表当前无 Demo 数据;**禁止**在草案中使用 Demo 租户 |
+| 全局批次 | `S1S4_UAT_20260604_RQ_V1` | 草案统一使用该批次标记 |
+| 写库 | 第一阶段禁止写库 | 本次仅执行 SELECT;INSERT 见 SQL 草案且默认注释 |
+| 链路 | S1→S2→S3→S4 串联 | 草案按订单明细→工单→采购申请→采购订单→交货/发货设计 |
+
+---
+
+## 2. UAT 库(MySQL `aidopdev`)现状
+
+**目标库即本机 UAT 服务器**(公网 `39.105.125.212:3306`,本机 `127.0.0.1:3306` 为同一实例,hostname `iZgwfu8jrvudt3Z`)。只读查询使用 `127.0.0.1`;远端访问使用 `aidopremote@39.105.125.212`。
+
+### 2.1 目标表存在性
+
+以下 S1-S4 核心业务表均存在于 `aidopdev`:
+
+| 模块 | 表名 | 状态 |
+|------|------|------|
+| S1 | `crm_seorder`, `crm_seorderentry`, `b_order_examine_result`, `b_order_detail` | 存在 |
+| S1 | `ShippingPlan`, `ASNBOLShipperMaster` | 存在 |
+| S2 | `mes_morder`, `mes_moentry`, `WorkOrdMaster`, `WorkOrdDetail`, `WorkOrdRouting` | 存在 |
+| S2 | `PeriodSequenceDet`, `ScheduleResultOpMaster` | 存在 |
+| S3 | `srm_pr_main`, `PurOrdMaster`, `PurOrdDetail`, `srm_polist_ds` | 存在 |
+| S4 | `scm_shd`, `scm_shdzb`, `PurOrdRctMaster`, `PurOrdRctDetail` | 存在 |
+| S4 | `scm_shd.tenant_id` | **UAT 实库无此列**(实体类有定义,试导时勿写 tenant_id) |
+| S3 | `DeliveryExceptionMaster` | 存在 |
+
+### 2.2 系统默认租户(`1300000000001`,检查时误标为 AIDOP)数据量
+
+| 表 | 行数 | 说明 |
+|----|------|------|
+| `crm_seorder` | 2 | 现有:`S20260430001`、`S2260504001` |
+| `crm_seorderentry` | 4 | 每单 2 行明细 |
+| `mes_morder` | 0 | AIDOP 租户无工单 |
+| `mes_moentry` | 0 | — |
+| `PurOrdMaster` | 1 | `PW202605100002`(PW 委外类型) |
+| `PurOrdDetail` | 1 | 关联上表 1 行 |
+| `srm_pr_main` | 0 | AIDOP 租户无采购申请 |
+
+### 2.3 真实 AIDOP 租户(`797403760988229`)当时已有样本
+
+| 表 | tenant_id | 行数 |
+|----|-----------|------|
+| `mes_morder` | `797403760988229` | 1 |
+| `srm_pr_main` | `797403760988229` | 1 |
+| `PurOrdMaster` | `797403760988229` | 1 |
+
+**结论(更正后)**:UAT 导入必须显式写 `tenant_id = 797403760988229`,验收 SQL 必须带该租户过滤;勿写入 `1300000000001`(系统默认)或 `1300000000888`(Demo)。
+
+### 2.4 Demo 租户(1300000000888)
+
+`crm_seorder` 在 Demo 租户有 **1** 条记录。草案与试导 SQL **不得**向 Demo 租户插入或更新。
+
+---
+
+## 3. P0 候选单号冲突检查
+
+对 S1 方案推荐的 10 个 P0 单号做重复检查:
+
+```sql
+SELECT bill_no, tenant_id, COUNT(*) AS cnt
+FROM crm_seorder
+WHERE bill_no IN (
+  'MPO482024102300001','MPO482025010900002','MPO482025012100001',
+  'MPO482024120200003','MPO482025010800003','MPO482025011300004',
+  'MPO482025042800001','SO241020241018001','SO241020241015003','SO241020241021002'
+)
+GROUP BY bill_no, tenant_id;
+```
+
+**结果**:0 行 — P0 单号在 UAT 库中尚未占用,可安全试导(需先从 `dopdemorq` 抽取业务字段)。
+
+---
+
+## 4. 全局链路设计(P0 试导)
+
+P0 采用 **5 张销售订单 × 每单 2 行明细** 的最小闭环(满足全局方案 5-10 单要求):
+
+| 序号 | 销售订单号 | 场景标签 | 下游预期 |
+|------|------------|----------|----------|
+| 1 | `MPO482024102300001` | 完整闭环主样例 | 工单+排程+采购+发货 |
+| 2 | `MPO482025010900002` | 小体量冒烟 | 正常完成 |
+| 3 | `MPO482025012100001` | 交付侧衔接 | 部分发货 |
+| 4 | `MPO482025010800003` | ASN/发货 | 发货+ASN |
+| 5 | `SO241020241018001` | 客户订单 | 缺料风险样例 |
+
+### 4.1 关联键(全局一致)
+
+```text
+crm_seorder.bill_no
+  └─ crm_seorderentry (seorder_id, Id=soentry_id)
+       └─ mes_morder (morder_no) ← mes_moentry.soentry_id
+            └─ srm_pr_main (pr_billno, 需求来源=工单)
+                 └─ PurOrdMaster (PurOrd, SalesOrd=bill_no, WorkOrd=morder_no)
+                      └─ PurOrdDetail (PurOrd + Line)
+                           └─ srm_polist_ds (ponumber, poline)
+                                └─ scm_shd (po_billno) → scm_shdzb
+                                     └─ PurOrdRctMaster (退货, OrdNbr=PurOrd)
+```
+
+### 4.2 P0 数量规划
+
+| 层级 | 实体 | 计划数量 |
+|------|------|----------|
+| S1 | 销售订单 | 5 |
+| S1 | 订单明细 | 10 |
+| S1 | 需求核验主表 | 5 |
+| S1 | 需求核验明细(抽样) | 50(每单约 10 行) |
+| S2 | 工单 `mes_morder` | 10(每明细 1 工单) |
+| S2 | 工单子表 `mes_moentry` | 10 |
+| S2 | 工单主数据 `WorkOrdMaster` | 10(与 mes 并行,供排程页) |
+| S3 | 采购申请 `srm_pr_main` | 10 |
+| S3 | 采购订单 `PurOrdMaster` | 5(每单 2 行明细) |
+| S3 | 交货计划 `srm_polist_ds` | 10 |
+| S4 | 供应商发货 `scm_shd` | 3 |
+| S4 | 采购退货 `PurOrdRctMaster` | 2 |
+
+---
+
+## 5. 旧库素材依赖(待人工抽取)
+
+本阶段**未连接** SQL Server `dopdemorq`。正式试导前需完成:
+
+1. 按 P0 五单号从 `dopdemorq` 导出订单、明细、客户、物料、工单、采购、发货中间 CSV。
+2. 在本地生成 `source_id → target_id` 映射(ID 基址建议 `9106000400000001` 起,避开现有 `800234425405509` 段)。
+3. 将 CSV 灌入 SQL 草案中的 `tmp_s1s4_uat_*` 临时表后再执行 INSERT。
+
+---
+
+## 6. 风险与阻塞项
+
+| 级别 | 项 | 处理建议 |
+|------|-----|----------|
+| 高 | 旧库字段未抽取,草案中业务字段为占位符 | 试导前必须替换 `tmp_*` 表数据 |
+| 高 | `PurOrdMaster`/`PurOrdDetail` 必填字段多 | 草案仅列 P0 最小字段集,执行前对照表结构补全 |
+| 中 | S4 功能未完全开发 | 发货/退货按测试报告占位,功能完成后复核 |
+| 中 | `mes_morder` 与 `WorkOrdMaster` 双轨 | S2 页面部分读 `WorkOrd*`,部分读 `mes_*`,P0 两轨均写入 |
+| 低 | 现有 AIDOP 订单 `S20260430001` 与 P0 批次无关 | 验收时用 `bill_from LIKE 'UAT导入:S1S4_UAT_%'` 过滤 |
+
+---
+
+## 7. 产出物
+
+| 文件 | 说明 |
+|------|------|
+| 本文档 | 只读检查报告 |
+| `doc/plan/S1S4_UAT_P0_抽数记录_20260604.md` | dopdemorq 实抽字段与单号调整说明 |
+| `doc/plan/sql/S1S4_UAT_P0_试导SQL草案_20260604.sql` | 检查 + DML 模板(Section 0 可执行) |
+| `doc/plan/sql/S1S4_UAT_P0_试导数据填充_20260604.sql` | **dopdemorq 实数 tmp 填充**(Section A 可执行自检) |
+| `doc/plan/sql/_extract_p0.tsv` | sqlcmd 原始导出 |
+
+---
+
+## 8. 下一步(需人工确认后执行)
+
+1. 从 `dopdemorq` 抽取 P0 五单中间数据并填入 `tmp_*` 表。
+2. 人工审阅 SQL 草案中的租户 ID、单号、数量链路。
+3. 在 UAT 库小批量试导(建议 `START TRANSACTION` + 验证 + `COMMIT`)。
+4. 按全局方案第 8 节执行串联验收 SQL。
+5. 运行 S1-S4 MDP 转换任务并验证 KPI。

+ 106 - 0
doc/plan/S1S4_UAT_P0_抽数记录_20260604.md

@@ -0,0 +1,106 @@
+# S1-S4 P0 抽数记录(dopdemorq → UAT 草案)
+
+> 来源:SQL Server `123.60.180.165` / `dopdemorq`(`sa` 只读)  
+> 目标:MySQL `39.105.125.212` / `aidopdev`(本机 `127.0.0.1` 同实例)  
+> 批次:`S1S4_UAT_20260604_RQ_V1` | 租户:`797403760988229`(AIDOP;2026-06-05 自 `1300000000001` 迁正)
+
+## 1. P0 单号调整
+
+| 原计划单号 | 旧库状态 | P0 实际采用 |
+|------------|----------|-------------|
+| `MPO482024102300001` | 存在,7 行明细 | 采用,试导 **2 行**(seq 1-2) |
+| `MPO482025010900002` | 存在,2 行明细 | 采用,全 2 行 |
+| `MPO482025012100001` | 存在,2 行明细 | 采用,全 2 行 |
+| `MPO482024120200003` | 存在,**仅 1 行**明细 | 采用,1 行 + 1 工单 |
+| `MPO482025010800003` | **不存在** | 替换为 `MPO482025011300004`(2 行明细,有工单) |
+
+## 2. 销售订单头(crm_seorder)
+
+| bill_no | 旧库 Id | custom_name | rdate | urgent |
+|---------|---------|-------------|-------|--------|
+| MPO482024102300001 | 604078130520133 | WKQXGFYXGE | 2024-10-23 | 1 |
+| MPO482025010900002 | 631771613847621 | WKQXGFYXGE | 2025-01-09 | 1 |
+| MPO482024120200003 | 618329121550405 | WKQXGFYXGE | 2024-12-02 | 1 |
+| MPO482025012100001 | 636029205446725 | WKQXGFYXGE | 2025-01-21 | 1 |
+| MPO482025011300004 | 633180642168901 | WKQXGFYXGE | 2025-01-13 | 1 |
+
+`custom_no` 在旧库均为 NULL;UAT 导入时建议写 `CUST0005` / 客户名 `WKQXGFYXGE`(与 S1 候选清单 ET0005 口径对齐,待产品确认)。
+
+## 3. 订单明细(crm_seorderentry,P0 抽样)
+
+| bill_no | 旧 entry Id | seq | item_number | qty | plan_date |
+|---------|-------------|-----|-------------|-----|-----------|
+| MPO482024102300001 | 604078133665861 | 1 | 3121C0035 | 1500 | 2024-10-29 |
+| MPO482024102300001 | 604078133665862 | 2 | 1A0C885 | 3500 | 2024-10-29 |
+| MPO482025010900002 | 631771616395333 | 1 | 3121C0035 | 850 | 2025-01-18 |
+| MPO482025010900002 | 631771616399429 | 2 | 3124C0015 | 850 | 2025-01-21 |
+| MPO482024120200003 | 618329124159557 | 1 | 1AB9275 | 800 | 2024-12-03 |
+| MPO482025012100001 | 636029208526917 | 1 | 91C0D2C | 600 | 2025-02-13 |
+| MPO482025012100001 | 636029208526918 | 2 | 91CC0231 | 100 | 2025-02-13 |
+| MPO482025011300004 | 633180644831301 | 1 | 322AD001 | 5500 | 2025-02-11 |
+| MPO482025011300004 | 633180644831302 | 2 | 3221C0031 | 5500 | 2025-02-18 |
+
+合计 **9 行**明细(原目标 10 行;`MPO482024120200003` 旧库仅 1 行)。
+
+## 4. 工单(mes_morder ← 订单明细)
+
+| bill_no | soentry_id | morder_no | product_code | need_number |
+|---------|------------|-----------|--------------|-------------|
+| MPO482024102300001 | 604078133665861 | M500029406 | 32100035 | 1500 |
+| MPO482024102300001 | 604078133665862 | M500029407 | 1000885 | 3500 |
+| MPO482025010900002 | 631771616395333 | M500067189 | 32100035 | 850 |
+| MPO482025010900002 | 631771616399429 | M500067190 | 32400015 | 850 |
+| MPO482024120200003 | 618329124159557 | M500053856 | 1009275 | 800 |
+| MPO482025012100001 | 636029208526917 | M500077552 | 93000230 | 600 |
+| MPO482025012100001 | 636029208526918 | M500077553 | 93000231 | 100 |
+| MPO482025011300004 | 633180644831301 | M500070779 | 32100001 | 5500 |
+| MPO482025011300004 | 633180644831302 | M500070780 | 32100031 | 5500 |
+
+旧库 **保留原工单号**(`M500029406` 等),便于与排程/历史对照;UAT 新 Id 由映射表生成。
+
+## 5. S3/S4 旧库关联情况
+
+- `b_order_examine_result`:按 `order_no` 查 P0 单号 **无行**(可能字段名/口径不同,试导可跳过或 UAT 补造)。
+- `PurOrdMaster`:按 `SalesOrd` / `WorkOrd` 查 P0 主线 **无直接 PO**;S3/S4 试导采用 **合成 PO**(`PO-UAT-20260604-00x`),物料编码取自订单明细,供应商沿用 UAT 已有 `VEN00060`。
+
+## 6. 中间文件
+
+- `doc/plan/sql/_extract_p0.tsv`:sqlcmd 导出原始键值(勿提交含敏感信息时检查)
+
+## 7. 写库执行记录(2026-06-04)
+
+已执行 `doc/plan/sql/S1S4_UAT_P0_execute_write.sql` 并成功 `COMMIT`。
+
+| 表 | 写入行数 |
+|----|----------|
+| crm_seorder | 5 |
+| crm_seorderentry | 9 |
+| mes_morder / mes_moentry | 9 |
+| WorkOrdMaster | 9 |
+| srm_pr_main | 9 |
+| PurOrdMaster | 5 |
+| PurOrdDetail | 10 |
+| srm_polist_ds | 10 |
+| scm_shd | 3 |
+| scm_shdzb | 6 |
+
+- Demo 租户泄漏:**0**
+- S4 发货:5 张 PO 均已补 `scm_shd`(`SH-UAT-20260604-01`~`05`,含 PO-04/05 补全)
+- `bill_from` 批次标记已写入(PowerShell 管道下中文可能显示为 `??`,库内 UTF-8 正常)
+
+## 8. 后续执行记录(2026-06-05)
+
+| 步骤 | 状态 |
+|------|------|
+| S1/S2/S3 MDP 全量刷新 | 已完成 |
+| S1 `mdp_entity` 产品设计三实体 | 已完成(`1.0.152.sql`) |
+| PO-04/05 发货补全 | 已完成 |
+| SQL + 看板 API 冒烟 | 见 [S1S4_UAT_P0_冒烟验收报告_20260605.md](./S1S4_UAT_P0_冒烟验收报告_20260605.md) |
+
+**API 登录态**:`AIDOPDemo` / `1234567890dop` / 租户 `797403760988229` 已跑通 seorder、delivery、工单进度、采购订单列表(见冒烟报告 §4.1)。
+
+## 9. 完整 UAT 包(2026-06-05)
+
+- 批次 `S1S4_UAT_FULL_20260605_V1`:**45** 张新订单写入(叠加 P0 共 **50** 单)。
+- 执行记录:[S1S4_UAT_FULL_执行记录_20260605.md](./S1S4_UAT_FULL_执行记录_20260605.md)
+- **待人工**:浏览器 `:8888` 走查;S4 IQC/退货/异常状态样例可另批补造。

+ 126 - 0
doc/plan/S2/S2制造协同UAT数据生成执行任务书.md

@@ -0,0 +1,126 @@
+# S2 制造协同 UAT 数据生成执行任务书
+
+## 1. 任务目标
+
+为 S2 制造协同生成 UAT 测试数据,支撑工单工序排程、排产异常、可执行日计划、产线日历、执行进度看板和 S2 制造协同看板测试。
+
+## 2. 必读文档
+
+- `doc/plan/S2/S2制造协同UAT测试数据生成方案.md`
+- `doc/plan/S1/S1产销协同UAT测试数据抽取与导入方案.md`
+- `doc/plan/S1/S1产销协同UAT数据生成执行任务书.md`
+- `doc/plan/aidop项目服务器数据库相关资源信息.md`
+
+## 3. 核心约束
+
+- 所有写入数据必须使用 AIDOP 租户:`tenant_id = 797403760988229`。
+- 不得写入 Demo 租户:`tenant_id = 1300000000888`。
+- 推荐批次号:`S2_UAT_20260604_RQ_V1`。
+- 旧库仅作素材库,不做生产迁移。
+- 先做只读检查和 P0 SQL,未经人工确认不得写入 UAT MySQL。
+- 不要求复杂回滚脚本,但必须有批次标记。
+
+## 4. 执行阶段
+
+### 阶段 1:只读检查
+
+只允许执行 SELECT 或元数据查询。
+
+必须输出:
+
+- AIDOP 租户确认结果。
+- S2 目标表清单和字段缺口。
+- AIDOP 租户下现有 S2 数据量。
+- P0 工单、产线、物料是否已存在。
+
+### 阶段 2:生成 P0 中间数据
+
+生成本地中间数据,不直接写库。
+
+P0 至少包含:
+
+- 5-10 个工单。
+- 每工单 2-3 道工序。
+- 每工单 2-5 行物料需求。
+- 2 条排产异常。
+- 2 条可执行日计划。
+- 2 条产线日历配置。
+- 1 条休息时间、1 条节假日、1 条加班记录。
+
+### 阶段 3:补造制造协同场景
+
+补造旧库缺失但测试报告要求的数据:
+
+- 产线工作日历。
+- 产线休息时间。
+- 产线节假日。
+- 产线加班。
+- 资源冲突、产能不足、物料不足、工艺缺失等排产异常。
+- 工单执行进度阶段数据。
+
+### 阶段 4:生成 P0 SQL
+
+SQL 必须包含:
+
+- 批次变量。
+- 重复数据检查。
+- ID 映射逻辑。
+- 工单、工序、排程、日计划、产线日历、异常数据写入。
+- 验收 SQL。
+- 执行前人工确认提示。
+
+### 阶段 5:人工确认
+
+执行写入前确认:
+
+- 目标库为 UAT `aidopdev`。
+- 租户 ID 为 `797403760988229`。
+- 不包含全表删除、全库更新、无条件覆盖。
+- 不包含明文凭据。
+- P0 数据量符合测试报告最小要求。
+
+### 阶段 6:P0 试导与验收
+
+导入后验证:
+
+- 工单排程列表可查询。
+- 优先级调整、加急/特急、工单关闭样例可测试。
+- 可执行日计划能按未来 3 天和全部计划查询。
+- 产线日历、休息、节假日、加班可查询。
+- 排产异常可查询。
+- S2 看板和 DWD/KPI 有结果。
+
+## 5. 给执行模型的提示词
+
+```text
+你要为 Ai-DOP 新系统 UAT 环境生成 S2 制造协同测试数据。
+
+请严格阅读:
+1. doc/plan/S2/S2制造协同UAT测试数据生成方案.md
+2. doc/plan/S2/S2制造协同UAT数据生成执行任务书.md
+3. doc/plan/aidop项目服务器数据库相关资源信息.md
+
+第一步只允许做只读检查,不得写 UAT 数据库。
+
+重要约束:
+- 所有数据必须写入 AIDOP 租户 tenant_id = 797403760988229。
+- 不得写入 Demo 租户 tenant_id = 1300000000888。
+- 批次号使用 S2_UAT_20260604_RQ_V1。
+- 旧库只是素材库,不要全量导入。
+- 未经人工确认不得执行写入。
+
+请先输出:
+1. S2 目标表和字段确认
+2. AIDOP 租户下现有 S2 数据量
+3. P0 数据生成计划
+4. P0 SQL 生成计划
+```
+
+## 6. 完成标准
+
+- P0 工单排程和日计划能在页面查询。
+- S2 产线日历相关数据能查询。
+- S2 异常记录能查询。
+- S2 MDP、DWD、KPI 有结果。
+- 数据全部归属 AIDOP 租户。
+- Demo 租户无新增数据。

+ 149 - 0
doc/plan/S2/S2制造协同UAT测试数据生成方案.md

@@ -0,0 +1,149 @@
+# S2 制造协同 UAT 测试数据生成方案
+
+## 1. 目标
+
+为新系统正式 UAT 测试准备 S2 制造协同业务数据。旧 DOP 数据库仅作为真实业务素材库,最终目标是构造一套归属 AIDOP 租户、能支撑工单排程、日计划、产线日历、执行跟踪和 S2 看板的测试数据。
+
+本方案参考 `S2制造协同_UAT测试报告v1.0.xlsx`,并沿用 S1 UAT 数据准备原则:不做生产迁移,不要求照搬旧库主键和全字段,优先保证业务场景闭环、数据可查询、看板可统计、异常可验证。
+
+S2 的 P0 数据必须优先复用 S1 全局订单样本。工单、工序、日计划、排程和执行进度应能追溯到 S1 订单明细,后续 S3 物料需求也应基于这些 S2 工单生成。全局链路要求见 `doc/plan/S1-S4全局UAT场景测试数据生成方案.md`。
+
+## 2. 来源与目标
+
+| 类型 | 数据库/文件 | 用途 |
+|------|-------------|------|
+| 测试报告 | `D:\Projects\Ai-DOP\项目\项目测试\S2制造协同_UAT测试报告v1.0.xlsx` | S2 场景和用例来源 |
+| 旧 DOP 瑞奇库 | SQL Server `dopdemorq` | 工单、工艺、排程、报工、日历等素材来源 |
+| UAT 新系统库 | MySQL `aidopdev` | 目标导入库 |
+
+## 3. 租户与批次
+
+| 项 | 值 |
+|----|----|
+| AIDOP 租户 ID | `797403760988229`(组织名 AIDOP) |
+| UAT 登录账号 | `AIDOPDemo` / `1234567890dop` |
+| Demo 租户 ID | `1300000000888` |
+| 推荐批次号 | `S2_UAT_20260604_RQ_V1` |
+
+所有写入 UAT 的数据必须使用 `tenant_id = 797403760988229`,不得写入 Demo 租户。每批数据需带批次标记,便于人工识别、复查和必要时清理。
+
+## 4. 测试报告覆盖场景
+
+S2 测试报告包含 9 个分场景,报告要求每个场景不少于 2 张单据、每单行数不少于 2 行,并包含异常场景验证。
+
+| 序号 | 场景 | 数据要求 |
+|------|------|----------|
+| 1 | 工单工序排程 | 工单、工序、物料、产线、计划日期、排程状态、齐套数量 |
+| 2 | 排产异常记录 | 工单号、异常类型、异常描述、发生时间、处理状态 |
+| 3 | 可执行日计划 | 产线、物料、计划日期、数量、报工点、物料状态、下达状态 |
+| 4 | 产线工作日历管理 | 产线、周工作时间、工作时段 |
+| 5 | 产线休息时间管理 | 产线、休息开始/结束时间、有效日期 |
+| 6 | 产线节假日管理 | 产线、节假日、停线日期、节假日类型 |
+| 7 | 产线加班管理 | 产线、加班日期、加班时段、审批/启用状态 |
+| 8 | 工单执行进度看板 | 资源检查、计划排程、执行采购、生产备料、生产执行、成品入库 |
+| 9 | S2 制造协同看板 | S2 KPI、排程趋势、异常、工单进度、产线负荷 |
+
+## 5. 场景化数据包
+
+### 5.1 工单排程闭环数据包
+
+用于验证工单工序排程列表、优先级调整、生产排程、同步物料需求、执行追踪、物料明细、工序明细、同步工艺路线、加急/特急、工单关闭、导出。
+
+建议准备:
+
+- 10-20 个工单,覆盖未排程、已排程、已下达、执行中、已完工、已关闭。
+- 每个工单不少于 2 道工序。
+- 每个工单不少于 2 行物料需求。
+- 至少 2 个加急/特急工单。
+- 至少 2 个已有完工数量的工单,用于验证“已有完工数量不允许同步工艺路线”。
+
+### 5.2 生产日历与产线能力数据包
+
+用于验证产线工作日历、休息时间、节假日、加班管理,以及日计划计算。
+
+建议准备:
+
+- 3-5 条产线。
+- 每条产线配置周一到周日工作日历。
+- 每条产线配置 1-2 条休息时间。
+- 至少 2 条节假日停线记录。
+- 至少 2 条加班记录。
+- 至少 1 条异常样例:时间重叠、结束时间早于开始时间或无效产线。
+
+### 5.3 可执行日计划数据包
+
+用于验证未来 3 天计划、全部已下单计划、计划下达、产线/物料/日期筛选。
+
+建议准备:
+
+- 未来 3 天内日计划 20-50 行。
+- 超出 3 天范围但已下单计划 10-20 行。
+- 覆盖未下达、已下达、暂停、完成状态。
+- 关联工单、产线、物料、报工点和物料状态。
+
+### 5.4 异常与看板数据包
+
+用于验证排产异常记录、工单执行进度看板和 S2 制造协同看板。
+
+建议准备:
+
+- 排产异常 10-20 条,覆盖资源冲突、产能不足、物料不足、工艺缺失、日历不可用。
+- 工单执行进度数据覆盖资源检查、采购、备料、生产、入库各阶段。
+- 至少 2 个工单缺少部分跟踪数据,用于验证空状态不影响其它数据展示。
+- KPI 数据覆盖排程达成率、工单准时率、异常数、产线负荷、齐套率。
+
+## 6. 目标表与数据来源建议
+
+| 数据类型 | 旧库素材表/来源 | 新系统目标/平台层 | 处理策略 |
+|----------|-----------------|-------------------|----------|
+| 工单主数据 | `mes_morder`、`WorkOrdMaster` | `mes_morder`、`ado_s2_work_order`、`dwd_order_schedule_trans` | 以旧库工单为蓝本,生成新系统 ID |
+| 工单明细 | `mes_moentry`、`WorkOrdDetail` | `mes_moentry`、`ado_s2_work_order_op` | 保持工单到明细关联 |
+| 工艺路线 | `RoutingOpDetail`、`WorkOrdRouting` | 工序/工艺明细、S2 看板 | 可按物料补造 |
+| 排程明细 | `PeriodSequenceDet` | `mdp_stg_schedule`、`mdp_std_work_order_schedule` | 保留计划日期、产线、工序 |
+| 排程结果 | `ScheduleResultOpMaster` | `dwd_order_schedule_trans` | 保留执行结果和时间 |
+| 报工/执行 | `OpTransEmployee` | 执行进度、DWD/KPI | 按工单抽样 |
+| 产线日历 | 旧库主数据或补造 | 产线工作日历相关表 | 可按测试报告补造 |
+| 异常记录 | 旧库异常或补造 | 排产异常记录表、看板异常 | 优先补造覆盖异常类型 |
+
+## 7. 导入与生成原则
+
+1. 旧库只作为素材库,不保留旧库原始主键作为强约束。
+2. 工单、工序、物料、产线、日历、排程必须能串联。
+3. 日计划日期应覆盖未来 3 天和更长范围。
+4. 产线日历、休息、节假日、加班之间不能互相矛盾,异常样例需单独标记。
+5. 看板数据应同时覆盖有数据、缺数据、异常数据。
+6. 所有数据写入 AIDOP 租户,并带批次标记。
+7. 首轮只导入 P0 工单排程闭环样例,验证通过后扩展日历和看板。
+
+## 8. P0 试导建议
+
+P0 试导建议选择:
+
+- 5-10 个工单。
+- 每工单 2-3 道工序。
+- 每工单 2-5 行物料需求。
+- 2 条排产异常。
+- 2 条可执行日计划。
+- 2 条产线日历配置。
+- 1 条休息时间、1 条节假日、1 条加班记录。
+
+## 9. 验收 SQL 方向
+
+正式 SQL 需结合实际表结构生成,至少验证:
+
+- 工单主表、工单明细、工序明细数量。
+- 排程明细、排程结果数量。
+- 可执行日计划数量。
+- 产线工作日历、休息、节假日、加班数量。
+- 排产异常数量。
+- `mdp_stg_schedule`、`mdp_std_work_order_schedule`、`dwd_order_schedule_trans`。
+- `ado_s9_kpi_value_l1_day` 中 S2 指标写入。
+
+## 10. 下一步
+
+1. 只读确认 UAT S2 目标表结构和现有 AIDOP 租户数据量。
+2. 从旧库筛选工单、工艺、排程、执行样本。
+3. 补造产线日历、休息、节假日、加班和异常样例。
+4. 生成 P0 试导 SQL。
+5. 人工确认后执行 P0 试导。
+6. 验证 S2 页面、MDP、DWD、KPI 和看板。

+ 124 - 0
doc/plan/S3/S3供应协同UAT数据生成执行任务书.md

@@ -0,0 +1,124 @@
+# S3 供应协同 UAT 数据生成执行任务书
+
+## 1. 任务目标
+
+为 S3 供应协同生成 UAT 测试数据,支撑物料需求计划、交货计划、采购申请、要货令、采购订单、委外加工、工序外协、供应协同看板和工单齐套上线看板测试。
+
+## 2. 必读文档
+
+- `doc/plan/S3/S3供应协同UAT测试数据生成方案.md`
+- `doc/plan/S1/S1产销协同UAT数据生成执行任务书.md`
+- `doc/plan/数据库迁移/S3/S3数据中台与看板动态化验收.md`
+- `doc/plan/aidop项目服务器数据库相关资源信息.md`
+
+## 3. 核心约束
+
+- 所有写入数据必须使用 AIDOP 租户:`tenant_id = 797403760988229`。
+- 不得写入 Demo 租户:`tenant_id = 1300000000888`。
+- 推荐批次号:`S3_UAT_20260604_RQ_V1`。
+- 旧库仅作素材库,不做生产迁移。
+- 先做只读检查和 P0 SQL,未经人工确认不得写入 UAT MySQL。
+- 不要求复杂回滚脚本,但必须有批次标记。
+
+## 4. 执行阶段
+
+### 阶段 1:只读检查
+
+只允许执行 SELECT 或元数据查询。
+
+必须输出:
+
+- AIDOP 租户确认结果。
+- S3 目标表清单和字段缺口。
+- AIDOP 租户下现有 S3 数据量。
+- P0 物料、供应商、采购订单是否已存在。
+
+### 阶段 2:生成 P0 中间数据
+
+P0 至少包含:
+
+- 10-20 条物料需求计划。
+- 5-10 条交货计划。
+- 5 张采购申请。
+- 5 张采购订单,每张不少于 2 行。
+- 3 个供应商。
+- 3 条交货异常。
+- 2 条齐套缺料样例。
+
+### 阶段 3:补造供应协同场景
+
+补造旧库缺失但测试报告要求的数据:
+
+- 供应商主数据与供应商物料关系。
+- 发布/取消发布/生成交货单状态。
+- 交货异常与供应风险。
+- 委外加工订单。
+- 工序外协订单。
+- 齐套上线缺料和风险状态。
+
+### 阶段 4:生成 P0 SQL
+
+SQL 必须包含:
+
+- 批次变量。
+- 重复数据检查。
+- ID 映射逻辑。
+- 物料、供应商、需求、采购、交货、异常、齐套数据写入。
+- MDP/DWD/KPI 验收 SQL。
+- 执行前人工确认提示。
+
+### 阶段 5:人工确认
+
+执行写入前确认:
+
+- 目标库为 UAT `aidopdev`。
+- 租户 ID 为 `797403760988229`。
+- 不包含全表删除、全库更新、无条件覆盖。
+- 不包含明文凭据。
+- P0 数据量符合测试报告最小要求。
+
+### 阶段 6:P0 试导与验收
+
+导入后验证:
+
+- 物料需求计划可查询、发布、全部发布、新增、编辑、删除。
+- 交货计划可查询、发布、取消发布、生成交货单、批量添加。
+- 采购申请、采购订单、要货令可查询。
+- 委外、外协订单可查询。
+- 交货异常和齐套上线看板有数据。
+- S3 MDP、DWD、KPI 有结果。
+
+## 5. 给执行模型的提示词
+
+```text
+你要为 Ai-DOP 新系统 UAT 环境生成 S3 供应协同测试数据。
+
+请严格阅读:
+1. doc/plan/S3/S3供应协同UAT测试数据生成方案.md
+2. doc/plan/S3/S3供应协同UAT数据生成执行任务书.md
+3. doc/plan/数据库迁移/S3/S3数据中台与看板动态化验收.md
+4. doc/plan/aidop项目服务器数据库相关资源信息.md
+
+第一步只允许做只读检查,不得写 UAT 数据库。
+
+重要约束:
+- 所有数据必须写入 AIDOP 租户 tenant_id = 797403760988229。
+- 不得写入 Demo 租户 tenant_id = 1300000000888。
+- 批次号使用 S3_UAT_20260604_RQ_V1。
+- 旧库只是素材库,不要全量导入。
+- 未经人工确认不得执行写入。
+
+请先输出:
+1. S3 目标表和字段确认
+2. AIDOP 租户下现有 S3 数据量
+3. P0 数据生成计划
+4. P0 SQL 生成计划
+```
+
+## 6. 完成标准
+
+- P0 物料需求、交货计划、采购订单能在页面查询。
+- S3 交货异常、委外、外协、齐套上线样例可测试。
+- S3 MDP、DWD、KPI 有结果。
+- 数据全部归属 AIDOP 租户。
+- Demo 租户无新增数据。

+ 147 - 0
doc/plan/S3/S3供应协同UAT测试数据生成方案.md

@@ -0,0 +1,147 @@
+# S3 供应协同 UAT 测试数据生成方案
+
+## 1. 目标
+
+为新系统正式 UAT 测试准备 S3 供应协同业务数据。旧 DOP 数据库仅作为真实业务素材库,最终目标是构造一套归属 AIDOP 租户、能支撑物料需求、交货计划、采购申请、采购订单、委外外协、齐套上线和 S3 看板的测试数据。
+
+本方案参考 `S3供应协同_UAT测试报告v1.0.xlsx`,并沿用 S1/S2 的 UAT 数据准备原则:不做生产迁移,不照搬旧库主键和全字段,优先保证业务链路、测试场景、异常状态、数据中台和看板指标可验证。
+
+S3 的 P0 数据必须优先复用 S1-S2 全局主线。物料需求、采购申请、采购订单、交货计划和齐套上线数据应能追溯到 S2 工单或 S1 订单需求,后续 S4 采购执行应基于这些 S3 采购订单和交货计划生成。全局链路要求见 `doc/plan/S1-S4全局UAT场景测试数据生成方案.md`。
+
+## 2. 来源与目标
+
+| 类型 | 数据库/文件 | 用途 |
+|------|-------------|------|
+| 测试报告 | `D:\Projects\Ai-DOP\项目\项目测试\S3供应协同_UAT测试报告v1.0.xlsx` | S3 场景和用例来源 |
+| 旧 DOP 瑞奇库 | SQL Server `dopdemorq` | 物料、供应商、采购、交付、委外等素材来源 |
+| UAT 新系统库 | MySQL `aidopdev` | 目标导入库 |
+
+## 3. 租户与批次
+
+| 项 | 值 |
+|----|----|
+| AIDOP 租户 ID | `797403760988229`(组织名 AIDOP) |
+| UAT 登录账号 | `AIDOPDemo` / `1234567890dop` |
+| Demo 租户 ID | `1300000000888` |
+| 推荐批次号 | `S3_UAT_20260604_RQ_V1` |
+
+所有写入 UAT 的数据必须使用 `tenant_id = 797403760988229`,不得写入 Demo 租户。每批数据需带批次标记。
+
+## 4. 测试报告覆盖场景
+
+S3 测试报告包含 10 个分场景,报告要求每个场景不少于 2 张单据、每单行数不少于 2 行,并包含异常场景验证。
+
+| 序号 | 场景 | 数据要求 |
+|------|------|----------|
+| 1 | 物料需求计划 | 物料、需求日期、需求量、可用库存、净需求、建议采购量、MRP 状态 |
+| 2 | 物料交货计划 | 物料、供应商、交货日期、交货数量、发布状态、到货状态 |
+| 3 | 交货单异常记录 | 交货单、供应商、异常类型、异常描述、发生时间 |
+| 4 | 物料采购申请 | 物料、需求来源、申请数量、申请状态、审批/发布状态 |
+| 5 | 要货令 | 要货令主表、明细、供应商、交期、状态 |
+| 6 | 物料采购订单 | 采购订单、明细、供应商、物料、数量、价格、交期 |
+| 7 | 委外加工订单 | 委外供应商、加工物料、数量、交期、收发料状态 |
+| 8 | 工序外协订单 | 工单、工序、外协供应商、外协数量、交期 |
+| 9 | 供应协同看板 | 供应 KPI、交货计划、风险、异常、供应商表现 |
+| 10 | 工单物料齐套上线看板 | 工单、物料齐套、缺料、上线日期、风险状态 |
+
+## 5. 场景化数据包
+
+### 5.1 需求到交货闭环数据包
+
+用于验证物料需求计划、发布、交货计划、生成交货单、采购申请和采购订单链路。
+
+建议准备:
+
+- 30-80 条物料需求计划。
+- 覆盖未发布、已发布、部分转交货、已生成采购申请状态。
+- 20-50 条交货计划,关联供应商和采购订单。
+- 10-30 条采购申请,关联物料需求。
+- 10-30 张采购订单,每张不少于 2 行明细。
+
+### 5.2 供应异常与风险数据包
+
+用于验证交货单异常、供应风险和看板预警。
+
+建议准备:
+
+- 10-20 条交货异常,覆盖延期、数量不足、供应商未回复、质量风险、计划变更。
+- 至少 5 个供应商,覆盖正常、延期、高风险、黑名单/禁用样例。
+- 至少 5 条物料缺口,支撑齐套上线看板。
+
+### 5.3 委外与外协数据包
+
+用于验证委外加工订单和工序外协订单。
+
+建议准备:
+
+- 5-10 张委外加工订单,每张不少于 2 行明细。
+- 5-10 张工序外协订单,关联工单、工序和供应商。
+- 覆盖未下达、已下达、部分收货、已完成、异常状态。
+
+### 5.4 看板与数据中台数据包
+
+用于验证 S3 供应协同看板、工单齐套上线看板、MDP/DWD/KPI。
+
+建议准备:
+
+- 供应商交付准时率、延期数、缺料数、风险数等指标样例。
+- 物料齐套率、缺料明细、预计上线日期。
+- 覆盖有数据、空数据、异常数据三种状态。
+
+## 6. 目标表与数据来源建议
+
+| 数据类型 | 旧库素材表/来源 | 新系统目标/平台层 | 处理策略 |
+|----------|-----------------|-------------------|----------|
+| 物料主数据 | `ItemMaster` | `mdp_std_item`、S3 页面 | 抽取需求/采购/订单涉及物料 |
+| 供应商主数据 | 供应商相关旧表或补造 | `mdp_std_supplier`、S3 页面 | 至少覆盖 5-10 个供应商 |
+| 物料需求 | `srm_pr_main`、工单物料需求 | `mdp_stg_supply_demand`、`mdp_std_supply_demand`、`dwd_supply_demand` | 按物料和工单生成 |
+| 采购申请 | `srm_pr_main` | `mdp_std_purchase_request` | 保留申请数量、需求来源、状态 |
+| 采购订单 | `PurOrdMaster`、`PurOrdDetail` | `mdp_stg_purchase_order`、`mdp_std_purchase_order` | 关联供应商、物料、交期 |
+| 交货计划 | `srm_polist_ds` | `mdp_std_delivery_schedule` | 覆盖发布/取消/生成交货单 |
+| 交付结果 | 收货/发货相关旧表或补造 | `mdp_std_delivery_result`、`dwd_supplier_delivery` | 支撑准时率、延期、风险 |
+| 委外外协 | 委外/外协旧表或补造 | `mdp_std_process_outsource_order`、`dwd_process_outsource_delivery` | 按测试报告补造 |
+| 齐套上线 | 工单、物料、需求核验 | `dwd_material_readiness`、`dwd_material_shortage` | 关联 S2 工单和物料 |
+
+## 7. 生成与导入原则
+
+1. 旧库只作为素材库,不保留旧库原始主键作为强约束。
+2. 物料、供应商、采购申请、采购订单、交货计划必须能串联。
+3. 所有测试数据必须归属 AIDOP 租户,并带批次标记。
+4. 交货计划与采购订单数量不能明显矛盾。
+5. 交付结果需要覆盖准时、延期、部分交付、未交付。
+6. 委外和外协若旧库链路不足,可按同一批工单、物料和供应商补造。
+7. 首轮先导入需求到交货闭环,再扩展委外、外协和看板。
+
+## 8. P0 试导建议
+
+P0 试导建议选择:
+
+- 10-20 条物料需求计划。
+- 5-10 条交货计划。
+- 5 张采购申请。
+- 5 张采购订单,每张不少于 2 行。
+- 3 个供应商。
+- 3 条交货异常。
+- 2 条齐套缺料样例。
+
+## 9. 验收 SQL 方向
+
+正式 SQL 需结合实际表结构生成,至少验证:
+
+- 物料需求、交货计划、采购申请、采购订单数量。
+- 供应商、供应商物料关系数量。
+- 委外、外协订单数量。
+- 交货异常数量。
+- `mdp_stg_supply_demand`、`mdp_std_supply_demand`、`dwd_supply_demand`。
+- `mdp_std_purchase_request`、`mdp_std_purchase_order`、`mdp_std_delivery_schedule`、`mdp_std_delivery_result`。
+- `dwd_supplier_delivery`、`dwd_supplier_risk`、`dwd_material_readiness`、`dwd_material_shortage`。
+- `ado_s9_kpi_value_l1_day` 中 S3 指标写入。
+
+## 10. 下一步
+
+1. 只读确认 UAT S3 目标表结构和 AIDOP 租户数据量。
+2. 从旧库筛选物料、供应商、采购订单、交货计划样本。
+3. 补造交货异常、委外、外协、齐套上线样例。
+4. 生成 P0 试导 SQL。
+5. 人工确认后执行 P0 试导。
+6. 验证 S3 页面、MDP、DWD、KPI 和看板。

+ 131 - 0
doc/plan/S4/S4采购执行UAT数据生成执行任务书.md

@@ -0,0 +1,131 @@
+# S4 采购执行 UAT 数据生成执行任务书
+
+## 1. 任务目标
+
+为 S4 采购执行生成 UAT 测试数据,支撑供应商交货管理、供应商发货单、采购退货单、IQC 退货查询、采购执行看板主页和供应商欠料看板测试。
+
+S4 当前尚未完全完成开发,本任务以测试报告驱动数据准备。待 S4 页面、接口、表结构和数据中台链路完成后,再做实现交叉校验。
+
+## 2. 必读文档
+
+- `doc/plan/S4/S4采购执行UAT测试数据生成方案.md`
+- `doc/plan/S3/S3供应协同UAT测试数据生成方案.md`
+- `doc/plan/S1/S1产销协同UAT数据生成执行任务书.md`
+- `doc/plan/aidop项目服务器数据库相关资源信息.md`
+
+## 3. 核心约束
+
+- 所有写入数据必须使用 AIDOP 租户:`tenant_id = 797403760988229`。
+- 不得写入 Demo 租户:`tenant_id = 1300000000888`。
+- 推荐批次号:`S4_UAT_20260604_RQ_V1`。
+- 旧库仅作素材库,不做生产迁移。
+- S4 未完成前,不得假定目标表和接口已稳定。
+- 先做只读检查和 P0 SQL,未经人工确认不得写入 UAT MySQL。
+- 不要求复杂回滚脚本,但必须有批次标记。
+
+## 4. 执行阶段
+
+### 阶段 1:只读检查
+
+只允许执行 SELECT 或元数据查询。
+
+必须输出:
+
+- AIDOP 租户确认结果。
+- S4 当前已存在目标表清单。
+- 已开发页面/API 与测试报告差异。
+- AIDOP 租户下现有 S4 数据量。
+- P0 采购订单、供应商、物料是否已存在。
+
+### 阶段 2:生成 P0 中间数据
+
+P0 至少包含:
+
+- 5 张采购订单,每张不少于 2 行。
+- 5 条供应商交货记录。
+- 3 张供应商发货单。
+- 2 张采购退货单。
+- 2 条 IQC 退货查询记录。
+- 5 条供应商欠料看板记录。
+- 2 条异常场景记录。
+
+### 阶段 3:补造采购执行场景
+
+补造旧库缺失但测试报告要求的数据:
+
+- 交货发布、交期回复、按计划日期回复。
+- 生成发货单、发货单标签、送货单打印、质检附件。
+- 采购退货和 IQC 退货。
+- 供应商欠料和看板 KPI。
+- 异常场景:多供应商生成发货单、未收完关闭、发货超量、未关联采购订单。
+
+### 阶段 4:生成 P0 SQL
+
+SQL 必须包含:
+
+- 批次变量。
+- 重复数据检查。
+- ID 映射逻辑。
+- 采购订单、交货、发货、退货、IQC、欠料数据写入。
+- 验收 SQL。
+- 执行前人工确认提示。
+
+如目标表尚未完成,则先生成中间数据和字段映射草案,不执行写入。
+
+### 阶段 5:人工确认
+
+执行写入前确认:
+
+- 目标库为 UAT `aidopdev`。
+- 租户 ID 为 `797403760988229`。
+- 目标表确实存在且字段已确认。
+- 不包含全表删除、全库更新、无条件覆盖。
+- 不包含明文凭据。
+- P0 数据量符合测试报告最小要求。
+
+### 阶段 6:P0 试导与验收
+
+导入后验证:
+
+- 供应商交货管理可查询、发布、回复和生成发货单。
+- 供应商发货单可查询、编辑、生成标签、打印、上传附件。
+- 采购退货单和 IQC 退货查询有数据。
+- 采购执行看板和供应商欠料看板有数据。
+- 数据全部归属 AIDOP 租户。
+
+## 5. 给执行模型的提示词
+
+```text
+你要为 Ai-DOP 新系统 UAT 环境生成 S4 采购执行测试数据。
+
+请严格阅读:
+1. doc/plan/S4/S4采购执行UAT测试数据生成方案.md
+2. doc/plan/S4/S4采购执行UAT数据生成执行任务书.md
+3. doc/plan/aidop项目服务器数据库相关资源信息.md
+
+第一步只允许做只读检查,不得写 UAT 数据库。
+
+重要约束:
+- S4 尚未完全完成开发,当前以测试报告驱动造数。
+- 所有数据必须写入 AIDOP 租户 tenant_id = 797403760988229。
+- 不得写入 Demo 租户 tenant_id = 1300000000888。
+- 批次号使用 S4_UAT_20260604_RQ_V1。
+- 旧库只是素材库,不要全量导入。
+- 未确认目标表和字段前,不得执行写入。
+- 未经人工确认不得执行写入。
+
+请先输出:
+1. S4 当前目标表和字段确认
+2. 已开发功能与测试报告差异
+3. AIDOP 租户下现有 S4 数据量
+4. P0 数据生成计划
+5. P0 SQL 或中间数据生成计划
+```
+
+## 6. 完成标准
+
+- P0 采购订单、交货、发货、退货、IQC、欠料数据可识别。
+- 已完成开发的 S4 页面能按测试报告查询和操作。
+- 未完成开发的场景已标注为待实现交叉校验。
+- 数据全部归属 AIDOP 租户。
+- Demo 租户无新增数据。

+ 155 - 0
doc/plan/S4/S4采购执行UAT测试数据生成方案.md

@@ -0,0 +1,155 @@
+# S4 采购执行 UAT 测试数据生成方案
+
+## 1. 目标
+
+为新系统正式 UAT 测试准备 S4 采购执行业务数据。由于 S4 当前尚未完全完成开发,本方案以 `S4采购执行_UAT测试报告v1.0.xlsx` 为主要依据,先设计可支撑测试报告场景的数据包;待 S4 功能、页面、接口和数据中台链路完成后,再进行实现交叉校验和字段级修订。
+
+本方案不是生产迁移,不要求照搬旧库主键和全字段。旧 DOP 数据库仅作为真实业务素材库,必要时可以围绕测试场景补造数据。
+
+S4 的 P0 数据必须优先复用 S1-S3 全局主线。供应商交货、发货、IQC、退货和欠料数据应能追溯到 S3 采购订单或交货计划,并进一步关联到 S2 工单和 S1 销售订单。S4 尚未完全完成开发时,先按该链路设计占位数据,待功能完成后再做字段和接口校验。全局链路要求见 `doc/plan/S1-S4全局UAT场景测试数据生成方案.md`。
+
+## 2. 来源与目标
+
+| 类型 | 数据库/文件 | 用途 |
+|------|-------------|------|
+| 测试报告 | `D:\Projects\Ai-DOP\项目\项目测试\S4采购执行_UAT测试报告v1.0.xlsx` | S4 场景和用例来源 |
+| 旧 DOP 瑞奇库 | SQL Server `dopdemorq` | 采购订单、供应商、交货、发货、退货等素材来源 |
+| UAT 新系统库 | MySQL `aidopdev` | 目标导入库 |
+
+## 3. 租户与批次
+
+| 项 | 值 |
+|----|----|
+| AIDOP 租户 ID | `797403760988229`(组织名 AIDOP) |
+| UAT 登录账号 | `AIDOPDemo` / `1234567890dop` |
+| Demo 租户 ID | `1300000000888` |
+| 推荐批次号 | `S4_UAT_20260604_RQ_V1` |
+
+所有写入 UAT 的数据必须使用 `tenant_id = 797403760988229`,不得写入 Demo 租户。每批数据需带批次标记。
+
+## 4. 测试报告覆盖场景
+
+S4 测试报告包含 6 个分场景,报告要求每个场景不少于 2 张单据、每单行数不少于 2 行,并包含异常场景验证。
+
+| 序号 | 场景 | 数据要求 |
+|------|------|----------|
+| 1 | 供应商交货管理 | 采购订单、供应商、物料、计划交期、实际交期、交货数量、状态 |
+| 2 | 供应商发货单 | 发货单、供应商、采购订单、发货日期、发货数量、状态、标签、质检附件 |
+| 3 | 采购退货单 | 退货单、供应商、采购订单、退货数量、退货原因、退货状态 |
+| 4 | IQC 退货查询 | IQC 检验、退货记录、供应商、物料、质量状态 |
+| 5 | 采购执行看板主页 | 采购交付 KPI、订单交付、收货、退货、异常、风险 |
+| 6 | 供应商欠料看板 | 供应商欠料、物料缺口、交期风险、欠料数量 |
+
+## 5. 场景化数据包
+
+### 5.1 供应商交货闭环数据包
+
+用于验证供应商交货管理的查询、发布、交期回复、按计划日期回复、生成发货单、交货单关闭和导出。
+
+建议准备:
+
+- 10-20 条供应商交货记录。
+- 5-10 张采购订单,每张不少于 2 行。
+- 3-5 个供应商。
+- 覆盖未发布、已发布、已回复、收货中、已收完、已关闭状态。
+- 至少 2 条异常:多供应商生成发货单、未收完关闭交货单。
+
+### 5.2 供应商发货单数据包
+
+用于验证发货单查询、编辑、查看、生成标签、打印送货单、打印标签、上传质检报告和删除。
+
+建议准备:
+
+- 5-10 张供应商发货单,每张不少于 2 行。
+- 覆盖待确认、已生成标签、收货中、完成、已删除/作废状态。
+- 2-5 条标签数据。
+- 2-5 个质检附件占位数据。
+- 至少 1 条异常:已生成标签的发货单不可编辑。
+
+### 5.3 采购退货与 IQC 数据包
+
+用于验证采购退货单和 IQC 退货查询。
+
+建议准备:
+
+- 5-10 张采购退货单,每张不少于 2 行。
+- 覆盖待提交、已提交、已审核、已完成、作废状态。
+- 5-10 条 IQC 检验或退货查询记录。
+- 退货原因覆盖质量不合格、数量异常、错料、供应商原因。
+- 至少 2 条异常:退货数量超过已收数量、未关联检验记录退货。
+
+### 5.4 看板与欠料数据包
+
+用于验证采购执行看板主页和供应商欠料看板。
+
+建议准备:
+
+- 采购订单总数、按期交付、延期交付、退货数、异常数等 KPI 样例。
+- 供应商欠料 10-20 条,覆盖高/中/低风险。
+- 物料缺口、预计到货日、影响工单或销售订单。
+- 覆盖有数据、空数据、异常数据三种看板状态。
+
+## 6. 目标表与数据来源建议
+
+S4 尚未完全完成开发,以下目标表仅作为数据设计方向,正式执行前必须按实际表结构确认。
+
+| 数据类型 | 旧库素材表/来源 | 新系统目标/平台层 | 处理策略 |
+|----------|-----------------|-------------------|----------|
+| 供应商 | 供应商相关旧表或补造 | 供应商主数据、`mdp_std_supplier` | 至少 3-5 个供应商 |
+| 采购订单 | `PurOrdMaster`、`PurOrdDetail` | 采购订单业务表、`mdp_std_purchase_order` | 保留订单号、供应商、物料、数量、交期 |
+| 交货管理 | `srm_polist_ds` 或补造 | 供应商交货管理表、`mdp_std_delivery_schedule` | 重点覆盖发布、回复、关闭 |
+| 发货单 | 旧库发货/ASN 或补造 | 供应商发货单表、标签表 | 按采购订单生成 |
+| 收货/IQC | 收货、检验相关旧表或补造 | IQC、收货、退货相关表 | S4 未完成时以测试报告字段补造 |
+| 采购退货 | 退货相关旧表或补造 | 采购退货单表 | 覆盖退货状态和原因 |
+| 欠料看板 | 采购订单、交货计划、工单缺料 | 欠料看板、DWD/KPI | 可与 S3 齐套/缺料样例联动 |
+
+## 7. 生成与导入原则
+
+1. S4 当前以测试报告驱动造数,不假定所有页面/API/表已完成。
+2. 正式执行前必须只读确认 S4 目标表结构。
+3. 旧库只作为素材库,不保留旧库原始主键作为强约束。
+4. 采购订单、交货记录、发货单、退货单、IQC、欠料必须能通过供应商、采购订单号、物料编码串联。
+5. 交货数量、发货数量、收货数量、退货数量不能明显矛盾。
+6. 异常样例需单独标记,避免影响正常闭环数据。
+7. 所有数据写入 AIDOP 租户,并带批次标记。
+
+## 8. P0 试导建议
+
+P0 试导建议选择:
+
+- 5 张采购订单,每张不少于 2 行。
+- 5 条供应商交货记录。
+- 3 张供应商发货单。
+- 2 张采购退货单。
+- 2 条 IQC 退货查询记录。
+- 5 条供应商欠料看板记录。
+- 2 条异常场景记录。
+
+## 9. 验收方向
+
+正式 SQL 需结合实际表结构生成,至少验证:
+
+- 采购订单、交货记录、发货单、退货单、IQC 记录数量。
+- 供应商欠料记录数量。
+- 供应商、物料、采购订单关联完整性。
+- 看板 KPI 数据是否能按 AIDOP 租户产出。
+- S4 页面已开发部分是否能按测试报告查询和操作。
+
+## 10. 待开发完成后的补充校验
+
+S4 功能完成后必须补做:
+
+- 页面菜单和按钮与测试报告逐项对照。
+- 后端 API / Service 实际读取表确认。
+- MDP、DWD、KPI 链路确认。
+- 目标表字段级映射确认。
+- P0 试导 SQL 重新生成和人工确认。
+
+## 11. 下一步
+
+1. 只读确认 UAT S4 已有表结构和当前开发完成范围。
+2. 按测试报告生成 P0 中间数据。
+3. 从旧库筛选采购订单、供应商、物料、交货素材。
+4. 补造发货单、采购退货、IQC 和欠料样例。
+5. 生成 P0 试导 SQL。
+6. 待人工确认后执行 P0 试导。

+ 1346 - 0
doc/plan/sql/S1S4_UAT_FULL_execute_write.sql

@@ -0,0 +1,1346 @@
+-- S1-S4 FULL UAT write (AIDOP tenant 797403760988229)
+-- Batch: S1S4_UAT_FULL_20260605_V1
+-- Generated: 2026-06-05 00:47:27
+-- Orders: 45
+
+SET @tenant_id     := 797403760988229;
+SET @batch_no      := 'S1S4_UAT_FULL_20260605_V1';
+SET @operator_id   := 1300000000111;
+SET @operator_name := 'UAT鏁版嵁瀵煎叆';
+SET @now           := NOW();
+SET @factory_id    := 797403760988229;
+SET @id_base       := 9106000500000001;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so;
+CREATE TEMPORARY TABLE tmp_s1_uat_so (
+    bill_no VARCHAR(64) NOT NULL PRIMARY KEY,
+    target_id BIGINT NOT NULL,
+    custom_no VARCHAR(64) NULL,
+    custom_name VARCHAR(128) NULL,
+    order_date DATETIME NULL,
+    delivery_date DATETIME NULL,
+    urgent INT DEFAULT 0
+);
+INSERT INTO tmp_s1_uat_so VALUES
+('MPO482024102400001',9106000500000002,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482024120200001',9106000500000003,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482024120200002',9106000500000004,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482024120400002',9106000500000005,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025010700001',9106000500000006,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025010700002',9106000500000007,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025010900001',9106000500000008,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011000001',9106000500000009,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011000002',9106000500000010,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011000003',9106000500000011,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011300002',9106000500000012,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011300003',9106000500000013,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011300005',9106000500000014,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011300006',9106000500000015,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011400001',9106000500000016,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025011400002',9106000500000017,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',1),
+('MPO482025022100001',9106000500000018,'CUST0005','WKQXGFYXGE','2025-02-26 00:00:00.000','2025-02-26 00:00:00.000',1),
+('MPO482025032900001',9106000500000019,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025041300001',9106000500000020,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025042800001',9106000500000021,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025051800001',9106000500000022,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025062100002',9106000500000023,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025062100003',9106000500000024,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025062600003',9106000500000025,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025081500001',9106000500000026,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025081500002',9106000500000027,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025082900002',9106000500000028,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025090400005',9106000500000029,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025091800003',9106000500000030,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025091900001',9106000500000031,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482025092200002',9106000500000032,'CUST0005','WKQXGFYXGE','2025-06-01 00:00:00.000','2025-06-15 00:00:00.000',0),
+('MPO482026012100001',9106000500000033,'CUST0005','WKQXGFYXGE','2026-01-21 00:00:00.000','2026-01-21 00:00:00.000',0),
+('MPO482026020300001',9106000500000034,'10000000','瑞贝德','2026-02-03 00:00:00.000','2026-02-03 00:00:00.000',0),
+('SO241020240923001',9106000500000035,'CUST0005','ET0005','2024-09-23 00:00:00.000','2024-09-23 00:00:00.000',0),
+('SO241020241014001',9106000500000036,'CUST0005','ET0005','2024-10-14 00:00:00.000','2024-10-14 00:00:00.000',0),
+('SO241020241015003',9106000500000037,'CUST0005','ET0005','2024-10-15 00:00:00.000','2024-10-15 00:00:00.000',0),
+('SO241020241018001',9106000500000038,'CUST0005','ET0005','2024-10-18 00:00:00.000','2024-10-18 00:00:00.000',0),
+('SO241020241019001',9106000500000039,'CUST0005','ET0005','2024-10-19 00:00:00.000','2024-10-19 00:00:00.000',0),
+('SO241020241021002',9106000500000040,'CUST0005','ET0005','2024-10-21 00:00:00.000','2024-10-21 00:00:00.000',0),
+('SO241020241022001',9106000500000041,'CUST0005','ET0005','2024-10-22 00:00:00.000','2024-10-22 00:00:00.000',0),
+('SO241020241102001',9106000500000042,'CUST0005','ET0005','2024-11-02 00:00:00.000','2024-11-02 00:00:00.000',0),
+('SO241020241102004',9106000500000043,'CUST0005','ET0005','2024-11-02 00:00:00.000','2024-11-02 00:00:00.000',0),
+('SO241020241104001',9106000500000044,'CUST0005','ET0005','2024-11-04 00:00:00.000','2024-11-04 00:00:00.000',0),
+('SO241020241219001',9106000500000045,'CUST0005','ET0005','2024-12-19 00:00:00.000','2024-12-19 00:00:00.000',0),
+('SO241020250114003',9106000500000046,'CUST0005','ET0005','2025-01-14 00:00:00.000','2025-01-14 00:00:00.000',0);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so_line;
+CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
+    target_id BIGINT NOT NULL PRIMARY KEY,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    entry_seq INT NOT NULL,
+    item_number VARCHAR(64) NULL,
+    qty DECIMAL(18,4) NULL,
+    plan_date DATETIME NULL
+);
+INSERT INTO tmp_s1_uat_so_line VALUES
+(9106000500010002,'604438178041925','MPO482024102400001',1,'91DC0292',4500.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010003,'604438178041926','MPO482024102400001',2,'1A03D23',3500.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010004,'604438178046021','MPO482024102400001',3,'1A0C329',400000.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010005,'604438178046022','MPO482024102400001',4,'1A0C655',100000.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010006,'604438178046023','MPO482024102400001',5,'A2C7114',250000.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010007,'604438178046024','MPO482024102400001',6,'A2C7115',600000.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010008,'604438178050117','MPO482024102400001',7,'A2B4199',6000.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010009,'604438178050118','MPO482024102400001',8,'1A0C588',10000.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010010,'604438178050119','MPO482024102400001',9,'1A03G94',2500.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010011,'604438178050120','MPO482024102400001',10,'91CC0286',1500.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010012,'604438178054213','MPO482024102400001',11,'91DC0218',800.00000000,'2024-10-31 00:00:00.000'),
+(9106000500010013,'618270140751941','MPO482024120200001',1,'91CC0229',60.00000000,'2024-12-06 00:00:00.000'),
+(9106000500010014,'618290062549061','MPO482024120200002',1,'91DC0218',2000.00000000,'2024-12-30 00:00:00.000'),
+(9106000500010015,'619057595396165','MPO482024120400002',1,'91CC0237',200.00000000,'2024-12-12 00:00:00.000'),
+(9106000500010016,'630994145116229','MPO482025010700001',1,'A2C7114',250000.00000000,'2025-01-10 00:00:00.000'),
+(9106000500010017,'631069575503941','MPO482025010700002',1,'1A0C329',100000.00000000,'2025-01-15 00:00:00.000'),
+(9106000500010018,'631769478479941','MPO482025010900001',1,'91CC0312',500.00000000,'2025-01-24 00:00:00.000'),
+(9106000500010019,'631769478479942','MPO482025010900001',2,'1A03D23',600.00000000,'2025-01-14 00:00:00.000'),
+(9106000500010020,'631769478484037','MPO482025010900001',3,'91CC0231',100.00000000,'2025-01-23 00:00:00.000'),
+(9106000500010021,'631769478484038','MPO482025010900001',4,'91CC0286',800.00000000,'2025-02-06 00:00:00.000'),
+(9106000500010022,'632121332793413','MPO482025011000001',1,'91C0D058',400.00000000,'2025-02-05 00:00:00.000'),
+(9106000500010023,'632124508205125','MPO482025011000002',1,'A2B8361',1000.00000000,'2025-02-05 00:00:00.000'),
+(9106000500010024,'632125640785989','MPO482025011000003',1,'A2B8184',700.00000000,'2025-02-05 00:00:00.000'),
+(9106000500010025,'633173731577925','MPO482025011300002',1,'A2B4199',4000.00000000,'2025-02-17 00:00:00.000'),
+(9106000500010026,'633178120278085','MPO482025011300003',1,'1A03D23',5000.00000000,'2025-02-27 00:00:00.000'),
+(9106000500010027,'633197803688005','MPO482025011300005',1,'ABC431',10000.00000000,'2025-02-27 00:00:00.000'),
+(9106000500010028,'633197803688006','MPO482025011300005',2,'1A0C432',10000.00000000,'2025-02-27 00:00:00.000'),
+(9106000500010029,'633206945230917','MPO482025011300006',1,'ABC419',35000.00000000,'2025-02-17 00:00:00.000'),
+(9106000500010030,'633515239526469','MPO482025011400001',1,'1A0C293',650000.00000000,'2025-02-27 00:00:00.000'),
+(9106000500010031,'633515239526470','MPO482025011400001',2,'1A0C329',200000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010032,'633520970641477','MPO482025011400002',1,'91DC0215',1500.00000000,'2025-02-28 00:00:00.000'),
+(9106000500010033,'646977501577285','MPO482025022100001',1,'91CC0179',5000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010034,'646977501577286','MPO482025022100001',2,'91CC0287',10000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010035,'646977501581381','MPO482025022100001',3,'91CC0288',10000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010036,'646977501581382','MPO482025022100001',4,'91CC0187',5000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010037,'646977501581383','MPO482025022100001',5,'91CC0233',1500.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010038,'646977501581384','MPO482025022100001',6,'91DC0218',3000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010039,'646977501581385','MPO482025022100001',7,'A21C096',10000.00000000,'2025-02-26 00:00:00.000'),
+(9106000500010040,'659719952244805','MPO482025032900001',1,'91CC0177',5000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010041,'659719952244806','MPO482025032900001',2,'91CC0179',5000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010042,'659719952248901','MPO482025032900001',3,'91CC0287',4000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010043,'659719952248902','MPO482025032900001',4,'91DC0217',2000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010044,'659719952248903','MPO482025032900001',5,'91DC0219',9000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010045,'659719952248904','MPO482025032900001',6,'91C0D2D',2000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010046,'659719952252997','MPO482025032900001',7,'AB47111',200000.00000000,'2025-04-03 00:00:00.000'),
+(9106000500010047,'665010090852421','MPO482025041300001',1,'352AD0A',1.00000000,'2025-04-18 00:00:00.000'),
+(9106000500010048,'665010090852422','MPO482025041300001',2,'3521C0014',1.00000000,'2025-04-18 00:00:00.000'),
+(9106000500010049,'665010090852423','MPO482025041300001',3,'3151C0033',1.00000000,'2025-04-18 00:00:00.000'),
+(9106000500010050,'665010090856517','MPO482025041300001',4,'3151C0034',1.00000000,'2025-04-18 00:00:00.000'),
+(9106000500010051,'670272721616965','MPO482025042800001',1,'3221C0031',7000.00000000,'2025-04-30 00:00:00.000'),
+(9106000500010052,'677416091480133','MPO482025051800001',1,'3521C0015',1.00000000,'2025-05-23 00:00:00.000'),
+(9106000500010053,'677416091480134','MPO482025051800001',2,'3521C0015',1.00000000,'2025-05-23 00:00:00.000'),
+(9106000500010054,'677416091480135','MPO482025051800001',3,'3521C0015',1.00000000,'2025-05-23 00:00:00.000'),
+(9106000500010055,'677416091480136','MPO482025051800001',4,'3521C0015',1.00000000,'2025-05-23 00:00:00.000'),
+(9106000500010056,'677416091480137','MPO482025051800001',5,'3521C0015',1.00000000,'2025-05-28 00:00:00.000'),
+(9106000500010057,'677416091484229','MPO482025051800001',6,'3521C0015',1.00000000,'2025-05-28 00:00:00.000'),
+(9106000500010058,'677416091484230','MPO482025051800001',7,'3521C0015',1.00000000,'2025-05-28 00:00:00.000'),
+(9106000500010059,'677416091484231','MPO482025051800001',8,'3521C0015',1.00000000,'2025-05-28 00:00:00.000'),
+(9106000500010060,'677416091484232','MPO482025051800001',9,'3521C0015',1.00000000,'2025-05-28 00:00:00.000'),
+(9106000500010061,'677416091484233','MPO482025051800001',10,'3521C0015',1.00000000,'2025-05-28 00:00:00.000'),
+(9106000500010062,'689366516133957','MPO482025062100002',1,'3151C0034',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010063,'689366516133958','MPO482025062100002',2,'3151C0034',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010064,'689366516133959','MPO482025062100002',3,'3151C0034',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010065,'689366516138053','MPO482025062100002',4,'3151C0034',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010066,'689366516138054','MPO482025062100002',5,'3151C0034',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010067,'689366516138055','MPO482025062100002',6,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010068,'689366516138056','MPO482025062100002',7,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010069,'689366516142149','MPO482025062100002',8,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010070,'689366516142150','MPO482025062100002',9,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010071,'689366516142151','MPO482025062100002',10,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010072,'689366516142152','MPO482025062100002',11,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010073,'689366516142153','MPO482025062100002',12,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010074,'689369829818437','MPO482025062100003',1,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010075,'689369829818438','MPO482025062100003',2,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010076,'689369829818439','MPO482025062100003',3,'3521C0016',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010077,'689369829818440','MPO482025062100003',4,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010078,'689369829822533','MPO482025062100003',5,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010079,'689369829822534','MPO482025062100003',6,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010080,'689369829822535','MPO482025062100003',7,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010081,'689369829822536','MPO482025062100003',8,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010082,'689369829826629','MPO482025062100003',9,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010083,'689369829826630','MPO482025062100003',10,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010084,'689369829826631','MPO482025062100003',11,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010085,'689369829826632','MPO482025062100003',12,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010086,'689369829826633','MPO482025062100003',13,'352AD0A',1.00000000,'2025-06-27 00:00:00.000'),
+(9106000500010087,'691329582436421','MPO482025062600003',1,'91CC0178',4000.00000000,'2025-07-04 00:00:00.000'),
+(9106000500010088,'691329582436422','MPO482025062600003',2,'91CC0285',2000.00000000,'2025-07-04 00:00:00.000'),
+(9106000500010089,'691329582436423','MPO482025062600003',3,'91CC0286',4000.00000000,'2025-07-04 00:00:00.000'),
+(9106000500010090,'691329582440517','MPO482025062600003',4,'A2B8361',4000.00000000,'2025-07-04 00:00:00.000'),
+(9106000500010091,'708842858610757','MPO482025081500001',1,'1A0C273',200.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010092,'708842858610758','MPO482025081500001',2,'1A0C275',272.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010093,'708842858610759','MPO482025081500001',3,'1A004C4',960000.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010094,'708842858610760','MPO482025081500001',4,'ABC419',1000.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010095,'708842858610761','MPO482025081500001',5,'ABC431',2000.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010096,'708842858610762','MPO482025081500001',6,'1A0C432',1000.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010097,'708842858610763','MPO482025081500001',7,'1A0C588',29000.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010098,'708842858614853','MPO482025081500001',8,'1A0C595',670000.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010099,'708842858614854','MPO482025081500001',9,'AB32A4',111.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010100,'708853132763205','MPO482025081500002',1,'A21C092',550.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010101,'708853132763206','MPO482025081500002',2,'A21C093',60.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010102,'708853132763207','MPO482025081500002',3,'91B0D033',38.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010103,'708853132767301','MPO482025081500002',4,'91C0D058',558.00000000,'2025-08-22 00:00:00.000'),
+(9106000500010104,'708853132767302','MPO482025081500002',5,'91C0D074',2522.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010105,'708853132767303','MPO482025081500002',6,'91C0DA8',69.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010106,'708853132771397','MPO482025081500002',7,'93B0D1A',185.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010107,'708853132771398','MPO482025081500002',8,'91CC0123',2.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010108,'708853132771399','MPO482025081500002',9,'91CC0229',862.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010109,'708853132771400','MPO482025081500002',10,'91CC0262',200.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010110,'708853132771401','MPO482025081500002',11,'91CC0286',3000.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010111,'708853132775493','MPO482025081500002',12,'91CC0312',300.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010112,'708853132775494','MPO482025081500002',13,'91C0DD4',100.00000000,'2025-08-22 00:00:00.000'),
+(9106000500010113,'708853132775495','MPO482025081500002',14,'91CC0412',58.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010114,'708853132775496','MPO482025081500002',15,'91C0DE2',400.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010115,'708853132775497','MPO482025081500002',16,'91C0DE3',1050.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010116,'708853132779589','MPO482025081500002',17,'91C0DE6',400.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010117,'708853132779590','MPO482025081500002',18,'91C0DE7',1000.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010118,'708853132779591','MPO482025081500002',19,'91C0DE9',350.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010119,'708853132779592','MPO482025081500002',20,'91C0D5A',1100.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010120,'708853132779593','MPO482025081500002',21,'91CC0518',1250.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010121,'708853132783685','MPO482025081500002',22,'91CC0521',3000.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010122,'708853132783686','MPO482025081500002',23,'91CC0524',1500.00000000,'2025-08-29 00:00:00.000'),
+(9106000500010123,'708853132783687','MPO482025081500002',24,'91CC0525',3000.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010124,'708853132783688','MPO482025081500002',25,'91FC0339',600.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010125,'708853132783689','MPO482025081500002',26,'1AB9259',5000.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010126,'708853132783690','MPO482025081500002',27,'3124C0015',8000.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010127,'708853132787781','MPO482025081500002',28,'3151C0032',1.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010128,'708853132787782','MPO482025081500002',29,'1A0C452',1000.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010129,'708853132787783','MPO482025081500002',30,'1A03G82',3000.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010130,'708853132787784','MPO482025081500002',31,'91CC0319',160000.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010131,'708853132787785','MPO482025081500002',32,'AB37A2',16000.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010132,'708853132791877','MPO482025081500002',33,'91CC0248',500.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010133,'708853132791878','MPO482025081500002',34,'91C00EN',60000.00000000,'2025-08-21 00:00:00.000'),
+(9106000500010134,'708853132791879','MPO482025081500002',35,'AB37A3',130000.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010135,'708853132791880','MPO482025081500002',36,'91CC0517',100.00000000,'2025-08-28 00:00:00.000'),
+(9106000500010136,'708853132791881','MPO482025081500002',37,'3151C0034',1.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010137,'708853132791882','MPO482025081500002',38,'3151C0034',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010138,'708853132791883','MPO482025081500002',39,'3151C0034',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010139,'708853132791884','MPO482025081500002',40,'3151C0034',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010140,'708853132791885','MPO482025081500002',41,'3151C0034',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010141,'708853132795973','MPO482025081500002',42,'3151C0033',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010142,'708853132795974','MPO482025081500002',43,'3151C0033',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010143,'708853132795975','MPO482025081500002',44,'3151C0033',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010144,'708853132795976','MPO482025081500002',45,'3151C0033',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010145,'708853132795977','MPO482025081500002',46,'3151C0033',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010146,'708853132795978','MPO482025081500002',47,'3151C0033',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010147,'708853132795979','MPO482025081500002',48,'3151C0033',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010148,'708853132795980','MPO482025081500002',49,'3151C0033',1.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010149,'708853132795981','MPO482025081500002',50,'3521C0015',1.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010150,'708853132795982','MPO482025081500002',51,'3521C0015',1.00000000,'2025-08-19 00:00:00.000'),
+(9106000500010151,'708853132795983','MPO482025081500002',52,'3521C0015',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010152,'708853132800069','MPO482025081500002',53,'3521C0015',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010153,'708853132800070','MPO482025081500002',54,'3521C0015',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010154,'708853132800071','MPO482025081500002',55,'3521C0015',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010155,'708853132800072','MPO482025081500002',56,'3521C0015',1.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010156,'708853132800073','MPO482025081500002',57,'3521C0015',1.00000000,'2025-08-20 00:00:00.000'),
+(9106000500010157,'708853132800074','MPO482025081500002',58,'3521C0015',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010158,'708853132800075','MPO482025081500002',59,'3521C0015',1.00000000,'2025-08-27 00:00:00.000'),
+(9106000500010159,'708853132800076','MPO482025081500002',60,'3521C0015',1.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010160,'708853132800077','MPO482025081500002',61,'3521C0015',1.00000000,'2025-08-19 00:00:00.000'),
+(9106000500010161,'708853132804165','MPO482025081500002',62,'3521C0015',1.00000000,'2025-08-26 00:00:00.000'),
+(9106000500010162,'713850861281349','MPO482025082900002',1,'91C0D2G',5000.00000000,'2025-08-31 00:00:00.000'),
+(9106000500010163,'713850861281350','MPO482025082900002',2,'93BC0311',510.00000000,'2025-08-30 00:00:00.000'),
+(9106000500010164,'713850861281351','MPO482025082900002',3,'91CC0312',500.00000000,'2025-08-30 00:00:00.000'),
+(9106000500010165,'713850861285445','MPO482025082900002',4,'91CC0233',400.00000000,'2025-08-30 00:00:00.000'),
+(9106000500010166,'713850861285446','MPO482025082900002',5,'91CC0232',1500.00000000,'2025-08-30 00:00:00.000'),
+(9106000500010167,'716009096228933','MPO482025090400005',1,'91CC0312',5000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010168,'716009096228934','MPO482025090400005',2,'93BC0311',5000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010169,'720949568118853','MPO482025091800003',1,'91CC0483',1900.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010170,'720949568118854','MPO482025091800003',2,'91CC0312',100.00000000,'2025-09-25 00:00:00.000'),
+(9106000500010171,'720949568118855','MPO482025091800003',3,'93BC0311',600.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010172,'720949568122949','MPO482025091800003',4,'91CC0313',100.00000000,'2025-09-29 00:00:00.000'),
+(9106000500010173,'720949568122950','MPO482025091800003',5,'91CC0229',700.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010174,'721256689414213','MPO482025091900001',1,'91CC0182',10000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010175,'721256689414214','MPO482025091900001',2,'312CD009',10000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010176,'721256689414215','MPO482025091900001',3,'3123C0012',10000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010177,'721256689414216','MPO482025091900001',4,'3123C0026',3000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010178,'721256689414217','MPO482025091900001',5,'3123C0027',3000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010179,'721256689418309','MPO482025091900001',6,'3123C0028',3000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010180,'721256689418310','MPO482025091900001',7,'3123C0035',10000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010181,'721256689418311','MPO482025091900001',8,'3123C0046',3000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010182,'721256689422405','MPO482025091900001',9,'3123C0047',3000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010183,'721256689422406','MPO482025091900001',10,'3123C0048',3000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010184,'721256689422407','MPO482025091900001',11,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010185,'721256689422408','MPO482025091900001',12,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010186,'721256689426501','MPO482025091900001',13,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010187,'721256689426502','MPO482025091900001',14,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010188,'721256689426503','MPO482025091900001',15,'3521C0016',1.00000000,'2025-09-24 00:00:00.000'),
+(9106000500010189,'721256689426504','MPO482025091900001',16,'3521C0016',1.00000000,'2025-09-25 00:00:00.000'),
+(9106000500010190,'721256689426505','MPO482025091900001',17,'3521C0016',1.00000000,'2025-09-25 00:00:00.000'),
+(9106000500010191,'721256689430597','MPO482025091900001',18,'3521C0016',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010192,'721256689430598','MPO482025091900001',19,'3521C0016',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010193,'721256689430599','MPO482025091900001',20,'3521C0016',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010194,'721256689430600','MPO482025091900001',21,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010195,'721256689434693','MPO482025091900001',22,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010196,'721256689434694','MPO482025091900001',23,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010197,'721256689434695','MPO482025091900001',24,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010198,'721256689434696','MPO482025091900001',25,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010199,'721256689438789','MPO482025091900001',26,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010200,'721256689438790','MPO482025091900001',27,'3521C0015',1.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010201,'722351552172101','MPO482025092200002',1,'91CC0283',20000.00000000,'2025-09-30 00:00:00.000'),
+(9106000500010202,'765148661813317','MPO482026012100001',1,'1A0044F',1000.00000000,'2026-01-25 00:00:00.000'),
+(9106000500010203,'765148661813318','MPO482026012100001',2,'1A0045H',1000.00000000,'2026-01-25 00:00:00.000'),
+(9106000500010204,'765148661813319','MPO482026012100001',3,'1A0047E',1000.00000000,'2026-01-25 00:00:00.000'),
+(9106000500010205,'769809191923781','MPO482026020300001',1,'1A0044F',100.00000000,'2026-02-09 00:00:00.000'),
+(9106000500010206,'1958480382326104095','SO241020240923001',1,'91CC0232',400.00000000,'2024-09-23 17:36:13.000'),
+(9106000500010207,'1958480382326104096','SO241020240923001',2,'91CC0287',567.00000000,'2024-09-23 17:36:23.000'),
+(9106000500010208,'1958480382326104097','SO241020240923001',3,'91CC0288',256.00000000,'2024-09-23 17:36:38.000'),
+(9106000500010209,'1958480382326104098','SO241020240923001',4,'91C0D3A',400.00000000,'2024-09-23 17:36:55.000'),
+(9106000500010210,'1958480382326104099','SO241020240923001',5,'91CC0312',590.00000000,'2024-09-23 17:37:10.000'),
+(9106000500010211,'1958480382326104100','SO241020240923001',6,'91DC0219',1216.00000000,'2024-09-23 17:37:40.000'),
+(9106000500010212,'1958480382326104101','SO241020240923001',7,'91DC0284',1104.00000000,'2024-09-23 17:37:58.000'),
+(9106000500010213,'1958480382326104102','SO241020240923001',8,'91DC0292',1415.00000000,'2024-09-23 17:38:21.000'),
+(9106000500010214,'1958480382326104103','SO241020240923001',9,'91C0DC8',1200.00000000,'2024-09-23 17:53:47.000'),
+(9106000500010215,'1958480382326104104','SO241020240923001',10,'1A03D23',511.00000000,'2024-09-23 17:54:41.000'),
+(9106000500010216,'1958480382326104105','SO241020240923001',11,'91CC0228',1695.00000000,'2024-09-23 17:54:51.000'),
+(9106000500010217,'1958480382326104106','SO241020240923001',12,'91DC0213',210.00000000,'2024-09-24 09:07:26.000'),
+(9106000500010218,'1958480382326104265','SO241020241014001',1,'AB04C1',100.00000000,'2024-10-14 16:24:39.000'),
+(9106000500010219,'1958480382326104266','SO241020241014001',2,'1AB2737',66.00000000,'2024-10-14 16:24:52.000'),
+(9106000500010220,'1958480382326104267','SO241020241014001',3,'A2B5613',190.00000000,'2024-10-14 16:25:17.000'),
+(9106000500010221,'1958480382326104268','SO241020241014001',4,'1A03G94',83.00000000,'2024-10-14 16:25:40.000'),
+(9106000500010222,'1958480382326104269','SO241020241014001',5,'1A03G96',4208.00000000,'2024-10-14 16:25:51.000'),
+(9106000500010223,'1958480382326104270','SO241020241014001',6,'AB37A2',1000.00000000,'2024-10-14 16:26:17.000'),
+(9106000500010224,'1958480382326104271','SO241020241014001',7,'A2C7113',115000.00000000,'2024-10-14 16:26:36.000'),
+(9106000500010225,'1958480382326104272','SO241020241014001',8,'A2C7114',120000.00000000,'2024-10-14 16:28:00.000'),
+(9106000500010226,'1958480382326104273','SO241020241014001',9,'A2C7115',280000.00000000,'2024-10-14 16:28:17.000'),
+(9106000500010227,'1958480382326104274','SO241020241014001',10,'A2C7116',10000.00000000,'2024-10-14 16:28:31.000'),
+(9106000500010228,'1958480382326104275','SO241020241014001',11,'A2C7117',30000.00000000,'2024-10-14 16:28:44.000'),
+(9106000500010229,'1958480382326104276','SO241020241014001',12,'A2B8361',400.00000000,'2024-10-14 16:29:26.000'),
+(9106000500010230,'1958480382326104277','SO241020241014001',13,'1AB9259',418.00000000,'2024-10-14 16:29:43.000'),
+(9106000500010231,'1958480382326104278','SO241020241014001',14,'A21C096',1088.00000000,'2024-10-14 16:30:04.000'),
+(9106000500010232,'1958480382326104279','SO241020241014001',15,'91C0D058',300.00000000,'2024-10-14 16:30:25.000'),
+(9106000500010233,'1958480382326104280','SO241020241014001',16,'91CC0283',1107.00000000,'2024-10-14 16:30:41.000'),
+(9106000500010234,'1958480382326104286','SO241020241015003',1,'91CC0229',1000.00000000,'2024-10-15 17:40:11.000'),
+(9106000500010235,'1958480382326104287','SO241020241015003',2,'91FC0339',600.00000000,'2024-10-15 17:40:33.000'),
+(9106000500010236,'1958480382326104288','SO241020241015003',3,'91CC0319',7000.00000000,'2024-10-15 17:40:45.000'),
+(9106000500010237,'1958480382326104289','SO241020241015003',4,'91DC0284',1635.00000000,'2024-10-15 17:40:58.000'),
+(9106000500010238,'1958480382326104290','SO241020241015003',5,'91DC0219',975.00000000,'2024-10-15 17:41:16.000'),
+(9106000500010239,'1958480382326104291','SO241020241015003',6,'91CC0283',368.00000000,'2024-10-15 17:41:28.000'),
+(9106000500010240,'1958480382326104292','SO241020241015003',7,'1A03G96',822.00000000,'2024-10-15 17:41:41.000'),
+(9106000500010241,'1958480382326104293','SO241020241015003',8,'91C0D2G',1200.00000000,'2024-10-15 17:41:54.000'),
+(9106000500010242,'1958480382326104294','SO241020241015003',9,'1A03G82',10000.00000000,'2024-10-15 17:42:06.000'),
+(9106000500010243,'1958480382326104295','SO241020241015003',10,'ABC431',6614.00000000,'2024-10-15 17:42:20.000'),
+(9106000500010244,'1958480382326104296','SO241020241015003',11,'1A0C432',7810.00000000,'2024-10-15 17:42:33.000'),
+(9106000500010245,'1958480382326104297','SO241020241015003',12,'1A0387B',341.00000000,'2024-10-15 17:42:48.000'),
+(9106000500010246,'1958480382326104298','SO241020241015003',13,'91C0DC8',400.00000000,'2024-10-15 17:43:01.000'),
+(9106000500010247,'1958480382326104299','SO241020241015003',14,'1A03D23',958.00000000,'2024-10-15 17:43:24.000'),
+(9106000500010248,'1958480382326104300','SO241020241015003',15,'91CC0235',200.00000000,'2024-10-15 17:43:37.000'),
+(9106000500010249,'1958480382326104301','SO241020241015003',16,'91CC0179',300.00000000,'2024-10-15 17:43:54.000'),
+(9106000500010250,'1958902016386269185','SO241020241018001',1,'91C0DC9',280.00000000,'2024-10-18 17:34:58.000'),
+(9106000500010251,'1958902016386269186','SO241020241018001',2,'ABC431',4000.00000000,'2024-10-18 17:35:20.000'),
+(9106000500010252,'1958902016386269187','SO241020241018001',3,'1A0C432',4200.00000000,'2024-10-18 17:35:29.000'),
+(9106000500010253,'1958902016386269188','SO241020241018001',4,'1A0C595',200000.00000000,'2024-10-18 17:35:44.000'),
+(9106000500010254,'1958902016386269189','SO241020241018001',5,'1A0C689',400.00000000,'2024-10-18 17:36:00.000'),
+(9106000500010255,'1958902016386269190','SO241020241018001',6,'1AB2755',101.00000000,'2024-10-18 17:36:12.000'),
+(9106000500010256,'1958902016386269191','SO241020241018001',7,'AB3D14',50000.00000000,'2024-10-18 17:36:23.000'),
+(9106000500010257,'1958902016386269192','SO241020241018001',8,'A2B5613',1783.00000000,'2024-10-18 17:36:38.000'),
+(9106000500010258,'1958902016386269193','SO241020241018001',9,'1A03G96',1473.00000000,'2024-10-18 17:36:50.000'),
+(9106000500010259,'1958902016386269194','SO241020241018001',10,'91DC0214',600.00000000,'2024-10-18 17:37:10.000'),
+(9106000500010260,'1958902016386269195','SO241020241018001',11,'91DC0219',202.00000000,'2024-10-18 17:37:23.000'),
+(9106000500010261,'1958902016386269196','SO241020241018001',12,'AB3B81',256.00000000,'2024-10-18 17:38:03.000'),
+(9106000500010262,'1958902016386269197','SO241020241018001',13,'91CC0177',81.00000000,'2024-10-18 17:38:14.000'),
+(9106000500010263,'1958902016386269198','SO241020241018001',14,'91C0D2D',400.00000000,'2024-10-18 17:38:28.000'),
+(9106000500010264,'1958902016386269199','SO241020241018001',15,'91CC0283',1044.00000000,'2024-10-18 17:38:38.000'),
+(9106000500010265,'1958902016386269200','SO241020241018001',16,'91CC0236',400.00000000,'2024-10-18 17:38:50.000'),
+(9106000500010266,'1958902016386269201','SO241020241018001',17,'91DC0284',1082.00000000,'2024-10-18 17:39:00.000'),
+(9106000500010267,'1958902016386269202','SO241020241018001',18,'91DC0292',202.00000000,'2024-10-18 17:39:14.000'),
+(9106000500010268,'1958956122157088769','SO241020241019001',1,'91CC0187',54.00000000,'2024-10-19 16:25:13.000'),
+(9106000500010269,'1958956122157088770','SO241020241019001',2,'91FC0339',11.00000000,'2024-10-19 16:25:29.000'),
+(9106000500010270,'1958956122157088771','SO241020241019001',3,'91CC0228',131.00000000,'2024-10-19 16:25:40.000'),
+(9106000500010271,'1958956122157088772','SO241020241019001',4,'91C0D051',1.00000000,'2024-10-19 16:25:52.000'),
+(9106000500010272,'1958956122157088773','SO241020241019001',5,'A21C092',15.00000000,'2024-10-19 16:25:59.000'),
+(9106000500010273,'1959718646913695745','SO241020241021002',1,'1A039D8',350.00000000,'2024-10-21 18:33:52.000'),
+(9106000500010274,'1959718646913695746','SO241020241021002',2,'91CC0283',716.00000000,'2024-10-21 18:34:04.000'),
+(9106000500010275,'1959718646913695747','SO241020241021002',3,'91DC0292',967.00000000,'2024-10-21 18:34:17.000'),
+(9106000500010276,'1959718646917890048','SO241020241021002',4,'91DC0284',640.00000000,'2024-10-21 18:53:13.000'),
+(9106000500010277,'1959718646917890049','SO241020241021002',5,'1A03D23',1134.00000000,'2024-10-21 18:53:36.000'),
+(9106000500010278,'1959718646917890050','SO241020241021002',6,'91CC0229',1800.00000000,'2024-10-21 18:53:49.000'),
+(9106000500010279,'1959718646917890051','SO241020241021002',7,'91CC0241',200.00000000,'2024-10-21 18:54:00.000'),
+(9106000500010280,'1959718646917890052','SO241020241021002',8,'91CC0278',70.00000000,'2024-10-21 18:54:18.000'),
+(9106000500010281,'1959718646917890053','SO241020241021002',9,'91DC0215',587.00000000,'2024-10-21 19:38:04.000'),
+(9106000500010282,'1959729971345752064','SO241020241021002',10,'91DC0215',587.00000000,'2024-10-21 19:38:04.000'),
+(9106000500010283,'1960006795304894465','SO241020241022001',1,'91CC0235',600.00000000,'2024-10-22 14:01:07.000'),
+(9106000500010284,'1963915047889534977','SO241020241102001',1,'91CC0287',313.00000000,'2024-11-02 08:44:39.000'),
+(9106000500010285,'1963915047889534978','SO241020241102001',2,'91CC0288',454.00000000,'2024-11-02 08:44:50.000'),
+(9106000500010286,'1963915047889534979','SO241020241102001',3,'91CC0319',340.00000000,'2024-11-02 08:45:03.000'),
+(9106000500010287,'1963915047889534980','SO241020241102001',4,'91FC0339',900.00000000,'2024-11-02 08:45:17.000'),
+(9106000500010288,'1963915047889534981','SO241020241102001',5,'91DC0284',813.00000000,'2024-11-02 08:45:28.000'),
+(9106000500010289,'1963915047889534982','SO241020241102001',6,'91DC0218',180.00000000,'2024-11-02 08:45:41.000'),
+(9106000500010290,'1963915047889534983','SO241020241102001',7,'91DC0219',92.00000000,'2024-11-02 08:45:54.000'),
+(9106000500010291,'1963915047889534984','SO241020241102001',8,'91CC0234',200.00000000,'2024-11-02 08:46:06.000'),
+(9106000500010292,'1963915047889534985','SO241020241102001',9,'AB3B81',218.00000000,'2024-11-02 08:46:33.000'),
+(9106000500010293,'1963971671127752705','SO241020241102004',1,'A2B4199',1596.00000000,'2024-11-02 12:32:48.000'),
+(9106000500010294,'1963971671127752706','SO241020241102004',2,'1A03G96',489.00000000,'2024-11-02 12:33:02.000'),
+(9106000500010295,'1963971671127752707','SO241020241102004',3,'AB37A2',2000.00000000,'2024-11-02 12:33:20.000'),
+(9106000500010296,'1963971671127752708','SO241020241102004',4,'AB37A3',5000.00000000,'2024-11-02 12:33:30.000'),
+(9106000500010297,'1963971671127752709','SO241020241102004',5,'A2C7116',35000.00000000,'2024-11-02 12:33:45.000'),
+(9106000500010298,'1963971671127752710','SO241020241102004',6,'A2C7117',15000.00000000,'2024-11-02 12:33:58.000'),
+(9106000500010299,'1963971671131947008','SO241020241102004',7,'1A0387B',130.00000000,'2024-11-02 12:34:15.000'),
+(9106000500010300,'1963971671131947009','SO241020241102004',8,'91CC0177',300.00000000,'2024-11-02 12:34:28.000'),
+(9106000500010301,'1963971671131947010','SO241020241102004',9,'91CC0178',525.00000000,'2024-11-02 12:34:42.000'),
+(9106000500010302,'1963971671131947011','SO241020241102004',10,'91CC0179',1200.00000000,'2024-11-02 12:34:55.000'),
+(9106000500010303,'1963971671131947012','SO241020241102004',11,'91CC0228',2367.00000000,'2024-11-02 12:35:09.000'),
+(9106000500010304,'1964653664643579905','SO241020241104001',1,'91CC0229',900.00000000,'2024-11-04 09:41:34.000'),
+(9106000500010305,'1964653664643579906','SO241020241104001',2,'AB3A76',1815.00000000,'2024-11-04 09:41:49.000'),
+(9106000500010306,'1964653664643579907','SO241020241104001',3,'A2B8414',300.00000000,'2024-11-04 09:41:59.000'),
+(9106000500010307,'1964653664643579908','SO241020241104001',4,'91DC0284',263.00000000,'2024-11-04 09:43:50.000'),
+(9106000500010308,'1964653664643579909','SO241020241104001',5,'91F0D061',121.00000000,'2024-11-04 09:44:13.000'),
+(9106000500010309,'1964653664643579910','SO241020241104001',6,'91DC0219',2030.00000000,'2024-11-04 09:44:50.000'),
+(9106000500010310,'1964653664643579911','SO241020241104001',7,'91DC0218',318.00000000,'2024-11-04 09:45:09.000'),
+(9106000500010311,'1964653664643579912','SO241020241104001',8,'91CC0231',200.00000000,'2024-11-04 09:45:30.000'),
+(9106000500010312,'1964653664643579913','SO241020241104001',9,'91CC0233',800.00000000,'2024-11-04 09:45:42.000'),
+(9106000500010313,'1981045424231809025','SO241020241219001',1,'91DC0218',400.00000000,'2024-12-19 15:13:21.000'),
+(9106000500010314,'1981045424231809026','SO241020241219001',2,'91DC0219',1312.00000000,'2024-12-19 15:13:31.000'),
+(9106000500010315,'1981045424231809027','SO241020241219001',3,'1A004C4',436000.00000000,'2024-12-19 15:14:15.000'),
+(9106000500010316,'1981045424231809028','SO241020241219001',4,'ABC419',3200.00000000,'2024-12-19 15:14:29.000'),
+(9106000500010317,'1981045424231809029','SO241020241219001',5,'ABC431',1600.00000000,'2024-12-19 15:14:42.000'),
+(9106000500010318,'1981045424231809030','SO241020241219001',6,'1A0C432',1400.00000000,'2024-12-19 15:14:53.000'),
+(9106000500010319,'1981045424231809031','SO241020241219001',7,'1A0044F',1753.00000000,'2024-12-19 15:15:05.000'),
+(9106000500010320,'1981045424231809032','SO241020241219001',8,'1A03D23',743.00000000,'2024-12-19 15:15:19.000'),
+(9106000500010321,'1981045424231809033','SO241020241219001',9,'A2B4199',1746.00000000,'2024-12-19 15:15:32.000'),
+(9106000500010322,'1981045424231809034','SO241020241219001',10,'1A03G96',1960.00000000,'2024-12-19 15:15:46.000'),
+(9106000500010323,'1981045424231809035','SO241020241219001',11,'A2B8184',100.00000000,'2024-12-19 15:15:59.000'),
+(9106000500010324,'1981045424231809036','SO241020241219001',12,'A2B8361',400.00000000,'2024-12-19 15:16:10.000'),
+(9106000500010325,'1981045424231809037','SO241020241219001',13,'91CC0188',1700.00000000,'2024-12-19 15:16:23.000'),
+(9106000500010326,'1981045424231809038','SO241020241219001',14,'91CC0228',2315.00000000,'2024-12-19 15:16:34.000'),
+(9106000500010327,'1981045424231809039','SO241020241219001',15,'91CC0232',800.00000000,'2024-12-19 15:16:46.000'),
+(9106000500010328,'1981045424231809040','SO241020241219001',16,'91CC0233',400.00000000,'2024-12-19 15:16:57.000'),
+(9106000500010329,'1981045424231809041','SO241020241219001',17,'91CC0234',100.00000000,'2024-12-19 15:17:08.000'),
+(9106000500010330,'1981045424231809042','SO241020241219001',18,'91CC0283',1890.00000000,'2024-12-19 15:17:24.000'),
+(9106000500010331,'1981045424231809043','SO241020241219001',19,'91CC0319',3500.00000000,'2024-12-19 15:17:36.000'),
+(9106000500010332,'1990491416446369793','SO241020250114003',1,'1A03G94',1686.00000000,'2025-01-14 16:53:10.000'),
+(9106000500010333,'1990491416446369794','SO241020250114003',2,'AB37A3',2000.00000000,'2025-01-14 16:53:26.000'),
+(9106000500010334,'1990491416446369795','SO241020250114003',3,'A2B8361',400.00000000,'2025-01-14 16:53:37.000'),
+(9106000500010335,'1990491416446369796','SO241020250114003',4,'1AB9275',1017.00000000,'2025-01-14 16:53:48.000'),
+(9106000500010336,'1990491416446369797','SO241020250114003',5,'A21C092',2063.00000000,'2025-01-14 16:53:59.000'),
+(9106000500010337,'1990491416446369798','SO241020250114003',6,'A21C096',1000.00000000,'2025-01-14 16:54:12.000'),
+(9106000500010338,'1990491416446369799','SO241020250114003',7,'91C0D051',299.00000000,'2025-01-14 16:54:35.000'),
+(9106000500010339,'1990491416446369800','SO241020250114003',8,'91C0D053',300.00000000,'2025-01-14 16:54:50.000'),
+(9106000500010340,'1990491416446369801','SO241020250114003',9,'91C0D074',400.00000000,'2025-01-14 16:55:01.000');
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s2_uat_morder;
+CREATE TEMPORARY TABLE tmp_s2_uat_morder (
+    target_mo_id BIGINT NOT NULL PRIMARY KEY,
+    target_me_id BIGINT NOT NULL,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    morder_no VARCHAR(128) NOT NULL,
+    product_code VARCHAR(128) NULL,
+    need_number DECIMAL(23,10) NULL
+);
+INSERT INTO tmp_s2_uat_morder VALUES
+(9106000500020002,9106000500040002,'604438178041925','MPO482024102400001','M500029670','94000292',4500.0000000000),
+(9106000500020003,9106000500040003,'604438178041926','MPO482024102400001','M500029671','1004023',3500.0000000000),
+(9106000500020004,9106000500040004,'604438178046021','MPO482024102400001','M500029672','1000329',400000.0000000000),
+(9106000500020005,9106000500040005,'604438178046022','MPO482024102400001','M500029673','1000655',100000.0000000000),
+(9106000500020006,9106000500040006,'604438178046023','MPO482024102400001','M500029674','1007114',250000.0000000000),
+(9106000500020007,9106000500040007,'604438178046024','MPO482024102400001','M500029675','1007115',600000.0000000000),
+(9106000500020008,9106000500040008,'604438178050117','MPO482024102400001','M500029676','1004199',6000.0000000000),
+(9106000500020009,9106000500040009,'604438178050118','MPO482024102400001','M500029677','1000588',10000.0000000000),
+(9106000500020010,9106000500040010,'604438178050119','MPO482024102400001','M500029678','1007094',2500.0000000000),
+(9106000500020011,9106000500040011,'604438178050120','MPO482024102400001','M500029680','32400015',1470.0000000000),
+(9106000500020012,9106000500040012,'604438178054213','MPO482024102400001','M500029682','94000218',800.0000000000),
+(9106000500020013,9106000500040013,'618270140751941','MPO482024120200001','M500053217','93000229',60.0000000000),
+(9106000500020014,9106000500040014,'618290062549061','MPO482024120200002','M500053390','94000218',2000.0000000000),
+(9106000500020015,9106000500040015,'619057595396165','MPO482024120400002','M500055223','93000237',200.0000000000),
+(9106000500020016,9106000500040016,'630994145116229','MPO482025010700001','M500061078','1007114',250000.0000000000),
+(9106000500020017,9106000500040017,'631069575503941','MPO482025010700002','M500061979','1000329',100000.0000000000),
+(9106000500020018,9106000500040018,'631769478479941','MPO482025010900001','M500067184','93000312',500.0000000000),
+(9106000500020019,9106000500040019,'631769478479942','MPO482025010900001','M500067185','1004023',600.0000000000),
+(9106000500020020,9106000500040020,'631769478484037','MPO482025010900001','M500067186','93000231',100.0000000000),
+(9106000500020021,9106000500040021,'631769478484038','MPO482025010900001','M500067187','93000286',800.0000000000),
+(9106000500020022,9106000500040022,'632121332793413','MPO482025011000001','M500068611','93000058',400.0000000000),
+(9106000500020023,9106000500040023,'632124508205125','MPO482025011000002','M500068948','1008361',1000.0000000000),
+(9106000500020024,9106000500040024,'632125640785989','MPO482025011000003','M500069117','1008184',700.0000000000),
+(9106000500020025,9106000500040025,'633173731577925','MPO482025011300002','M500070459','1004199',4000.0000000000),
+(9106000500020026,9106000500040026,'633178120278085','MPO482025011300003','M500070619','1004023',5000.0000000000),
+(9106000500020027,9106000500040027,'633197803688005','MPO482025011300005','M500070942','1000431',10000.0000000000),
+(9106000500020028,9106000500040028,'633197803688006','MPO482025011300005','M500070943','1000432',10000.0000000000),
+(9106000500020029,9106000500040029,'633206945230917','MPO482025011300006','M500070944','1000419',35000.0000000000),
+(9106000500020030,9106000500040030,'633515239526469','MPO482025011400001','M500072258','1000293',650000.0000000000),
+(9106000500020031,9106000500040031,'633515239526470','MPO482025011400001','M500072259','1000329',200000.0000000000),
+(9106000500020032,9106000500040032,'633520970641477','MPO482025011400002','M500072882','94000215',1500.0000000000),
+(9106000500020033,9106000500040033,'646977501577285','MPO482025022100001','M500085317','93000179',5000.0000000000),
+(9106000500020034,9106000500040034,'646977501577286','MPO482025022100001','M500085321','35100015',1.0000000000),
+(9106000500020035,9106000500040035,'646977501581381','MPO482025022100001','M500085326','35100016',1.0000000000),
+(9106000500020036,9106000500040036,'646977501581382','MPO482025022100001','M500085328','93000187',5000.0000000000),
+(9106000500020037,9106000500040037,'646977501581383','MPO482025022100001','M500085329','93000233',1500.0000000000),
+(9106000500020038,9106000500040038,'646977501581384','MPO482025022100001','M500085330','94000218',3000.0000000000),
+(9106000500020039,9106000500040039,'646977501581385','MPO482025022100001','M500085331','1010096',10000.0000000000),
+(9106000500020040,9106000500040040,'659719952244805','MPO482025032900001','M500089559','93000177',5000.0000000000),
+(9106000500020041,9106000500040041,'659719952244806','MPO482025032900001','M500089562','32100034',11000.0000000000),
+(9106000500020042,9106000500040042,'659719952248901','MPO482025032900001','M500089566','35100015',1.0000000000),
+(9106000500020043,9106000500040043,'659719952248902','MPO482025032900001','M500089568','94000217',2000.0000000000),
+(9106000500020044,9106000500040044,'659719952248903','MPO482025032900001','M500089569','94000219',9000.0000000000),
+(9106000500020045,9106000500040045,'659719952248904','MPO482025032900001','M500089570','93000240',2000.0000000000),
+(9106000500020046,9106000500040046,'659719952252997','MPO482025032900001','M500089573','1007111',200000.0000000000),
+(9106000500020047,9106000500040047,'665010090852421','MPO482025041300001','M500090472','35100010',1.0000000000),
+(9106000500020048,9106000500040048,'665010090852422','MPO482025041300001','M500090473','35100014',1.0000000000),
+(9106000500020049,9106000500040049,'665010090852423','MPO482025041300001','M500090474','35100033',1.0000000000),
+(9106000500020050,9106000500040050,'665010090856517','MPO482025041300001','M500090475','35100034',1.0000000000),
+(9106000500020051,9106000500040051,'670272721616965','MPO482025042800001','M500093527','32100031',7000.0000000000),
+(9106000500020052,9106000500040052,'677416091480133','MPO482025051800001','M500101110','35100015',1.0000000000),
+(9106000500020053,9106000500040053,'677416091480134','MPO482025051800001','M500101111','35100015',1.0000000000),
+(9106000500020054,9106000500040054,'677416091480135','MPO482025051800001','M500101112','35100015',1.0000000000),
+(9106000500020055,9106000500040055,'677416091480136','MPO482025051800001','M500101113','35100015',1.0000000000),
+(9106000500020056,9106000500040056,'677416091480137','MPO482025051800001','M500101114','35100015',1.0000000000),
+(9106000500020057,9106000500040057,'677416091484229','MPO482025051800001','M500101115','35100015',1.0000000000),
+(9106000500020058,9106000500040058,'677416091484230','MPO482025051800001','M500101116','35100015',1.0000000000),
+(9106000500020059,9106000500040059,'677416091484231','MPO482025051800001','M500101117','35100015',1.0000000000),
+(9106000500020060,9106000500040060,'677416091484232','MPO482025051800001','M500101118','35100015',1.0000000000),
+(9106000500020061,9106000500040061,'677416091484233','MPO482025051800001','M500101119','35100015',1.0000000000),
+(9106000500020062,9106000500040062,'689366516133957','MPO482025062100002','M500108428','35100034',1.0000000000),
+(9106000500020063,9106000500040063,'689366516133958','MPO482025062100002','M500108429','35100034',1.0000000000),
+(9106000500020064,9106000500040064,'689366516133959','MPO482025062100002','M500108430','35100034',1.0000000000),
+(9106000500020065,9106000500040065,'689366516138053','MPO482025062100002','M500108431','35100034',1.0000000000),
+(9106000500020066,9106000500040066,'689366516138054','MPO482025062100002','M500108432','35100034',1.0000000000),
+(9106000500020067,9106000500040067,'689366516138055','MPO482025062100002','M500108433','35100016',1.0000000000),
+(9106000500020068,9106000500040068,'689366516138056','MPO482025062100002','M500108434','35100016',1.0000000000),
+(9106000500020069,9106000500040069,'689366516142149','MPO482025062100002','M500108435','35100016',1.0000000000),
+(9106000500020070,9106000500040070,'689366516142150','MPO482025062100002','M500108436','35100016',1.0000000000),
+(9106000500020071,9106000500040071,'689366516142151','MPO482025062100002','M500108437','35100016',1.0000000000),
+(9106000500020072,9106000500040072,'689366516142152','MPO482025062100002','M500108438','35100016',1.0000000000),
+(9106000500020073,9106000500040073,'689366516142153','MPO482025062100002','M500108439','35100016',1.0000000000),
+(9106000500020074,9106000500040074,'689369829818437','MPO482025062100003','M500108487','35100016',1.0000000000),
+(9106000500020075,9106000500040075,'689369829818438','MPO482025062100003','M500108488','35100016',1.0000000000),
+(9106000500020076,9106000500040076,'689369829818439','MPO482025062100003','M500108489','35100016',1.0000000000),
+(9106000500020077,9106000500040077,'689369829818440','MPO482025062100003','M500108490','35100010',1.0000000000),
+(9106000500020078,9106000500040078,'689369829822533','MPO482025062100003','M500108491','35100010',1.0000000000),
+(9106000500020079,9106000500040079,'689369829822534','MPO482025062100003','M500108492','35100010',1.0000000000),
+(9106000500020080,9106000500040080,'689369829822535','MPO482025062100003','M500108493','35100010',1.0000000000),
+(9106000500020081,9106000500040081,'689369829822536','MPO482025062100003','M500108494','35100010',1.0000000000),
+(9106000500020082,9106000500040082,'689369829826629','MPO482025062100003','M500108495','35100010',1.0000000000),
+(9106000500020083,9106000500040083,'689369829826630','MPO482025062100003','M500108496','35100010',1.0000000000),
+(9106000500020084,9106000500040084,'689369829826631','MPO482025062100003','M500108497','35100010',1.0000000000),
+(9106000500020085,9106000500040085,'689369829826632','MPO482025062100003','M500108498','35100010',1.0000000000),
+(9106000500020086,9106000500040086,'689369829826633','MPO482025062100003','M500108499','35100010',1.0000000000),
+(9106000500020087,9106000500040087,'691329582436421','MPO482025062600003','M500109125','93000178',3000.0000000000),
+(9106000500020088,9106000500040088,'691329582436422','MPO482025062600003','M500109128','32400038',3100.0000000000),
+(9106000500020089,9106000500040089,'691329582436423','MPO482025062600003','M500109132','32400015',5100.0000000000),
+(9106000500020090,9106000500040090,'691329582440517','MPO482025062600003','M500109134','1008361',4000.0000000000),
+(9106000500020091,9106000500040091,'708842858610757','MPO482025081500001','M500123310','1000273',200.0000000000),
+(9106000500020092,9106000500040092,'708842858610758','MPO482025081500001','M500123311','1000275',272.0000000000),
+(9106000500020093,9106000500040093,'708842858610759','MPO482025081500001','M500123312','1000304',360000.0000000000),
+(9106000500020094,9106000500040094,'708842858610760','MPO482025081500001','M500123313','1000419',1000.0000000000),
+(9106000500020095,9106000500040095,'708842858610761','MPO482025081500001','M500123314','1000431',2000.0000000000),
+(9106000500020096,9106000500040096,'708842858610762','MPO482025081500001','M500123315','1000432',-2000.0000000000),
+(9106000500020097,9106000500040097,'708842858610763','MPO482025081500001','M500123316','1000588',-29000.0000000000),
+(9106000500020098,9106000500040098,'708842858614853','MPO482025081500001','M500123317','1000595',670000.0000000000),
+(9106000500020099,9106000500040099,'708842858614854','MPO482025081500001','M500123318','1002104',-113.0000000000),
+(9106000500020100,9106000500040100,'708853132763205','MPO482025081500002','M500123386','1010092',550.0000000000),
+(9106000500020101,9106000500040101,'708853132763206','MPO482025081500002','M500123387','1010093',1.0000000000),
+(9106000500020102,9106000500040102,'708853132763207','MPO482025081500002','M500123388','92000033',38.0000000000),
+(9106000500020103,9106000500040103,'708853132767301','MPO482025081500002','M500123389','93000058',558.0000000000),
+(9106000500020104,9106000500040104,'708853132767302','MPO482025081500002','M500123390','93000074',2522.0000000000),
+(9106000500020105,9106000500040105,'708853132767303','MPO482025081500002','M500123392','35100032',1.0000000000),
+(9106000500020106,9106000500040106,'708853132771397','MPO482025081500002','M500123393','93000110',185.0000000000),
+(9106000500020107,9106000500040107,'708853132771398','MPO482025081500002','M500123395','93000123',2.0000000000),
+(9106000500020108,9106000500040108,'708853132771399','MPO482025081500002','M500123396','93000229',862.0000000000),
+(9106000500020109,9106000500040109,'708853132771400','MPO482025081500002','M500123401','32300026',200.0000000000),
+(9106000500020110,9106000500040110,'708853132771401','MPO482025081500002','M500123404','32400015',-3015.0000000000),
+(9106000500020111,9106000500040111,'708853132775493','MPO482025081500002','M500123405','93000312',300.0000000000),
+(9106000500020112,9106000500040112,'708853132775494','MPO482025081500002','M500123407','93000404',500.0000000000),
+(9106000500020113,9106000500040113,'708853132775495','MPO482025081500002','M500123408','93000412',800.0000000000),
+(9106000500020114,9106000500040114,'708853132775496','MPO482025081500002','M500123409','93000502',400.0000000000),
+(9106000500020115,9106000500040115,'708853132775497','MPO482025081500002','M500123411','93000503',1050.0000000000),
+(9106000500020116,9106000500040116,'708853132779589','MPO482025081500002','M500123413','93000506',1.0000000000),
+(9106000500020117,9106000500040117,'708853132779590','MPO482025081500002','M500123414','93000507',1000.0000000000),
+(9106000500020118,9106000500040118,'708853132779591','MPO482025081500002','M500123415','93000509',350.0000000000),
+(9106000500020119,9106000500040119,'708853132779592','MPO482025081500002','M500123416','93000510',1100.0000000000),
+(9106000500020120,9106000500040120,'708853132779593','MPO482025081500002','M500123417','93000518',1250.0000000000),
+(9106000500020121,9106000500040121,'708853132783685','MPO482025081500002','M500123418','93000521',3000.0000000000),
+(9106000500020122,9106000500040122,'708853132783686','MPO482025081500002','M500123419','93000524',1500.0000000000),
+(9106000500020123,9106000500040123,'708853132783687','MPO482025081500002','M500123420','93000525',3000.0000000000),
+(9106000500020124,9106000500040124,'708853132783688','MPO482025081500002','M500123421','96000339',6000.0000000000),
+(9106000500020125,9106000500040125,'708853132783689','MPO482025081500002','M500123423','32100042',-20000.0000000000),
+(9106000500020126,9106000500040126,'708853132783690','MPO482025081500002','M500123425','32400015',-8000.0000000000),
+(9106000500020127,9106000500040127,'708853132787781','MPO482025081500002','M500123426','35100032',1.0000000000),
+(9106000500020128,9106000500040128,'708853132787782','MPO482025081500002','M500123427','1000452',1000.0000000000),
+(9106000500020129,9106000500040129,'708853132791880','MPO482025081500002','M500123430','93000517',100.0000000000),
+(9106000500020130,9106000500040130,'708853132791881','MPO482025081500002','M500123431','35100034',1.0000000000),
+(9106000500020131,9106000500040131,'708853132791882','MPO482025081500002','M500123432','35100034',-1.0000000000),
+(9106000500020132,9106000500040132,'708853132791883','MPO482025081500002','M500123433','35100034',1.0000000000),
+(9106000500020133,9106000500040133,'708853132791884','MPO482025081500002','M500123434','35100034',1.0000000000),
+(9106000500020134,9106000500040134,'708853132791885','MPO482025081500002','M500123435','35100034',1.0000000000),
+(9106000500020135,9106000500040135,'708853132795973','MPO482025081500002','M500123436','35100033',1.0000000000),
+(9106000500020136,9106000500040136,'708853132795974','MPO482025081500002','M500123437','35100033',1.0000000000),
+(9106000500020137,9106000500040137,'708853132795975','MPO482025081500002','M500123438','35100033',1.0000000000),
+(9106000500020138,9106000500040138,'708853132795976','MPO482025081500002','M500123439','35100033',1.0000000000),
+(9106000500020139,9106000500040139,'708853132795977','MPO482025081500002','M500123440','35100033',1.0000000000),
+(9106000500020140,9106000500040140,'708853132795978','MPO482025081500002','M500123441','35100033',-1.0000000000),
+(9106000500020141,9106000500040141,'708853132795979','MPO482025081500002','M500123442','35100033',1.0000000000),
+(9106000500020142,9106000500040142,'708853132795980','MPO482025081500002','M500123443','35100033',1.0000000000),
+(9106000500020143,9106000500040143,'708853132795981','MPO482025081500002','M500123444','35100015',1.0000000000),
+(9106000500020144,9106000500040144,'708853132795982','MPO482025081500002','M500123445','35100015',1.0000000000),
+(9106000500020145,9106000500040145,'708853132795983','MPO482025081500002','M500123446','35100015',1.0000000000),
+(9106000500020146,9106000500040146,'708853132800069','MPO482025081500002','M500123447','35100015',1.0000000000),
+(9106000500020147,9106000500040147,'708853132800070','MPO482025081500002','M500123448','35100015',1.0000000000),
+(9106000500020148,9106000500040148,'708853132800071','MPO482025081500002','M500123449','35100015',1.0000000000),
+(9106000500020149,9106000500040149,'708853132800072','MPO482025081500002','M500123450','35100015',1.0000000000),
+(9106000500020150,9106000500040150,'708853132800073','MPO482025081500002','M500123451','35100015',1.0000000000),
+(9106000500020151,9106000500040151,'708853132800074','MPO482025081500002','M500123452','35100015',1.0000000000),
+(9106000500020152,9106000500040152,'708853132800075','MPO482025081500002','M500123453','35100015',1.0000000000),
+(9106000500020153,9106000500040153,'708853132800076','MPO482025081500002','M500123454','35100015',1.0000000000),
+(9106000500020154,9106000500040154,'708853132800077','MPO482025081500002','M500123455','35100015',1.0000000000),
+(9106000500020155,9106000500040155,'708853132804165','MPO482025081500002','M500123456','35100015',1.0000000000),
+(9106000500020156,9106000500040156,'713850861281349','MPO482025082900002','M500124855','93000270',5000.0000000000),
+(9106000500020157,9106000500040157,'713850861281350','MPO482025082900002','M500124858','93000311',510.0000000000),
+(9106000500020158,9106000500040158,'713850861281351','MPO482025082900002','M500124861','93000312',500.0000000000),
+(9106000500020159,9106000500040159,'713850861285445','MPO482025082900002','M500124864','93000233',600.0000000000),
+(9106000500020160,9106000500040160,'713850861285446','MPO482025082900002','M500124867','93000232',1500.0000000000),
+(9106000500020161,9106000500040161,'716009096228933','MPO482025090400005','M500125396','32300021',5000.0000000000),
+(9106000500020162,9106000500040162,'716009096228934','MPO482025090400005','M500125401','32300021',5000.0000000000),
+(9106000500020163,9106000500040163,'720949568118853','MPO482025091800003','M500130061','32300065',1900.0000000000),
+(9106000500020164,9106000500040164,'720949568118854','MPO482025091800003','M500130063','32300021',100.0000000000),
+(9106000500020165,9106000500040165,'720949568118855','MPO482025091800003','M500130067','32300021',600.0000000000),
+(9106000500020166,9106000500040166,'720949568122949','MPO482025091800003','M500130068','93000313',100.0000000000),
+(9106000500020167,9106000500040167,'720949568122950','MPO482025091800003','M500130070','93000229',700.0000000000),
+(9106000500020168,9106000500040168,'721256689414213','MPO482025091900001','M500130445','93000182',10000.0000000000),
+(9106000500020169,9106000500040169,'721256689414214','MPO482025091900001','M500130446','32300009',10000.0000000000),
+(9106000500020170,9106000500040170,'721256689414215','MPO482025091900001','M500130447','32300012',10000.0000000000),
+(9106000500020171,9106000500040171,'721256689414216','MPO482025091900001','M500130448','32300026',-2980.0000000000),
+(9106000500020172,9106000500040172,'721256689414217','MPO482025091900001','M500130449','32300027',-2968.0000000000),
+(9106000500020173,9106000500040173,'721256689418309','MPO482025091900001','M500130450','32300028',3000.0000000000),
+(9106000500020174,9106000500040174,'721256689418310','MPO482025091900001','M500130451','32300035',10000.0000000000),
+(9106000500020175,9106000500040175,'721256689418311','MPO482025091900001','M500130452','32300046',3000.0000000000),
+(9106000500020176,9106000500040176,'721256689422405','MPO482025091900001','M500130453','32300047',2108.0000000000),
+(9106000500020177,9106000500040177,'721256689422406','MPO482025091900001','M500130454','32300048',-10000.0000000000),
+(9106000500020178,9106000500040178,'721256689422407','MPO482025091900001','M500130455','35100015',1.0000000000),
+(9106000500020179,9106000500040179,'721256689422408','MPO482025091900001','M500130456','35100015',1.0000000000),
+(9106000500020180,9106000500040180,'721256689426501','MPO482025091900001','M500130457','35100015',1.0000000000),
+(9106000500020181,9106000500040181,'721256689426502','MPO482025091900001','M500130458','35100015',1.0000000000),
+(9106000500020182,9106000500040182,'721256689426503','MPO482025091900001','M500130459','35100016',1.0000000000),
+(9106000500020183,9106000500040183,'721256689426504','MPO482025091900001','M500130460','35100016',1.0000000000),
+(9106000500020184,9106000500040184,'721256689426505','MPO482025091900001','M500130461','35100016',1.0000000000),
+(9106000500020185,9106000500040185,'721256689430597','MPO482025091900001','M500130462','35100016',1.0000000000),
+(9106000500020186,9106000500040186,'721256689430598','MPO482025091900001','M500130463','35100016',1.0000000000),
+(9106000500020187,9106000500040187,'721256689430599','MPO482025091900001','M500130464','35100016',1.0000000000),
+(9106000500020188,9106000500040188,'721256689430600','MPO482025091900001','M500130465','35100015',1.0000000000),
+(9106000500020189,9106000500040189,'721256689434693','MPO482025091900001','M500130466','35100015',1.0000000000),
+(9106000500020190,9106000500040190,'721256689434694','MPO482025091900001','M500130467','35100015',1.0000000000),
+(9106000500020191,9106000500040191,'721256689434695','MPO482025091900001','M500130468','35100015',1.0000000000),
+(9106000500020192,9106000500040192,'721256689434696','MPO482025091900001','M500130469','35100015',1.0000000000),
+(9106000500020193,9106000500040193,'721256689438789','MPO482025091900001','M500130470','35100015',1.0000000000),
+(9106000500020194,9106000500040194,'721256689438790','MPO482025091900001','M500130471','35100015',1.0000000000),
+(9106000500020195,9106000500040195,'722351552172101','MPO482025092200002','M500130840','93000283',20000.0000000000),
+(9106000500020196,9106000500040196,'765148661813317','MPO482026012100001','M500103888','3221C0031',1000.0000000000),
+(9106000500020197,9106000500040197,'765148661813318','MPO482026012100001','M500103890','3521C0018',2.0000000000),
+(9106000500020198,9106000500040198,'765148661813319','MPO482026012100001','M500103891','1A0047E',1000.0000000000),
+(9106000500020199,9106000500040199,'769809191923781','MPO482026020300001','M500105946','3221C0031',100.0000000000),
+(9106000500020200,9106000500040200,'1958480382326104095','SO241020240923001','UAT-MO-0034','91CC0232',400.00000000),
+(9106000500020201,9106000500040201,'1958480382326104272','SO241020241014001','M500028977','1007114',120000.0000000000),
+(9106000500020202,9106000500040202,'1958480382326104273','SO241020241014001','M500028978','1007115',30000.0000000000),
+(9106000500020203,9106000500040203,'1958480382326104295','SO241020241015003','M500028992','1000431',5000.0000000000),
+(9106000500020204,9106000500040204,'1958480382326104296','SO241020241015003','M500028993','1000432',5000.0000000000),
+(9106000500020205,9106000500040205,'1958902016386269188','SO241020241018001','M500029021','1000595',92000.0000000000),
+(9106000500020206,9106000500040206,'1958902016386269193','SO241020241018001','M500029024','1007096',7000.0000000000),
+(9106000500020207,9106000500040207,'1958902016386269196','SO241020241018001','M500029027','1002081',1256.0000000000),
+(9106000500020208,9106000500040208,'1958902016386269200','SO241020241018001','M500029034','93000236',140.0000000000),
+(9106000500020209,9106000500040209,'1958956122157088771','SO241020241019001','M500029040','93000228',3000.0000000000),
+(9106000500020210,9106000500040210,'1959718646913695745','SO241020241021002','UAT-MO-0039','1A039D8',350.00000000),
+(9106000500020211,9106000500040211,'1960006795304894465','SO241020241022001','M500029272','93000235',600.0000000000),
+(9106000500020212,9106000500040212,'1963915047889534981','SO241020241102001','M500033844','94000284',10000.0000000000),
+(9106000500020213,9106000500040213,'1963915047889534985','SO241020241102001','M500033846','1002081',1200.0000000000),
+(9106000500020214,9106000500040214,'1963971671131947011','SO241020241102004','M500033849','93000179',2000.0000000000),
+(9106000500020215,9106000500040215,'1964653664643579905','SO241020241104001','M500033851','93000229',6000.0000000000),
+(9106000500020216,9106000500040216,'1964653664643579907','SO241020241104001','M500033853','1008414',176.0000000000),
+(9106000500020217,9106000500040217,'1964653664643579908','SO241020241104001','M500033854','94000284',10000.0000000000),
+(9106000500020218,9106000500040218,'1964653664643579910','SO241020241104001','M500033856','94000219',11000.0000000000),
+(9106000500020219,9106000500040219,'1964653664643579913','SO241020241104001','M500033857','93000233',1000.0000000000),
+(9106000500020220,9106000500040220,'1981045424231809025','SO241020241219001','UAT-MO-0044','91DC0218',400.00000000),
+(9106000500020221,9106000500040221,'1990491416446369793','SO241020250114003','UAT-MO-0045','1A03G94',1686.00000000);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_pr;
+CREATE TEMPORARY TABLE tmp_s3_uat_pr (
+    voucher BIGINT NOT NULL PRIMARY KEY,
+    pr_billno VARCHAR(64) NOT NULL,
+    morder_no VARCHAR(128) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    icitem_code VARCHAR(64) NULL,
+    pr_rqty DECIMAL(18,4) NULL,
+    mo_id BIGINT NOT NULL
+);
+INSERT INTO tmp_s3_uat_pr VALUES
+(9106000500050002,'PR-UAT-FULL-20260605-001','M500029670','MPO482024102400001','94000292',4500.0000000000,9106000500020002),
+(9106000500050003,'PR-UAT-FULL-20260605-002','M500029671','MPO482024102400001','1004023',3500.0000000000,9106000500020003),
+(9106000500050004,'PR-UAT-FULL-20260605-003','M500029672','MPO482024102400001','1000329',400000.0000000000,9106000500020004),
+(9106000500050005,'PR-UAT-FULL-20260605-004','M500029673','MPO482024102400001','1000655',100000.0000000000,9106000500020005),
+(9106000500050006,'PR-UAT-FULL-20260605-005','M500029674','MPO482024102400001','1007114',250000.0000000000,9106000500020006),
+(9106000500050007,'PR-UAT-FULL-20260605-006','M500029675','MPO482024102400001','1007115',600000.0000000000,9106000500020007),
+(9106000500050008,'PR-UAT-FULL-20260605-007','M500029676','MPO482024102400001','1004199',6000.0000000000,9106000500020008),
+(9106000500050009,'PR-UAT-FULL-20260605-008','M500029677','MPO482024102400001','1000588',10000.0000000000,9106000500020009),
+(9106000500050010,'PR-UAT-FULL-20260605-009','M500029678','MPO482024102400001','1007094',2500.0000000000,9106000500020010),
+(9106000500050011,'PR-UAT-FULL-20260605-010','M500029680','MPO482024102400001','32400015',1470.0000000000,9106000500020011),
+(9106000500050012,'PR-UAT-FULL-20260605-011','M500029682','MPO482024102400001','94000218',800.0000000000,9106000500020012),
+(9106000500050013,'PR-UAT-FULL-20260605-001','M500053217','MPO482024120200001','93000229',60.0000000000,9106000500020013),
+(9106000500050014,'PR-UAT-FULL-20260605-001','M500053390','MPO482024120200002','94000218',2000.0000000000,9106000500020014),
+(9106000500050015,'PR-UAT-FULL-20260605-001','M500055223','MPO482024120400002','93000237',200.0000000000,9106000500020015),
+(9106000500050016,'PR-UAT-FULL-20260605-001','M500061078','MPO482025010700001','1007114',250000.0000000000,9106000500020016),
+(9106000500050017,'PR-UAT-FULL-20260605-001','M500061979','MPO482025010700002','1000329',100000.0000000000,9106000500020017),
+(9106000500050018,'PR-UAT-FULL-20260605-001','M500067184','MPO482025010900001','93000312',500.0000000000,9106000500020018),
+(9106000500050019,'PR-UAT-FULL-20260605-002','M500067185','MPO482025010900001','1004023',600.0000000000,9106000500020019),
+(9106000500050020,'PR-UAT-FULL-20260605-003','M500067186','MPO482025010900001','93000231',100.0000000000,9106000500020020),
+(9106000500050021,'PR-UAT-FULL-20260605-004','M500067187','MPO482025010900001','93000286',800.0000000000,9106000500020021),
+(9106000500050022,'PR-UAT-FULL-20260605-001','M500068611','MPO482025011000001','93000058',400.0000000000,9106000500020022),
+(9106000500050023,'PR-UAT-FULL-20260605-001','M500068948','MPO482025011000002','1008361',1000.0000000000,9106000500020023),
+(9106000500050024,'PR-UAT-FULL-20260605-001','M500069117','MPO482025011000003','1008184',700.0000000000,9106000500020024),
+(9106000500050025,'PR-UAT-FULL-20260605-001','M500070459','MPO482025011300002','1004199',4000.0000000000,9106000500020025),
+(9106000500050026,'PR-UAT-FULL-20260605-001','M500070619','MPO482025011300003','1004023',5000.0000000000,9106000500020026),
+(9106000500050027,'PR-UAT-FULL-20260605-001','M500070942','MPO482025011300005','1000431',10000.0000000000,9106000500020027),
+(9106000500050028,'PR-UAT-FULL-20260605-002','M500070943','MPO482025011300005','1000432',10000.0000000000,9106000500020028),
+(9106000500050029,'PR-UAT-FULL-20260605-001','M500070944','MPO482025011300006','1000419',35000.0000000000,9106000500020029),
+(9106000500050030,'PR-UAT-FULL-20260605-001','M500072258','MPO482025011400001','1000293',650000.0000000000,9106000500020030),
+(9106000500050031,'PR-UAT-FULL-20260605-002','M500072259','MPO482025011400001','1000329',200000.0000000000,9106000500020031),
+(9106000500050032,'PR-UAT-FULL-20260605-001','M500072882','MPO482025011400002','94000215',1500.0000000000,9106000500020032),
+(9106000500050033,'PR-UAT-FULL-20260605-001','M500085317','MPO482025022100001','93000179',5000.0000000000,9106000500020033),
+(9106000500050034,'PR-UAT-FULL-20260605-002','M500085321','MPO482025022100001','35100015',1.0000000000,9106000500020034),
+(9106000500050035,'PR-UAT-FULL-20260605-003','M500085326','MPO482025022100001','35100016',1.0000000000,9106000500020035),
+(9106000500050036,'PR-UAT-FULL-20260605-004','M500085328','MPO482025022100001','93000187',5000.0000000000,9106000500020036),
+(9106000500050037,'PR-UAT-FULL-20260605-005','M500085329','MPO482025022100001','93000233',1500.0000000000,9106000500020037),
+(9106000500050038,'PR-UAT-FULL-20260605-006','M500085330','MPO482025022100001','94000218',3000.0000000000,9106000500020038),
+(9106000500050039,'PR-UAT-FULL-20260605-007','M500085331','MPO482025022100001','1010096',10000.0000000000,9106000500020039),
+(9106000500050040,'PR-UAT-FULL-20260605-001','M500089559','MPO482025032900001','93000177',5000.0000000000,9106000500020040),
+(9106000500050041,'PR-UAT-FULL-20260605-002','M500089562','MPO482025032900001','32100034',11000.0000000000,9106000500020041),
+(9106000500050042,'PR-UAT-FULL-20260605-003','M500089566','MPO482025032900001','35100015',1.0000000000,9106000500020042),
+(9106000500050043,'PR-UAT-FULL-20260605-004','M500089568','MPO482025032900001','94000217',2000.0000000000,9106000500020043),
+(9106000500050044,'PR-UAT-FULL-20260605-005','M500089569','MPO482025032900001','94000219',9000.0000000000,9106000500020044),
+(9106000500050045,'PR-UAT-FULL-20260605-006','M500089570','MPO482025032900001','93000240',2000.0000000000,9106000500020045),
+(9106000500050046,'PR-UAT-FULL-20260605-007','M500089573','MPO482025032900001','1007111',200000.0000000000,9106000500020046),
+(9106000500050047,'PR-UAT-FULL-20260605-001','M500090472','MPO482025041300001','35100010',1.0000000000,9106000500020047),
+(9106000500050048,'PR-UAT-FULL-20260605-002','M500090473','MPO482025041300001','35100014',1.0000000000,9106000500020048),
+(9106000500050049,'PR-UAT-FULL-20260605-003','M500090474','MPO482025041300001','35100033',1.0000000000,9106000500020049),
+(9106000500050050,'PR-UAT-FULL-20260605-004','M500090475','MPO482025041300001','35100034',1.0000000000,9106000500020050),
+(9106000500050051,'PR-UAT-FULL-20260605-001','M500093527','MPO482025042800001','32100031',7000.0000000000,9106000500020051),
+(9106000500050052,'PR-UAT-FULL-20260605-001','M500101110','MPO482025051800001','35100015',1.0000000000,9106000500020052),
+(9106000500050053,'PR-UAT-FULL-20260605-002','M500101111','MPO482025051800001','35100015',1.0000000000,9106000500020053),
+(9106000500050054,'PR-UAT-FULL-20260605-003','M500101112','MPO482025051800001','35100015',1.0000000000,9106000500020054),
+(9106000500050055,'PR-UAT-FULL-20260605-004','M500101113','MPO482025051800001','35100015',1.0000000000,9106000500020055),
+(9106000500050056,'PR-UAT-FULL-20260605-005','M500101114','MPO482025051800001','35100015',1.0000000000,9106000500020056),
+(9106000500050057,'PR-UAT-FULL-20260605-006','M500101115','MPO482025051800001','35100015',1.0000000000,9106000500020057),
+(9106000500050058,'PR-UAT-FULL-20260605-007','M500101116','MPO482025051800001','35100015',1.0000000000,9106000500020058),
+(9106000500050059,'PR-UAT-FULL-20260605-008','M500101117','MPO482025051800001','35100015',1.0000000000,9106000500020059),
+(9106000500050060,'PR-UAT-FULL-20260605-009','M500101118','MPO482025051800001','35100015',1.0000000000,9106000500020060),
+(9106000500050061,'PR-UAT-FULL-20260605-010','M500101119','MPO482025051800001','35100015',1.0000000000,9106000500020061),
+(9106000500050062,'PR-UAT-FULL-20260605-001','M500108428','MPO482025062100002','35100034',1.0000000000,9106000500020062),
+(9106000500050063,'PR-UAT-FULL-20260605-002','M500108429','MPO482025062100002','35100034',1.0000000000,9106000500020063),
+(9106000500050064,'PR-UAT-FULL-20260605-003','M500108430','MPO482025062100002','35100034',1.0000000000,9106000500020064),
+(9106000500050065,'PR-UAT-FULL-20260605-004','M500108431','MPO482025062100002','35100034',1.0000000000,9106000500020065),
+(9106000500050066,'PR-UAT-FULL-20260605-005','M500108432','MPO482025062100002','35100034',1.0000000000,9106000500020066),
+(9106000500050067,'PR-UAT-FULL-20260605-006','M500108433','MPO482025062100002','35100016',1.0000000000,9106000500020067),
+(9106000500050068,'PR-UAT-FULL-20260605-007','M500108434','MPO482025062100002','35100016',1.0000000000,9106000500020068),
+(9106000500050069,'PR-UAT-FULL-20260605-008','M500108435','MPO482025062100002','35100016',1.0000000000,9106000500020069),
+(9106000500050070,'PR-UAT-FULL-20260605-009','M500108436','MPO482025062100002','35100016',1.0000000000,9106000500020070),
+(9106000500050071,'PR-UAT-FULL-20260605-010','M500108437','MPO482025062100002','35100016',1.0000000000,9106000500020071),
+(9106000500050072,'PR-UAT-FULL-20260605-011','M500108438','MPO482025062100002','35100016',1.0000000000,9106000500020072),
+(9106000500050073,'PR-UAT-FULL-20260605-012','M500108439','MPO482025062100002','35100016',1.0000000000,9106000500020073),
+(9106000500050074,'PR-UAT-FULL-20260605-001','M500108487','MPO482025062100003','35100016',1.0000000000,9106000500020074),
+(9106000500050075,'PR-UAT-FULL-20260605-002','M500108488','MPO482025062100003','35100016',1.0000000000,9106000500020075),
+(9106000500050076,'PR-UAT-FULL-20260605-003','M500108489','MPO482025062100003','35100016',1.0000000000,9106000500020076),
+(9106000500050077,'PR-UAT-FULL-20260605-004','M500108490','MPO482025062100003','35100010',1.0000000000,9106000500020077),
+(9106000500050078,'PR-UAT-FULL-20260605-005','M500108491','MPO482025062100003','35100010',1.0000000000,9106000500020078),
+(9106000500050079,'PR-UAT-FULL-20260605-006','M500108492','MPO482025062100003','35100010',1.0000000000,9106000500020079),
+(9106000500050080,'PR-UAT-FULL-20260605-007','M500108493','MPO482025062100003','35100010',1.0000000000,9106000500020080),
+(9106000500050081,'PR-UAT-FULL-20260605-008','M500108494','MPO482025062100003','35100010',1.0000000000,9106000500020081),
+(9106000500050082,'PR-UAT-FULL-20260605-009','M500108495','MPO482025062100003','35100010',1.0000000000,9106000500020082),
+(9106000500050083,'PR-UAT-FULL-20260605-010','M500108496','MPO482025062100003','35100010',1.0000000000,9106000500020083),
+(9106000500050084,'PR-UAT-FULL-20260605-011','M500108497','MPO482025062100003','35100010',1.0000000000,9106000500020084),
+(9106000500050085,'PR-UAT-FULL-20260605-012','M500108498','MPO482025062100003','35100010',1.0000000000,9106000500020085),
+(9106000500050086,'PR-UAT-FULL-20260605-013','M500108499','MPO482025062100003','35100010',1.0000000000,9106000500020086),
+(9106000500050087,'PR-UAT-FULL-20260605-001','M500109125','MPO482025062600003','93000178',3000.0000000000,9106000500020087),
+(9106000500050088,'PR-UAT-FULL-20260605-002','M500109128','MPO482025062600003','32400038',3100.0000000000,9106000500020088),
+(9106000500050089,'PR-UAT-FULL-20260605-003','M500109132','MPO482025062600003','32400015',5100.0000000000,9106000500020089),
+(9106000500050090,'PR-UAT-FULL-20260605-004','M500109134','MPO482025062600003','1008361',4000.0000000000,9106000500020090),
+(9106000500050091,'PR-UAT-FULL-20260605-001','M500123310','MPO482025081500001','1000273',200.0000000000,9106000500020091),
+(9106000500050092,'PR-UAT-FULL-20260605-002','M500123311','MPO482025081500001','1000275',272.0000000000,9106000500020092),
+(9106000500050093,'PR-UAT-FULL-20260605-003','M500123312','MPO482025081500001','1000304',360000.0000000000,9106000500020093),
+(9106000500050094,'PR-UAT-FULL-20260605-004','M500123313','MPO482025081500001','1000419',1000.0000000000,9106000500020094),
+(9106000500050095,'PR-UAT-FULL-20260605-005','M500123314','MPO482025081500001','1000431',2000.0000000000,9106000500020095),
+(9106000500050096,'PR-UAT-FULL-20260605-006','M500123315','MPO482025081500001','1000432',-2000.0000000000,9106000500020096),
+(9106000500050097,'PR-UAT-FULL-20260605-007','M500123316','MPO482025081500001','1000588',-29000.0000000000,9106000500020097),
+(9106000500050098,'PR-UAT-FULL-20260605-008','M500123317','MPO482025081500001','1000595',670000.0000000000,9106000500020098),
+(9106000500050099,'PR-UAT-FULL-20260605-009','M500123318','MPO482025081500001','1002104',-113.0000000000,9106000500020099),
+(9106000500050100,'PR-UAT-FULL-20260605-001','M500123386','MPO482025081500002','1010092',550.0000000000,9106000500020100),
+(9106000500050101,'PR-UAT-FULL-20260605-002','M500123387','MPO482025081500002','1010093',1.0000000000,9106000500020101),
+(9106000500050102,'PR-UAT-FULL-20260605-003','M500123388','MPO482025081500002','92000033',38.0000000000,9106000500020102),
+(9106000500050103,'PR-UAT-FULL-20260605-004','M500123389','MPO482025081500002','93000058',558.0000000000,9106000500020103),
+(9106000500050104,'PR-UAT-FULL-20260605-005','M500123390','MPO482025081500002','93000074',2522.0000000000,9106000500020104),
+(9106000500050105,'PR-UAT-FULL-20260605-006','M500123392','MPO482025081500002','35100032',1.0000000000,9106000500020105),
+(9106000500050106,'PR-UAT-FULL-20260605-007','M500123393','MPO482025081500002','93000110',185.0000000000,9106000500020106),
+(9106000500050107,'PR-UAT-FULL-20260605-008','M500123395','MPO482025081500002','93000123',2.0000000000,9106000500020107),
+(9106000500050108,'PR-UAT-FULL-20260605-009','M500123396','MPO482025081500002','93000229',862.0000000000,9106000500020108),
+(9106000500050109,'PR-UAT-FULL-20260605-010','M500123401','MPO482025081500002','32300026',200.0000000000,9106000500020109),
+(9106000500050110,'PR-UAT-FULL-20260605-011','M500123404','MPO482025081500002','32400015',-3015.0000000000,9106000500020110),
+(9106000500050111,'PR-UAT-FULL-20260605-012','M500123405','MPO482025081500002','93000312',300.0000000000,9106000500020111),
+(9106000500050112,'PR-UAT-FULL-20260605-013','M500123407','MPO482025081500002','93000404',500.0000000000,9106000500020112),
+(9106000500050113,'PR-UAT-FULL-20260605-014','M500123408','MPO482025081500002','93000412',800.0000000000,9106000500020113),
+(9106000500050114,'PR-UAT-FULL-20260605-015','M500123409','MPO482025081500002','93000502',400.0000000000,9106000500020114),
+(9106000500050115,'PR-UAT-FULL-20260605-016','M500123411','MPO482025081500002','93000503',1050.0000000000,9106000500020115),
+(9106000500050116,'PR-UAT-FULL-20260605-017','M500123413','MPO482025081500002','93000506',1.0000000000,9106000500020116),
+(9106000500050117,'PR-UAT-FULL-20260605-018','M500123414','MPO482025081500002','93000507',1000.0000000000,9106000500020117),
+(9106000500050118,'PR-UAT-FULL-20260605-019','M500123415','MPO482025081500002','93000509',350.0000000000,9106000500020118),
+(9106000500050119,'PR-UAT-FULL-20260605-020','M500123416','MPO482025081500002','93000510',1100.0000000000,9106000500020119),
+(9106000500050120,'PR-UAT-FULL-20260605-021','M500123417','MPO482025081500002','93000518',1250.0000000000,9106000500020120),
+(9106000500050121,'PR-UAT-FULL-20260605-022','M500123418','MPO482025081500002','93000521',3000.0000000000,9106000500020121),
+(9106000500050122,'PR-UAT-FULL-20260605-023','M500123419','MPO482025081500002','93000524',1500.0000000000,9106000500020122),
+(9106000500050123,'PR-UAT-FULL-20260605-024','M500123420','MPO482025081500002','93000525',3000.0000000000,9106000500020123),
+(9106000500050124,'PR-UAT-FULL-20260605-025','M500123421','MPO482025081500002','96000339',6000.0000000000,9106000500020124),
+(9106000500050125,'PR-UAT-FULL-20260605-026','M500123423','MPO482025081500002','32100042',-20000.0000000000,9106000500020125),
+(9106000500050126,'PR-UAT-FULL-20260605-027','M500123425','MPO482025081500002','32400015',-8000.0000000000,9106000500020126),
+(9106000500050127,'PR-UAT-FULL-20260605-028','M500123426','MPO482025081500002','35100032',1.0000000000,9106000500020127),
+(9106000500050128,'PR-UAT-FULL-20260605-029','M500123427','MPO482025081500002','1000452',1000.0000000000,9106000500020128),
+(9106000500050129,'PR-UAT-FULL-20260605-030','M500123430','MPO482025081500002','93000517',100.0000000000,9106000500020129),
+(9106000500050130,'PR-UAT-FULL-20260605-031','M500123431','MPO482025081500002','35100034',1.0000000000,9106000500020130),
+(9106000500050131,'PR-UAT-FULL-20260605-032','M500123432','MPO482025081500002','35100034',-1.0000000000,9106000500020131),
+(9106000500050132,'PR-UAT-FULL-20260605-033','M500123433','MPO482025081500002','35100034',1.0000000000,9106000500020132),
+(9106000500050133,'PR-UAT-FULL-20260605-034','M500123434','MPO482025081500002','35100034',1.0000000000,9106000500020133),
+(9106000500050134,'PR-UAT-FULL-20260605-035','M500123435','MPO482025081500002','35100034',1.0000000000,9106000500020134),
+(9106000500050135,'PR-UAT-FULL-20260605-036','M500123436','MPO482025081500002','35100033',1.0000000000,9106000500020135),
+(9106000500050136,'PR-UAT-FULL-20260605-037','M500123437','MPO482025081500002','35100033',1.0000000000,9106000500020136),
+(9106000500050137,'PR-UAT-FULL-20260605-038','M500123438','MPO482025081500002','35100033',1.0000000000,9106000500020137),
+(9106000500050138,'PR-UAT-FULL-20260605-039','M500123439','MPO482025081500002','35100033',1.0000000000,9106000500020138),
+(9106000500050139,'PR-UAT-FULL-20260605-040','M500123440','MPO482025081500002','35100033',1.0000000000,9106000500020139),
+(9106000500050140,'PR-UAT-FULL-20260605-041','M500123441','MPO482025081500002','35100033',-1.0000000000,9106000500020140),
+(9106000500050141,'PR-UAT-FULL-20260605-042','M500123442','MPO482025081500002','35100033',1.0000000000,9106000500020141),
+(9106000500050142,'PR-UAT-FULL-20260605-043','M500123443','MPO482025081500002','35100033',1.0000000000,9106000500020142),
+(9106000500050143,'PR-UAT-FULL-20260605-044','M500123444','MPO482025081500002','35100015',1.0000000000,9106000500020143),
+(9106000500050144,'PR-UAT-FULL-20260605-045','M500123445','MPO482025081500002','35100015',1.0000000000,9106000500020144),
+(9106000500050145,'PR-UAT-FULL-20260605-046','M500123446','MPO482025081500002','35100015',1.0000000000,9106000500020145),
+(9106000500050146,'PR-UAT-FULL-20260605-047','M500123447','MPO482025081500002','35100015',1.0000000000,9106000500020146),
+(9106000500050147,'PR-UAT-FULL-20260605-048','M500123448','MPO482025081500002','35100015',1.0000000000,9106000500020147),
+(9106000500050148,'PR-UAT-FULL-20260605-049','M500123449','MPO482025081500002','35100015',1.0000000000,9106000500020148),
+(9106000500050149,'PR-UAT-FULL-20260605-050','M500123450','MPO482025081500002','35100015',1.0000000000,9106000500020149),
+(9106000500050150,'PR-UAT-FULL-20260605-051','M500123451','MPO482025081500002','35100015',1.0000000000,9106000500020150),
+(9106000500050151,'PR-UAT-FULL-20260605-052','M500123452','MPO482025081500002','35100015',1.0000000000,9106000500020151),
+(9106000500050152,'PR-UAT-FULL-20260605-053','M500123453','MPO482025081500002','35100015',1.0000000000,9106000500020152),
+(9106000500050153,'PR-UAT-FULL-20260605-054','M500123454','MPO482025081500002','35100015',1.0000000000,9106000500020153),
+(9106000500050154,'PR-UAT-FULL-20260605-055','M500123455','MPO482025081500002','35100015',1.0000000000,9106000500020154),
+(9106000500050155,'PR-UAT-FULL-20260605-056','M500123456','MPO482025081500002','35100015',1.0000000000,9106000500020155),
+(9106000500050156,'PR-UAT-FULL-20260605-001','M500124855','MPO482025082900002','93000270',5000.0000000000,9106000500020156),
+(9106000500050157,'PR-UAT-FULL-20260605-002','M500124858','MPO482025082900002','93000311',510.0000000000,9106000500020157),
+(9106000500050158,'PR-UAT-FULL-20260605-003','M500124861','MPO482025082900002','93000312',500.0000000000,9106000500020158),
+(9106000500050159,'PR-UAT-FULL-20260605-004','M500124864','MPO482025082900002','93000233',600.0000000000,9106000500020159),
+(9106000500050160,'PR-UAT-FULL-20260605-005','M500124867','MPO482025082900002','93000232',1500.0000000000,9106000500020160),
+(9106000500050161,'PR-UAT-FULL-20260605-001','M500125396','MPO482025090400005','32300021',5000.0000000000,9106000500020161),
+(9106000500050162,'PR-UAT-FULL-20260605-002','M500125401','MPO482025090400005','32300021',5000.0000000000,9106000500020162),
+(9106000500050163,'PR-UAT-FULL-20260605-001','M500130061','MPO482025091800003','32300065',1900.0000000000,9106000500020163),
+(9106000500050164,'PR-UAT-FULL-20260605-002','M500130063','MPO482025091800003','32300021',100.0000000000,9106000500020164),
+(9106000500050165,'PR-UAT-FULL-20260605-003','M500130067','MPO482025091800003','32300021',600.0000000000,9106000500020165),
+(9106000500050166,'PR-UAT-FULL-20260605-004','M500130068','MPO482025091800003','93000313',100.0000000000,9106000500020166),
+(9106000500050167,'PR-UAT-FULL-20260605-005','M500130070','MPO482025091800003','93000229',700.0000000000,9106000500020167),
+(9106000500050168,'PR-UAT-FULL-20260605-001','M500130445','MPO482025091900001','93000182',10000.0000000000,9106000500020168),
+(9106000500050169,'PR-UAT-FULL-20260605-002','M500130446','MPO482025091900001','32300009',10000.0000000000,9106000500020169),
+(9106000500050170,'PR-UAT-FULL-20260605-003','M500130447','MPO482025091900001','32300012',10000.0000000000,9106000500020170),
+(9106000500050171,'PR-UAT-FULL-20260605-004','M500130448','MPO482025091900001','32300026',-2980.0000000000,9106000500020171),
+(9106000500050172,'PR-UAT-FULL-20260605-005','M500130449','MPO482025091900001','32300027',-2968.0000000000,9106000500020172),
+(9106000500050173,'PR-UAT-FULL-20260605-006','M500130450','MPO482025091900001','32300028',3000.0000000000,9106000500020173),
+(9106000500050174,'PR-UAT-FULL-20260605-007','M500130451','MPO482025091900001','32300035',10000.0000000000,9106000500020174),
+(9106000500050175,'PR-UAT-FULL-20260605-008','M500130452','MPO482025091900001','32300046',3000.0000000000,9106000500020175),
+(9106000500050176,'PR-UAT-FULL-20260605-009','M500130453','MPO482025091900001','32300047',2108.0000000000,9106000500020176),
+(9106000500050177,'PR-UAT-FULL-20260605-010','M500130454','MPO482025091900001','32300048',-10000.0000000000,9106000500020177),
+(9106000500050178,'PR-UAT-FULL-20260605-011','M500130455','MPO482025091900001','35100015',1.0000000000,9106000500020178),
+(9106000500050179,'PR-UAT-FULL-20260605-012','M500130456','MPO482025091900001','35100015',1.0000000000,9106000500020179),
+(9106000500050180,'PR-UAT-FULL-20260605-013','M500130457','MPO482025091900001','35100015',1.0000000000,9106000500020180),
+(9106000500050181,'PR-UAT-FULL-20260605-014','M500130458','MPO482025091900001','35100015',1.0000000000,9106000500020181),
+(9106000500050182,'PR-UAT-FULL-20260605-015','M500130459','MPO482025091900001','35100016',1.0000000000,9106000500020182),
+(9106000500050183,'PR-UAT-FULL-20260605-016','M500130460','MPO482025091900001','35100016',1.0000000000,9106000500020183),
+(9106000500050184,'PR-UAT-FULL-20260605-017','M500130461','MPO482025091900001','35100016',1.0000000000,9106000500020184),
+(9106000500050185,'PR-UAT-FULL-20260605-018','M500130462','MPO482025091900001','35100016',1.0000000000,9106000500020185),
+(9106000500050186,'PR-UAT-FULL-20260605-019','M500130463','MPO482025091900001','35100016',1.0000000000,9106000500020186),
+(9106000500050187,'PR-UAT-FULL-20260605-020','M500130464','MPO482025091900001','35100016',1.0000000000,9106000500020187),
+(9106000500050188,'PR-UAT-FULL-20260605-021','M500130465','MPO482025091900001','35100015',1.0000000000,9106000500020188),
+(9106000500050189,'PR-UAT-FULL-20260605-022','M500130466','MPO482025091900001','35100015',1.0000000000,9106000500020189),
+(9106000500050190,'PR-UAT-FULL-20260605-023','M500130467','MPO482025091900001','35100015',1.0000000000,9106000500020190),
+(9106000500050191,'PR-UAT-FULL-20260605-024','M500130468','MPO482025091900001','35100015',1.0000000000,9106000500020191),
+(9106000500050192,'PR-UAT-FULL-20260605-025','M500130469','MPO482025091900001','35100015',1.0000000000,9106000500020192),
+(9106000500050193,'PR-UAT-FULL-20260605-026','M500130470','MPO482025091900001','35100015',1.0000000000,9106000500020193),
+(9106000500050194,'PR-UAT-FULL-20260605-027','M500130471','MPO482025091900001','35100015',1.0000000000,9106000500020194),
+(9106000500050195,'PR-UAT-FULL-20260605-001','M500130840','MPO482025092200002','93000283',20000.0000000000,9106000500020195),
+(9106000500050196,'PR-UAT-FULL-20260605-001','M500103888','MPO482026012100001','3221C0031',1000.0000000000,9106000500020196),
+(9106000500050197,'PR-UAT-FULL-20260605-002','M500103890','MPO482026012100001','3521C0018',2.0000000000,9106000500020197),
+(9106000500050198,'PR-UAT-FULL-20260605-003','M500103891','MPO482026012100001','1A0047E',1000.0000000000,9106000500020198),
+(9106000500050199,'PR-UAT-FULL-20260605-001','M500105946','MPO482026020300001','3221C0031',100.0000000000,9106000500020199),
+(9106000500050200,'PR-UAT-FULL-20260605-001','UAT-MO-0034','SO241020240923001','91CC0232',400.00000000,9106000500020200),
+(9106000500050201,'PR-UAT-FULL-20260605-001','M500028977','SO241020241014001','1007114',120000.0000000000,9106000500020201),
+(9106000500050202,'PR-UAT-FULL-20260605-002','M500028978','SO241020241014001','1007115',30000.0000000000,9106000500020202),
+(9106000500050203,'PR-UAT-FULL-20260605-001','M500028992','SO241020241015003','1000431',5000.0000000000,9106000500020203),
+(9106000500050204,'PR-UAT-FULL-20260605-002','M500028993','SO241020241015003','1000432',5000.0000000000,9106000500020204),
+(9106000500050205,'PR-UAT-FULL-20260605-001','M500029021','SO241020241018001','1000595',92000.0000000000,9106000500020205),
+(9106000500050206,'PR-UAT-FULL-20260605-002','M500029024','SO241020241018001','1007096',7000.0000000000,9106000500020206),
+(9106000500050207,'PR-UAT-FULL-20260605-003','M500029027','SO241020241018001','1002081',1256.0000000000,9106000500020207),
+(9106000500050208,'PR-UAT-FULL-20260605-004','M500029034','SO241020241018001','93000236',140.0000000000,9106000500020208),
+(9106000500050209,'PR-UAT-FULL-20260605-001','M500029040','SO241020241019001','93000228',3000.0000000000,9106000500020209),
+(9106000500050210,'PR-UAT-FULL-20260605-001','UAT-MO-0039','SO241020241021002','1A039D8',350.00000000,9106000500020210),
+(9106000500050211,'PR-UAT-FULL-20260605-001','M500029272','SO241020241022001','93000235',600.0000000000,9106000500020211),
+(9106000500050212,'PR-UAT-FULL-20260605-001','M500033844','SO241020241102001','94000284',10000.0000000000,9106000500020212),
+(9106000500050213,'PR-UAT-FULL-20260605-002','M500033846','SO241020241102001','1002081',1200.0000000000,9106000500020213),
+(9106000500050214,'PR-UAT-FULL-20260605-001','M500033849','SO241020241102004','93000179',2000.0000000000,9106000500020214),
+(9106000500050215,'PR-UAT-FULL-20260605-001','M500033851','SO241020241104001','93000229',6000.0000000000,9106000500020215),
+(9106000500050216,'PR-UAT-FULL-20260605-002','M500033853','SO241020241104001','1008414',176.0000000000,9106000500020216),
+(9106000500050217,'PR-UAT-FULL-20260605-003','M500033854','SO241020241104001','94000284',10000.0000000000,9106000500020217),
+(9106000500050218,'PR-UAT-FULL-20260605-004','M500033856','SO241020241104001','94000219',11000.0000000000,9106000500020218),
+(9106000500050219,'PR-UAT-FULL-20260605-005','M500033857','SO241020241104001','93000233',1000.0000000000,9106000500020219),
+(9106000500050220,'PR-UAT-FULL-20260605-001','UAT-MO-0044','SO241020241219001','91DC0218',400.00000000,9106000500020220),
+(9106000500050221,'PR-UAT-FULL-20260605-001','UAT-MO-0045','SO241020250114003','1A03G94',1686.00000000,9106000500020221);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_line;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_line (
+    pur_ord VARCHAR(48) NOT NULL,
+    line_no INT NOT NULL,
+    sales_ord VARCHAR(64) NOT NULL,
+    work_ord VARCHAR(128) NULL,
+    item_num VARCHAR(60) NOT NULL,
+    qty DECIMAL(15,5) NOT NULL,
+    PRIMARY KEY (pur_ord, line_no)
+);
+INSERT INTO tmp_s3_uat_po_line VALUES
+('PO-UAT-FULL-20260605-001',1,'MPO482024102400001','M500029670','91DC0292',4500.00000000),
+('PO-UAT-FULL-20260605-001',2,'MPO482024102400001','M500029671','1A03D23',3500.00000000),
+('PO-UAT-FULL-20260605-001',3,'MPO482024102400001','M500029672','1A0C329',400000.00000000),
+('PO-UAT-FULL-20260605-001',4,'MPO482024102400001','M500029673','1A0C655',100000.00000000),
+('PO-UAT-FULL-20260605-001',5,'MPO482024102400001','M500029674','A2C7114',250000.00000000),
+('PO-UAT-FULL-20260605-001',6,'MPO482024102400001','M500029675','A2C7115',600000.00000000),
+('PO-UAT-FULL-20260605-001',7,'MPO482024102400001','M500029676','A2B4199',6000.00000000),
+('PO-UAT-FULL-20260605-001',8,'MPO482024102400001','M500029677','1A0C588',10000.00000000),
+('PO-UAT-FULL-20260605-001',9,'MPO482024102400001','M500029678','1A03G94',2500.00000000),
+('PO-UAT-FULL-20260605-001',10,'MPO482024102400001','M500029680','91CC0286',1500.00000000),
+('PO-UAT-FULL-20260605-001',11,'MPO482024102400001','M500029682','91DC0218',800.00000000),
+('PO-UAT-FULL-20260605-002',1,'MPO482024120200001','M500053217','91CC0229',60.00000000),
+('PO-UAT-FULL-20260605-003',1,'MPO482024120200002','M500053390','91DC0218',2000.00000000),
+('PO-UAT-FULL-20260605-004',1,'MPO482024120400002','M500055223','91CC0237',200.00000000),
+('PO-UAT-FULL-20260605-005',1,'MPO482025010700001','M500061078','A2C7114',250000.00000000),
+('PO-UAT-FULL-20260605-006',1,'MPO482025010700002','M500061979','1A0C329',100000.00000000),
+('PO-UAT-FULL-20260605-007',1,'MPO482025010900001','M500067184','91CC0312',500.00000000),
+('PO-UAT-FULL-20260605-007',2,'MPO482025010900001','M500067185','1A03D23',600.00000000),
+('PO-UAT-FULL-20260605-007',3,'MPO482025010900001','M500067186','91CC0231',100.00000000),
+('PO-UAT-FULL-20260605-007',4,'MPO482025010900001','M500067187','91CC0286',800.00000000),
+('PO-UAT-FULL-20260605-008',1,'MPO482025011000001','M500068611','91C0D058',400.00000000),
+('PO-UAT-FULL-20260605-009',1,'MPO482025011000002','M500068948','A2B8361',1000.00000000),
+('PO-UAT-FULL-20260605-010',1,'MPO482025011000003','M500069117','A2B8184',700.00000000),
+('PO-UAT-FULL-20260605-011',1,'MPO482025011300002','M500070459','A2B4199',4000.00000000),
+('PO-UAT-FULL-20260605-012',1,'MPO482025011300003','M500070619','1A03D23',5000.00000000),
+('PO-UAT-FULL-20260605-013',1,'MPO482025011300005','M500070942','ABC431',10000.00000000),
+('PO-UAT-FULL-20260605-013',2,'MPO482025011300005','M500070943','1A0C432',10000.00000000),
+('PO-UAT-FULL-20260605-014',1,'MPO482025011300006','M500070944','ABC419',35000.00000000),
+('PO-UAT-FULL-20260605-015',1,'MPO482025011400001','M500072258','1A0C293',650000.00000000),
+('PO-UAT-FULL-20260605-015',2,'MPO482025011400001','M500072259','1A0C329',200000.00000000),
+('PO-UAT-FULL-20260605-016',1,'MPO482025011400002','M500072882','91DC0215',1500.00000000),
+('PO-UAT-FULL-20260605-017',1,'MPO482025022100001','M500085317','91CC0179',5000.00000000),
+('PO-UAT-FULL-20260605-017',2,'MPO482025022100001','M500085321','91CC0287',10000.00000000),
+('PO-UAT-FULL-20260605-017',3,'MPO482025022100001','M500085326','91CC0288',10000.00000000),
+('PO-UAT-FULL-20260605-017',4,'MPO482025022100001','M500085328','91CC0187',5000.00000000),
+('PO-UAT-FULL-20260605-017',5,'MPO482025022100001','M500085329','91CC0233',1500.00000000),
+('PO-UAT-FULL-20260605-017',6,'MPO482025022100001','M500085330','91DC0218',3000.00000000),
+('PO-UAT-FULL-20260605-017',7,'MPO482025022100001','M500085331','A21C096',10000.00000000),
+('PO-UAT-FULL-20260605-018',1,'MPO482025032900001','M500089559','91CC0177',5000.00000000),
+('PO-UAT-FULL-20260605-018',2,'MPO482025032900001','M500089562','91CC0179',5000.00000000),
+('PO-UAT-FULL-20260605-018',3,'MPO482025032900001','M500089566','91CC0287',4000.00000000),
+('PO-UAT-FULL-20260605-018',4,'MPO482025032900001','M500089568','91DC0217',2000.00000000),
+('PO-UAT-FULL-20260605-018',5,'MPO482025032900001','M500089569','91DC0219',9000.00000000),
+('PO-UAT-FULL-20260605-018',6,'MPO482025032900001','M500089570','91C0D2D',2000.00000000),
+('PO-UAT-FULL-20260605-018',7,'MPO482025032900001','M500089573','AB47111',200000.00000000),
+('PO-UAT-FULL-20260605-019',1,'MPO482025041300001','M500090472','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-019',2,'MPO482025041300001','M500090473','3521C0014',1.00000000),
+('PO-UAT-FULL-20260605-019',3,'MPO482025041300001','M500090474','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-019',4,'MPO482025041300001','M500090475','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-020',1,'MPO482025042800001','M500093527','3221C0031',7000.00000000),
+('PO-UAT-FULL-20260605-021',1,'MPO482025051800001','M500101110','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',2,'MPO482025051800001','M500101111','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',3,'MPO482025051800001','M500101112','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',4,'MPO482025051800001','M500101113','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',5,'MPO482025051800001','M500101114','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',6,'MPO482025051800001','M500101115','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',7,'MPO482025051800001','M500101116','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',8,'MPO482025051800001','M500101117','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',9,'MPO482025051800001','M500101118','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-021',10,'MPO482025051800001','M500101119','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-022',1,'MPO482025062100002','M500108428','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-022',2,'MPO482025062100002','M500108429','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-022',3,'MPO482025062100002','M500108430','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-022',4,'MPO482025062100002','M500108431','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-022',5,'MPO482025062100002','M500108432','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-022',6,'MPO482025062100002','M500108433','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-022',7,'MPO482025062100002','M500108434','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-022',8,'MPO482025062100002','M500108435','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-022',9,'MPO482025062100002','M500108436','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-022',10,'MPO482025062100002','M500108437','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-022',11,'MPO482025062100002','M500108438','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-022',12,'MPO482025062100002','M500108439','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-023',1,'MPO482025062100003','M500108487','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-023',2,'MPO482025062100003','M500108488','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-023',3,'MPO482025062100003','M500108489','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-023',4,'MPO482025062100003','M500108490','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',5,'MPO482025062100003','M500108491','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',6,'MPO482025062100003','M500108492','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',7,'MPO482025062100003','M500108493','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',8,'MPO482025062100003','M500108494','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',9,'MPO482025062100003','M500108495','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',10,'MPO482025062100003','M500108496','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',11,'MPO482025062100003','M500108497','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',12,'MPO482025062100003','M500108498','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-023',13,'MPO482025062100003','M500108499','352AD0A',1.00000000),
+('PO-UAT-FULL-20260605-024',1,'MPO482025062600003','M500109125','91CC0178',4000.00000000),
+('PO-UAT-FULL-20260605-024',2,'MPO482025062600003','M500109128','91CC0285',2000.00000000),
+('PO-UAT-FULL-20260605-024',3,'MPO482025062600003','M500109132','91CC0286',4000.00000000),
+('PO-UAT-FULL-20260605-024',4,'MPO482025062600003','M500109134','A2B8361',4000.00000000),
+('PO-UAT-FULL-20260605-025',1,'MPO482025081500001','M500123310','1A0C273',200.00000000),
+('PO-UAT-FULL-20260605-025',2,'MPO482025081500001','M500123311','1A0C275',272.00000000),
+('PO-UAT-FULL-20260605-025',3,'MPO482025081500001','M500123312','1A004C4',960000.00000000),
+('PO-UAT-FULL-20260605-025',4,'MPO482025081500001','M500123313','ABC419',1000.00000000),
+('PO-UAT-FULL-20260605-025',5,'MPO482025081500001','M500123314','ABC431',2000.00000000),
+('PO-UAT-FULL-20260605-025',6,'MPO482025081500001','M500123315','1A0C432',1000.00000000),
+('PO-UAT-FULL-20260605-025',7,'MPO482025081500001','M500123316','1A0C588',29000.00000000),
+('PO-UAT-FULL-20260605-025',8,'MPO482025081500001','M500123317','1A0C595',670000.00000000),
+('PO-UAT-FULL-20260605-025',9,'MPO482025081500001','M500123318','AB32A4',111.00000000),
+('PO-UAT-FULL-20260605-026',1,'MPO482025081500002','M500123386','A21C092',550.00000000),
+('PO-UAT-FULL-20260605-026',2,'MPO482025081500002','M500123387','A21C093',60.00000000),
+('PO-UAT-FULL-20260605-026',3,'MPO482025081500002','M500123388','91B0D033',38.00000000),
+('PO-UAT-FULL-20260605-026',4,'MPO482025081500002','M500123389','91C0D058',558.00000000),
+('PO-UAT-FULL-20260605-026',5,'MPO482025081500002','M500123390','91C0D074',2522.00000000),
+('PO-UAT-FULL-20260605-026',6,'MPO482025081500002','M500123392','91C0DA8',69.00000000),
+('PO-UAT-FULL-20260605-026',7,'MPO482025081500002','M500123393','93B0D1A',185.00000000),
+('PO-UAT-FULL-20260605-026',8,'MPO482025081500002','M500123395','91CC0123',2.00000000),
+('PO-UAT-FULL-20260605-026',9,'MPO482025081500002','M500123396','91CC0229',862.00000000),
+('PO-UAT-FULL-20260605-026',10,'MPO482025081500002','M500123401','91CC0262',200.00000000),
+('PO-UAT-FULL-20260605-026',11,'MPO482025081500002','M500123404','91CC0286',3000.00000000),
+('PO-UAT-FULL-20260605-026',12,'MPO482025081500002','M500123405','91CC0312',300.00000000),
+('PO-UAT-FULL-20260605-026',13,'MPO482025081500002','M500123407','91C0DD4',100.00000000),
+('PO-UAT-FULL-20260605-026',14,'MPO482025081500002','M500123408','91CC0412',58.00000000),
+('PO-UAT-FULL-20260605-026',15,'MPO482025081500002','M500123409','91C0DE2',400.00000000),
+('PO-UAT-FULL-20260605-026',16,'MPO482025081500002','M500123411','91C0DE3',1050.00000000),
+('PO-UAT-FULL-20260605-026',17,'MPO482025081500002','M500123413','91C0DE6',400.00000000),
+('PO-UAT-FULL-20260605-026',18,'MPO482025081500002','M500123414','91C0DE7',1000.00000000),
+('PO-UAT-FULL-20260605-026',19,'MPO482025081500002','M500123415','91C0DE9',350.00000000),
+('PO-UAT-FULL-20260605-026',20,'MPO482025081500002','M500123416','91C0D5A',1100.00000000),
+('PO-UAT-FULL-20260605-026',21,'MPO482025081500002','M500123417','91CC0518',1250.00000000),
+('PO-UAT-FULL-20260605-026',22,'MPO482025081500002','M500123418','91CC0521',3000.00000000),
+('PO-UAT-FULL-20260605-026',23,'MPO482025081500002','M500123419','91CC0524',1500.00000000),
+('PO-UAT-FULL-20260605-026',24,'MPO482025081500002','M500123420','91CC0525',3000.00000000),
+('PO-UAT-FULL-20260605-026',25,'MPO482025081500002','M500123421','91FC0339',600.00000000),
+('PO-UAT-FULL-20260605-026',26,'MPO482025081500002','M500123423','1AB9259',5000.00000000),
+('PO-UAT-FULL-20260605-026',27,'MPO482025081500002','M500123425','3124C0015',8000.00000000),
+('PO-UAT-FULL-20260605-026',28,'MPO482025081500002','M500123426','3151C0032',1.00000000),
+('PO-UAT-FULL-20260605-026',29,'MPO482025081500002','M500123427','1A0C452',1000.00000000),
+('PO-UAT-FULL-20260605-026',30,'MPO482025081500002','M500123430','91CC0517',100.00000000),
+('PO-UAT-FULL-20260605-026',31,'MPO482025081500002','M500123431','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-026',32,'MPO482025081500002','M500123432','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-026',33,'MPO482025081500002','M500123433','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-026',34,'MPO482025081500002','M500123434','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-026',35,'MPO482025081500002','M500123435','3151C0034',1.00000000),
+('PO-UAT-FULL-20260605-026',36,'MPO482025081500002','M500123436','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',37,'MPO482025081500002','M500123437','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',38,'MPO482025081500002','M500123438','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',39,'MPO482025081500002','M500123439','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',40,'MPO482025081500002','M500123440','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',41,'MPO482025081500002','M500123441','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',42,'MPO482025081500002','M500123442','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',43,'MPO482025081500002','M500123443','3151C0033',1.00000000),
+('PO-UAT-FULL-20260605-026',44,'MPO482025081500002','M500123444','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',45,'MPO482025081500002','M500123445','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',46,'MPO482025081500002','M500123446','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',47,'MPO482025081500002','M500123447','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',48,'MPO482025081500002','M500123448','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',49,'MPO482025081500002','M500123449','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',50,'MPO482025081500002','M500123450','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',51,'MPO482025081500002','M500123451','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',52,'MPO482025081500002','M500123452','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',53,'MPO482025081500002','M500123453','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',54,'MPO482025081500002','M500123454','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',55,'MPO482025081500002','M500123455','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-026',56,'MPO482025081500002','M500123456','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-027',1,'MPO482025082900002','M500124855','91C0D2G',5000.00000000),
+('PO-UAT-FULL-20260605-027',2,'MPO482025082900002','M500124858','93BC0311',510.00000000),
+('PO-UAT-FULL-20260605-027',3,'MPO482025082900002','M500124861','91CC0312',500.00000000),
+('PO-UAT-FULL-20260605-027',4,'MPO482025082900002','M500124864','91CC0233',400.00000000),
+('PO-UAT-FULL-20260605-027',5,'MPO482025082900002','M500124867','91CC0232',1500.00000000),
+('PO-UAT-FULL-20260605-028',1,'MPO482025090400005','M500125396','91CC0312',5000.00000000),
+('PO-UAT-FULL-20260605-028',2,'MPO482025090400005','M500125401','93BC0311',5000.00000000),
+('PO-UAT-FULL-20260605-029',1,'MPO482025091800003','M500130061','91CC0483',1900.00000000),
+('PO-UAT-FULL-20260605-029',2,'MPO482025091800003','M500130063','91CC0312',100.00000000),
+('PO-UAT-FULL-20260605-029',3,'MPO482025091800003','M500130067','93BC0311',600.00000000),
+('PO-UAT-FULL-20260605-029',4,'MPO482025091800003','M500130068','91CC0313',100.00000000),
+('PO-UAT-FULL-20260605-029',5,'MPO482025091800003','M500130070','91CC0229',700.00000000),
+('PO-UAT-FULL-20260605-030',1,'MPO482025091900001','M500130445','91CC0182',10000.00000000),
+('PO-UAT-FULL-20260605-030',2,'MPO482025091900001','M500130446','312CD009',10000.00000000),
+('PO-UAT-FULL-20260605-030',3,'MPO482025091900001','M500130447','3123C0012',10000.00000000),
+('PO-UAT-FULL-20260605-030',4,'MPO482025091900001','M500130448','3123C0026',3000.00000000),
+('PO-UAT-FULL-20260605-030',5,'MPO482025091900001','M500130449','3123C0027',3000.00000000),
+('PO-UAT-FULL-20260605-030',6,'MPO482025091900001','M500130450','3123C0028',3000.00000000),
+('PO-UAT-FULL-20260605-030',7,'MPO482025091900001','M500130451','3123C0035',10000.00000000),
+('PO-UAT-FULL-20260605-030',8,'MPO482025091900001','M500130452','3123C0046',3000.00000000),
+('PO-UAT-FULL-20260605-030',9,'MPO482025091900001','M500130453','3123C0047',3000.00000000),
+('PO-UAT-FULL-20260605-030',10,'MPO482025091900001','M500130454','3123C0048',3000.00000000),
+('PO-UAT-FULL-20260605-030',11,'MPO482025091900001','M500130455','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',12,'MPO482025091900001','M500130456','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',13,'MPO482025091900001','M500130457','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',14,'MPO482025091900001','M500130458','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',15,'MPO482025091900001','M500130459','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-030',16,'MPO482025091900001','M500130460','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-030',17,'MPO482025091900001','M500130461','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-030',18,'MPO482025091900001','M500130462','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-030',19,'MPO482025091900001','M500130463','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-030',20,'MPO482025091900001','M500130464','3521C0016',1.00000000),
+('PO-UAT-FULL-20260605-030',21,'MPO482025091900001','M500130465','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',22,'MPO482025091900001','M500130466','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',23,'MPO482025091900001','M500130467','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',24,'MPO482025091900001','M500130468','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',25,'MPO482025091900001','M500130469','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',26,'MPO482025091900001','M500130470','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-030',27,'MPO482025091900001','M500130471','3521C0015',1.00000000),
+('PO-UAT-FULL-20260605-031',1,'MPO482025092200002','M500130840','91CC0283',20000.00000000),
+('PO-UAT-FULL-20260605-032',1,'MPO482026012100001','M500103888','1A0044F',1000.00000000),
+('PO-UAT-FULL-20260605-032',2,'MPO482026012100001','M500103890','1A0045H',1000.00000000),
+('PO-UAT-FULL-20260605-032',3,'MPO482026012100001','M500103891','1A0047E',1000.00000000),
+('PO-UAT-FULL-20260605-033',1,'MPO482026020300001','M500105946','1A0044F',100.00000000),
+('PO-UAT-FULL-20260605-034',1,'SO241020240923001','UAT-MO-0034','91CC0232',400.00000000),
+('PO-UAT-FULL-20260605-035',1,'SO241020241014001','M500028977','A2C7114',120000.00000000),
+('PO-UAT-FULL-20260605-035',2,'SO241020241014001','M500028978','A2C7115',280000.00000000),
+('PO-UAT-FULL-20260605-036',1,'SO241020241015003','M500028992','ABC431',6614.00000000),
+('PO-UAT-FULL-20260605-036',2,'SO241020241015003','M500028993','1A0C432',7810.00000000),
+('PO-UAT-FULL-20260605-037',1,'SO241020241018001','M500029021','1A0C595',200000.00000000),
+('PO-UAT-FULL-20260605-037',2,'SO241020241018001','M500029024','1A03G96',1473.00000000),
+('PO-UAT-FULL-20260605-037',3,'SO241020241018001','M500029027','AB3B81',256.00000000),
+('PO-UAT-FULL-20260605-037',4,'SO241020241018001','M500029034','91CC0236',400.00000000),
+('PO-UAT-FULL-20260605-038',1,'SO241020241019001','M500029040','91CC0228',131.00000000),
+('PO-UAT-FULL-20260605-039',1,'SO241020241021002','UAT-MO-0039','1A039D8',350.00000000),
+('PO-UAT-FULL-20260605-040',1,'SO241020241022001','M500029272','91CC0235',600.00000000),
+('PO-UAT-FULL-20260605-041',1,'SO241020241102001','M500033844','91DC0284',813.00000000),
+('PO-UAT-FULL-20260605-041',2,'SO241020241102001','M500033846','AB3B81',218.00000000),
+('PO-UAT-FULL-20260605-042',1,'SO241020241102004','M500033849','91CC0179',1200.00000000),
+('PO-UAT-FULL-20260605-043',1,'SO241020241104001','M500033851','91CC0229',900.00000000),
+('PO-UAT-FULL-20260605-043',2,'SO241020241104001','M500033853','A2B8414',300.00000000),
+('PO-UAT-FULL-20260605-043',3,'SO241020241104001','M500033854','91DC0284',263.00000000),
+('PO-UAT-FULL-20260605-043',4,'SO241020241104001','M500033856','91DC0219',2030.00000000),
+('PO-UAT-FULL-20260605-043',5,'SO241020241104001','M500033857','91CC0233',800.00000000),
+('PO-UAT-FULL-20260605-044',1,'SO241020241219001','UAT-MO-0044','91DC0218',400.00000000),
+('PO-UAT-FULL-20260605-045',1,'SO241020250114003','UAT-MO-0045','1A03G94',1686.00000000);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_hdr;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_hdr (
+    pur_ord VARCHAR(48) NOT NULL PRIMARY KEY,
+    sales_ord VARCHAR(64) NOT NULL,
+    work_ord VARCHAR(128) NULL
+);
+INSERT INTO tmp_s3_uat_po_hdr
+SELECT pur_ord, MIN(sales_ord), MIN(work_ord) FROM tmp_s3_uat_po_line GROUP BY pur_ord;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s4_uat_ship;
+CREATE TEMPORARY TABLE tmp_s4_uat_ship (
+    ship_id BIGINT NOT NULL PRIMARY KEY,
+    po_billno VARCHAR(48) NOT NULL,
+    shddh VARCHAR(64) NOT NULL
+);
+INSERT INTO tmp_s4_uat_ship VALUES
+(9106000500060002,'PO-UAT-FULL-20260605-001','SH-UAT-FULL-20260605-001'),
+(9106000500060003,'PO-UAT-FULL-20260605-002','SH-UAT-FULL-20260605-002'),
+(9106000500060004,'PO-UAT-FULL-20260605-003','SH-UAT-FULL-20260605-003'),
+(9106000500060005,'PO-UAT-FULL-20260605-004','SH-UAT-FULL-20260605-004'),
+(9106000500060006,'PO-UAT-FULL-20260605-005','SH-UAT-FULL-20260605-005'),
+(9106000500060007,'PO-UAT-FULL-20260605-006','SH-UAT-FULL-20260605-006'),
+(9106000500060008,'PO-UAT-FULL-20260605-007','SH-UAT-FULL-20260605-007'),
+(9106000500060009,'PO-UAT-FULL-20260605-008','SH-UAT-FULL-20260605-008'),
+(9106000500060010,'PO-UAT-FULL-20260605-009','SH-UAT-FULL-20260605-009'),
+(9106000500060011,'PO-UAT-FULL-20260605-010','SH-UAT-FULL-20260605-010'),
+(9106000500060012,'PO-UAT-FULL-20260605-011','SH-UAT-FULL-20260605-011'),
+(9106000500060013,'PO-UAT-FULL-20260605-012','SH-UAT-FULL-20260605-012'),
+(9106000500060014,'PO-UAT-FULL-20260605-013','SH-UAT-FULL-20260605-013'),
+(9106000500060015,'PO-UAT-FULL-20260605-014','SH-UAT-FULL-20260605-014'),
+(9106000500060016,'PO-UAT-FULL-20260605-015','SH-UAT-FULL-20260605-015'),
+(9106000500060017,'PO-UAT-FULL-20260605-016','SH-UAT-FULL-20260605-016'),
+(9106000500060018,'PO-UAT-FULL-20260605-017','SH-UAT-FULL-20260605-017'),
+(9106000500060019,'PO-UAT-FULL-20260605-018','SH-UAT-FULL-20260605-018'),
+(9106000500060020,'PO-UAT-FULL-20260605-019','SH-UAT-FULL-20260605-019'),
+(9106000500060021,'PO-UAT-FULL-20260605-020','SH-UAT-FULL-20260605-020'),
+(9106000500060022,'PO-UAT-FULL-20260605-021','SH-UAT-FULL-20260605-021'),
+(9106000500060023,'PO-UAT-FULL-20260605-022','SH-UAT-FULL-20260605-022'),
+(9106000500060024,'PO-UAT-FULL-20260605-023','SH-UAT-FULL-20260605-023'),
+(9106000500060025,'PO-UAT-FULL-20260605-024','SH-UAT-FULL-20260605-024'),
+(9106000500060026,'PO-UAT-FULL-20260605-025','SH-UAT-FULL-20260605-025'),
+(9106000500060027,'PO-UAT-FULL-20260605-026','SH-UAT-FULL-20260605-026'),
+(9106000500060028,'PO-UAT-FULL-20260605-027','SH-UAT-FULL-20260605-027'),
+(9106000500060029,'PO-UAT-FULL-20260605-028','SH-UAT-FULL-20260605-028'),
+(9106000500060030,'PO-UAT-FULL-20260605-029','SH-UAT-FULL-20260605-029'),
+(9106000500060031,'PO-UAT-FULL-20260605-030','SH-UAT-FULL-20260605-030'),
+(9106000500060032,'PO-UAT-FULL-20260605-031','SH-UAT-FULL-20260605-031'),
+(9106000500060033,'PO-UAT-FULL-20260605-032','SH-UAT-FULL-20260605-032'),
+(9106000500060034,'PO-UAT-FULL-20260605-033','SH-UAT-FULL-20260605-033'),
+(9106000500060035,'PO-UAT-FULL-20260605-034','SH-UAT-FULL-20260605-034'),
+(9106000500060036,'PO-UAT-FULL-20260605-035','SH-UAT-FULL-20260605-035'),
+(9106000500060037,'PO-UAT-FULL-20260605-036','SH-UAT-FULL-20260605-036'),
+(9106000500060038,'PO-UAT-FULL-20260605-037','SH-UAT-FULL-20260605-037'),
+(9106000500060039,'PO-UAT-FULL-20260605-038','SH-UAT-FULL-20260605-038'),
+(9106000500060040,'PO-UAT-FULL-20260605-039','SH-UAT-FULL-20260605-039'),
+(9106000500060041,'PO-UAT-FULL-20260605-040','SH-UAT-FULL-20260605-040'),
+(9106000500060042,'PO-UAT-FULL-20260605-041','SH-UAT-FULL-20260605-041'),
+(9106000500060043,'PO-UAT-FULL-20260605-042','SH-UAT-FULL-20260605-042'),
+(9106000500060044,'PO-UAT-FULL-20260605-043','SH-UAT-FULL-20260605-043'),
+(9106000500060045,'PO-UAT-FULL-20260605-044','SH-UAT-FULL-20260605-044'),
+(9106000500060046,'PO-UAT-FULL-20260605-045','SH-UAT-FULL-20260605-045');
+START TRANSACTION;
+
+INSERT INTO crm_seorder (
+    Id, bill_no, order_type, custom_no, custom_name,
+    date, rdate, urgent, bill_from, closed, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT target_id, bill_no, 1, custom_no, custom_name,
+       order_date, delivery_date, urgent,
+       CONCAT('UAT瀵煎叆:', @batch_no), 0, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id
+FROM tmp_s1_uat_so;
+
+INSERT INTO crm_seorderentry (
+    Id, seorder_id, bill_no, entry_seq, item_number,
+    qty, plan_date, date, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id, seorderentry_id
+)
+SELECT l.target_id, s.target_id, l.bill_no, l.entry_seq, l.item_number,
+       l.qty, l.plan_date, s.order_date, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id, l.target_id
+FROM tmp_s1_uat_so_line l
+JOIN tmp_s1_uat_so s ON s.bill_no = l.bill_no;
+
+INSERT INTO mes_morder (
+    Id, morder_no, morder_date, morder_state, product_code, product_name,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT target_mo_id, morder_no, @now, 'Released', product_code, product_code,
+       need_number, need_number, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id
+FROM tmp_s2_uat_morder;
+
+INSERT INTO mes_moentry (
+    Id, moentry_moid, moentry_mono, soentry_id, fbill_no,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, tenant_id, factory_id
+)
+SELECT m.target_me_id, m.target_mo_id, m.morder_no, l.target_id, m.bill_no,
+       m.need_number, m.need_number, 0,
+       @operator_name, @now, @tenant_id, @factory_id
+FROM tmp_s2_uat_morder m
+JOIN tmp_s1_uat_so_line l ON l.source_entry = m.source_entry;
+
+INSERT INTO WorkOrdMaster (
+    Domain, WorkOrd, ItemNum, Status, QtyOrded, QtyCompleted, LbrVar,
+    OrdDate, DueDate, SalesJob, BusinessID, IsActive, IsConfirm, Priority, Urgent,
+    tenant_id, CreateTime, UpdateTime
+)
+SELECT '8010', morder_no, product_code, 'R',
+       need_number, 0, 0, @now, DATE_ADD(@now, INTERVAL 14 DAY), bill_no,
+       0, 1, 1, 0, 0, @tenant_id, @now, @now
+FROM tmp_s2_uat_morder;
+
+INSERT INTO srm_pr_main (
+    Id, pr_billno, pr_purchaseid, pr_purchasenumber, pr_purchasename,
+    pr_rqty, pr_aqty, pr_sqty, icitem_id, icitem_name,
+    state, pr_type, currencytype,
+    create_by, create_by_name, create_time, update_by, update_by_name, update_time,
+    tenant_id, factory_id, IsDeleted, IsRequireGoods
+)
+SELECT p.voucher, p.pr_billno, p.mo_id, p.morder_no, p.morder_no,
+       p.pr_rqty, 0, 0, 0, p.icitem_code,
+       1, 1, 0,
+       @operator_id, @operator_name, @now, @operator_id, @operator_name, @now,
+       @tenant_id, @factory_id, 0, 0
+FROM tmp_s3_uat_pr p;
+
+INSERT INTO PurOrdMaster (
+    OwnerApplication, APAcct, CostCtr, APSubAcct, Bank, BillTo, BlanketOrd, Buyer, CloseDate,
+    CommentIndex, Confirming, Consignment, Contact, Contract, CreditTermsInt, CreditTerms, Curr,
+    CycleCode, DeliverTo, Disc, Domain, DueDate, DutyType, BlanketStart, BlanketEnd, ExchRate,
+    ERSOption, EstVal, Sequence, ExchRate1, ExchRate2, RateType, FixedPrice, FixedRate, FOB, Frt,
+    FSMType, FSTID, InvoicesVia, EMTPO, Language, MaxAgingDays, PurOrd, OrdDate, PartialOK,
+    AmtPrepaid, LastPriceDt, PricingDate, PrintPO, Project, DiscTbl, PriceTbl, ERSPriceListOption,
+    PST, PSTID, Recurr, `Release`, Rel, ReqBy, Revision, Remark, Scheduled, SchedulesVia,
+    ServiceCharge, ShipTo, ShipVia, Site, SecondarySOCrHold, PrimarySO, SpecialCharge, Status,
+    Taxable, TaxClass, TaxDate, TaxEnvironment, Tax1, Tax2, Tax3, TaxUsage, TermsofTrade,
+    TransportDays, Typed, Ufld1, Ufld2, EnteredBy, Supp, Transm, BusinessID, CreateUser,
+    UpdateUser, CreateTime, UpdateTime, EffTime, IsActive, IsConfirm, Potype, Department,
+    IsChanged, TaxIn, Amt, `Usage`, CustAddress, CustContact, CustPhone, SalesOrd, CustPO,
+    IsPriceChanged, CustName, Rev, RoleNo, InvoiceType, PricingMethod, ERPfld1, ERPWorkOrd,
+    WorkOrd, tenant_id
+)
+SELECT
+    m.OwnerApplication, m.APAcct, m.CostCtr, m.APSubAcct, m.Bank, m.BillTo, m.BlanketOrd, @operator_name, m.CloseDate,
+    m.CommentIndex, m.Confirming, m.Consignment, m.Contact, m.Contract, m.CreditTermsInt, m.CreditTerms, m.Curr,
+    m.CycleCode, m.DeliverTo, m.Disc, m.Domain, m.DueDate, m.DutyType, m.BlanketStart, m.BlanketEnd, m.ExchRate,
+    m.ERSOption, m.EstVal, m.Sequence, m.ExchRate1, m.ExchRate2, m.RateType, m.FixedPrice, m.FixedRate, m.FOB, m.Frt,
+    m.FSMType, m.FSTID, m.InvoicesVia, m.EMTPO, m.Language, m.MaxAgingDays, h.pur_ord, @now, m.PartialOK,
+    m.AmtPrepaid, m.LastPriceDt, m.PricingDate, m.PrintPO, m.Project, m.DiscTbl, m.PriceTbl, m.ERSPriceListOption,
+    m.PST, m.PSTID, m.Recurr, m.`Release`, m.Rel, m.ReqBy, m.Revision, CONCAT('UAT:', @batch_no), m.Scheduled, m.SchedulesVia,
+    m.ServiceCharge, m.ShipTo, m.ShipVia, m.Site, m.SecondarySOCrHold, m.PrimarySO, m.SpecialCharge, m.Status,
+    m.Taxable, m.TaxClass, m.TaxDate, m.TaxEnvironment, m.Tax1, m.Tax2, m.Tax3, m.TaxUsage, m.TermsofTrade,
+    m.TransportDays, m.Typed, m.Ufld1, m.Ufld2, m.EnteredBy, 'VEN00060', m.Transm, m.BusinessID, @operator_name,
+    @operator_name, @now, @now, m.EffTime, m.IsActive, m.IsConfirm, 'PT', m.Department,
+    m.IsChanged, m.TaxIn, m.Amt, m.`Usage`, m.CustAddress, m.CustContact, m.CustPhone, h.sales_ord, m.CustPO,
+    m.IsPriceChanged, m.CustName, m.Rev, m.RoleNo, m.InvoiceType, m.PricingMethod, m.ERPfld1, m.ERPWorkOrd,
+    h.work_ord, @tenant_id
+FROM tmp_s3_uat_po_hdr h
+CROSS JOIN (SELECT * FROM PurOrdMaster WHERE PurOrd='PW202605100002' AND tenant_id=@tenant_id LIMIT 1) m;
+
+INSERT INTO PurOrdDetail (
+    QtyBO, RctCost, CreditTermsInt, UpdateCurrentCost, CumReceived1, CumReceived2, CumReceived3, CumReceived4,
+    Disc, FixedPrice, InspectReq, SingleLot, SupplyPer, PurOrd, PST, PackingSlipQty, PayUMConv, PurCost,
+    RctQty, QtyOrded, QtyReceived, QtyReturned, Active, QtyReleased, RctUMConversion, Scheduled, ScheduledChanged,
+    SchedMRPReq, SafetyDays, SafetyHours, StdCost, Taxable, TaxIn, MaxTaxableAmt, TransportHours, UMConversion, VAT,
+    IsActive, IsConfirm, Potype, IsChanged, TaxRate, IsRounding, ReceiptQty, BarCodeQty, IsClosed, QtyReturnedRefund, CumQtyBO,
+    Line, ItemNum, UM, DueDate, LotSerial, PurOrdRecID, Status, WorkOrd,
+    CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id
+)
+SELECT
+    0,0,0,0,0,0,0,0,0,0,0,0,0,pl.pur_ord,0,0,1,0,0,pl.qty,0,0,1,0,1,0,0,0,0,0,0,1,1,0,0,1,0,
+    1,1,'PT',0,0,0,0,0,0,0,0,
+    pl.line_no, pl.item_num, 'EA', DATE_ADD(@now, INTERVAL 14 DAY), '', 0, 'O', pl.work_ord,
+    @operator_name, @now, @operator_name, @now, @tenant_id
+FROM tmp_s3_uat_po_line pl;
+
+SET @ds_seq := 800;
+INSERT INTO srm_polist_ds (
+    Id, domain, icdsid, dsnum, status, itemnum, um, purgroup,
+    suppliercode, supplier, ponumber, poline, schedqty, needdate, remarks, tenant_id
+)
+SELECT
+    @id_base+(@ds_seq:=@ds_seq+1),
+    '8010', @id_base+800, CONCAT('DS-', pl.pur_ord, '-', pl.line_no),
+    'P', pl.item_num, 'EA', 'PG01', 'VEN00060', 'VEN00060',
+    pl.pur_ord, pl.line_no, pl.qty, DATE_ADD(@now, INTERVAL 14 DAY), '', @tenant_id
+FROM tmp_s3_uat_po_line pl
+CROSS JOIN (SELECT @ds_seq:=800) init;
+
+INSERT INTO scm_shd (id, po_billno, shddh, sh_purchase_num, estimated_delivery_date, tjrxm, tjrq, state)
+SELECT ship_id, po_billno, shddh, 'VEN00060', DATE_ADD(@now, INTERVAL 7 DAY), @operator_name, DATE_FORMAT(@now,'%Y-%m-%d'), 0
+FROM tmp_s4_uat_ship;
+
+SET @zb_seq := 700;
+INSERT INTO scm_shdzb (id, glid, sh_material_code, sh_delivery_quantity, po_bill, po_billline)
+SELECT @id_base+(@zb_seq:=@zb_seq+1), CAST(s.ship_id AS CHAR), pl.item_num, pl.qty, pl.pur_ord, CAST(pl.line_no AS CHAR)
+FROM tmp_s3_uat_po_line pl
+JOIN tmp_s4_uat_ship s ON s.po_billno = pl.pur_ord
+CROSS JOIN (SELECT @zb_seq:=700) init;
+
+COMMIT;
+
+SELECT 'crm_seorder' AS tbl, COUNT(*) cnt FROM crm_seorder WHERE tenant_id=@tenant_id AND bill_from LIKE CONCAT('UAT瀵煎叆:',@batch_no,'%');
+SELECT 'crm_seorderentry' AS tbl, COUNT(*) cnt FROM crm_seorderentry WHERE tenant_id=@tenant_id AND bill_no IN (SELECT bill_no FROM tmp_s1_uat_so);
+SELECT 'mes_morder' AS tbl, COUNT(*) cnt FROM mes_morder WHERE tenant_id=@tenant_id AND morder_no LIKE 'M5000%';
+SELECT 'srm_pr_main' AS tbl, COUNT(*) cnt FROM srm_pr_main WHERE tenant_id=@tenant_id AND pr_billno LIKE 'PR-UAT-FULL-20260605-%';
+SELECT 'PurOrdMaster' AS tbl, COUNT(*) cnt FROM PurOrdMaster WHERE tenant_id=@tenant_id AND Remark LIKE CONCAT('%',@batch_no,'%');
+SELECT 'scm_shd' AS tbl, COUNT(*) cnt FROM scm_shd WHERE shddh LIKE 'SH-UAT-FULL-20260605-%';
+
+SELECT so.bill_no, COUNT(DISTINCT se.Id) line_cnt, COUNT(DISTINCT mo.Id) morder_cnt, COUNT(DISTINCT pom.PurOrd) po_cnt
+FROM crm_seorder so
+LEFT JOIN crm_seorderentry se ON se.seorder_id=so.Id AND se.tenant_id=@tenant_id
+LEFT JOIN mes_moentry me ON me.soentry_id=se.Id AND me.tenant_id=@tenant_id
+LEFT JOIN mes_morder mo ON mo.Id=me.moentry_moid AND mo.tenant_id=@tenant_id
+LEFT JOIN PurOrdMaster pom ON pom.SalesOrd=so.bill_no AND pom.tenant_id=@tenant_id
+LEFT JOIN PurOrdDetail pd ON pd.PurOrd=pom.PurOrd AND pd.tenant_id=@tenant_id
+WHERE so.tenant_id=@tenant_id AND so.bill_from LIKE CONCAT('UAT瀵煎叆:',@batch_no,'%')
+GROUP BY so.bill_no;
+

+ 300 - 0
doc/plan/sql/S1S4_UAT_P0_execute_write.sql

@@ -0,0 +1,300 @@
+-- S1-S4 P0 UAT write (AIDOP tenant 797403760988229)
+-- Batch: S1S4_UAT_20260604_RQ_V1
+
+SET @tenant_id     := 797403760988229;
+SET @batch_no      := 'S1S4_UAT_20260604_RQ_V1';
+SET @operator_id   := 1300000000111;
+SET @operator_name := 'UAT数据导入';
+SET @now           := NOW();
+SET @factory_id    := 797403760988229;
+SET @id_base       := 9106000400000001;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so;
+CREATE TEMPORARY TABLE tmp_s1_uat_so (
+    bill_no VARCHAR(64) NOT NULL PRIMARY KEY,
+    target_id BIGINT NOT NULL,
+    custom_no VARCHAR(64) NULL,
+    custom_name VARCHAR(128) NULL,
+    order_date DATETIME NULL,
+    delivery_date DATETIME NULL,
+    urgent INT DEFAULT 0
+);
+INSERT INTO tmp_s1_uat_so VALUES
+('MPO482024102300001',@id_base+1,'CUST0005','WKQXGFYXGE','2024-10-23','2024-10-23',1),
+('MPO482025010900002',@id_base+2,'CUST0005','WKQXGFYXGE','2025-01-09','2025-01-09',1),
+('MPO482024120200003',@id_base+3,'CUST0005','WKQXGFYXGE','2024-12-02','2024-12-02',1),
+('MPO482025012100001',@id_base+4,'CUST0005','WKQXGFYXGE','2025-01-21','2025-01-21',1),
+('MPO482025011300004',@id_base+5,'CUST0005','WKQXGFYXGE','2025-01-13','2025-01-13',1);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so_line;
+CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
+    target_id BIGINT NOT NULL PRIMARY KEY,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    entry_seq INT NOT NULL,
+    item_number VARCHAR(64) NULL,
+    qty DECIMAL(18,4) NULL,
+    plan_date DATETIME NULL
+);
+INSERT INTO tmp_s1_uat_so_line VALUES
+(@id_base+101,'604078133665861','MPO482024102300001',1,'3121C0035',1500,'2024-10-29'),
+(@id_base+102,'604078133665862','MPO482024102300001',2,'1A0C885',3500,'2024-10-29'),
+(@id_base+103,'631771616395333','MPO482025010900002',1,'3121C0035',850,'2025-01-18'),
+(@id_base+104,'631771616399429','MPO482025010900002',2,'3124C0015',850,'2025-01-21'),
+(@id_base+105,'618329124159557','MPO482024120200003',1,'1AB9275',800,'2024-12-03'),
+(@id_base+106,'636029208526917','MPO482025012100001',1,'91C0D2C',600,'2025-02-13'),
+(@id_base+107,'636029208526918','MPO482025012100001',2,'91CC0231',100,'2025-02-13'),
+(@id_base+108,'633180644831301','MPO482025011300004',1,'322AD001',5500,'2025-02-11'),
+(@id_base+109,'633180644831302','MPO482025011300004',2,'3221C0031',5500,'2025-02-18');
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s2_uat_morder;
+CREATE TEMPORARY TABLE tmp_s2_uat_morder (
+    target_mo_id BIGINT NOT NULL PRIMARY KEY,
+    target_me_id BIGINT NOT NULL,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    morder_no VARCHAR(128) NOT NULL,
+    product_code VARCHAR(128) NULL,
+    need_number DECIMAL(23,10) NULL
+);
+INSERT INTO tmp_s2_uat_morder VALUES
+(@id_base+201,@id_base+401,'604078133665861','MPO482024102300001','M500029406','32100035',1500),
+(@id_base+202,@id_base+402,'604078133665862','MPO482024102300001','M500029407','1000885',3500),
+(@id_base+203,@id_base+403,'631771616395333','MPO482025010900002','M500067189','32100035',850),
+(@id_base+204,@id_base+404,'631771616399429','MPO482025010900002','M500067190','32400015',850),
+(@id_base+205,@id_base+405,'618329124159557','MPO482024120200003','M500053856','1009275',800),
+(@id_base+206,@id_base+406,'636029208526917','MPO482025012100001','M500077552','93000230',600),
+(@id_base+207,@id_base+407,'636029208526918','MPO482025012100001','M500077553','93000231',100),
+(@id_base+208,@id_base+408,'633180644831301','MPO482025011300004','M500070779','32100001',5500),
+(@id_base+209,@id_base+409,'633180644831302','MPO482025011300004','M500070780','32100031',5500);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_pr;
+CREATE TEMPORARY TABLE tmp_s3_uat_pr (
+    voucher BIGINT NOT NULL PRIMARY KEY,
+    pr_billno VARCHAR(64) NOT NULL,
+    morder_no VARCHAR(128) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    icitem_code VARCHAR(64) NULL,
+    pr_rqty DECIMAL(18,4) NULL,
+    mo_id BIGINT NOT NULL
+);
+INSERT INTO tmp_s3_uat_pr VALUES
+(@id_base+501,'PR-UAT-20260604-01','M500029406','MPO482024102300001','32100035',1500,@id_base+201),
+(@id_base+502,'PR-UAT-20260604-02','M500029407','MPO482024102300001','1000885',3500,@id_base+202),
+(@id_base+503,'PR-UAT-20260604-03','M500067189','MPO482025010900002','32100035',850,@id_base+203),
+(@id_base+504,'PR-UAT-20260604-04','M500067190','MPO482025010900002','32400015',850,@id_base+204),
+(@id_base+505,'PR-UAT-20260604-05','M500053856','MPO482024120200003','1009275',800,@id_base+205),
+(@id_base+506,'PR-UAT-20260604-06','M500077552','MPO482025012100001','93000230',600,@id_base+206),
+(@id_base+507,'PR-UAT-20260604-07','M500077553','MPO482025012100001','93000231',100,@id_base+207),
+(@id_base+508,'PR-UAT-20260604-08','M500070779','MPO482025011300004','32100001',5500,@id_base+208),
+(@id_base+509,'PR-UAT-20260604-09','M500070780','MPO482025011300004','32100031',5500,@id_base+209);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_line;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_line (
+    pur_ord VARCHAR(48) NOT NULL,
+    line_no INT NOT NULL,
+    sales_ord VARCHAR(64) NOT NULL,
+    work_ord VARCHAR(128) NULL,
+    item_num VARCHAR(60) NOT NULL,
+    qty DECIMAL(15,5) NOT NULL,
+    PRIMARY KEY (pur_ord, line_no)
+);
+INSERT INTO tmp_s3_uat_po_line VALUES
+('PO-UAT-20260604-01',1,'MPO482024102300001','M500029406','3121C0035',1500),
+('PO-UAT-20260604-01',2,'MPO482024102300001','M500029407','1A0C885',3500),
+('PO-UAT-20260604-02',1,'MPO482025010900002','M500067189','3121C0035',850),
+('PO-UAT-20260604-02',2,'MPO482025010900002','M500067190','3124C0015',850),
+('PO-UAT-20260604-03',1,'MPO482024120200003','M500053856','1AB9275',800),
+('PO-UAT-20260604-03',2,'MPO482024120200003','M500053856','RAW-SUB-01',200),
+('PO-UAT-20260604-04',1,'MPO482025012100001','M500077552','91C0D2C',600),
+('PO-UAT-20260604-04',2,'MPO482025012100001','M500077553','91CC0231',100),
+('PO-UAT-20260604-05',1,'MPO482025011300004','M500070779','322AD001',5500),
+('PO-UAT-20260604-05',2,'MPO482025011300004','M500070780','3221C0031',5500);
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_hdr;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_hdr (
+    pur_ord VARCHAR(48) NOT NULL PRIMARY KEY,
+    sales_ord VARCHAR(64) NOT NULL,
+    work_ord VARCHAR(128) NULL
+);
+INSERT INTO tmp_s3_uat_po_hdr
+SELECT pur_ord, MIN(sales_ord), MIN(work_ord) FROM tmp_s3_uat_po_line GROUP BY pur_ord;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s4_uat_ship;
+CREATE TEMPORARY TABLE tmp_s4_uat_ship (
+    ship_id BIGINT NOT NULL PRIMARY KEY,
+    po_billno VARCHAR(48) NOT NULL,
+    shddh VARCHAR(64) NOT NULL
+);
+INSERT INTO tmp_s4_uat_ship VALUES
+(@id_base+601,'PO-UAT-20260604-01','SH-UAT-20260604-01'),
+(@id_base+602,'PO-UAT-20260604-02','SH-UAT-20260604-02'),
+(@id_base+603,'PO-UAT-20260604-03','SH-UAT-20260604-03');
+
+START TRANSACTION;
+
+INSERT INTO crm_seorder (
+    Id, bill_no, order_type, custom_no, custom_name,
+    date, rdate, urgent, bill_from, closed, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT target_id, bill_no, 1, custom_no, custom_name,
+       order_date, delivery_date, urgent,
+       CONCAT('UAT导入:', @batch_no), 0, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id
+FROM tmp_s1_uat_so;
+
+INSERT INTO crm_seorderentry (
+    Id, seorder_id, bill_no, entry_seq, item_number,
+    qty, plan_date, date, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id, seorderentry_id
+)
+SELECT l.target_id, s.target_id, l.bill_no, l.entry_seq, l.item_number,
+       l.qty, l.plan_date, s.order_date, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id, l.target_id
+FROM tmp_s1_uat_so_line l
+JOIN tmp_s1_uat_so s ON s.bill_no = l.bill_no;
+
+INSERT INTO mes_morder (
+    Id, morder_no, morder_date, morder_state, product_code, product_name,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT target_mo_id, morder_no, @now, 'Released', product_code, product_code,
+       need_number, need_number, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id
+FROM tmp_s2_uat_morder;
+
+INSERT INTO mes_moentry (
+    Id, moentry_moid, moentry_mono, soentry_id, fbill_no,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, tenant_id, factory_id
+)
+SELECT m.target_me_id, m.target_mo_id, m.morder_no, l.target_id, m.bill_no,
+       m.need_number, m.need_number, 0,
+       @operator_name, @now, @tenant_id, @factory_id
+FROM tmp_s2_uat_morder m
+JOIN tmp_s1_uat_so_line l ON l.source_entry = m.source_entry;
+
+INSERT INTO WorkOrdMaster (
+    Domain, WorkOrd, ItemNum, Status, QtyOrded, QtyCompleted, LbrVar,
+    OrdDate, DueDate, SalesJob, BusinessID, IsActive, IsConfirm, Priority, Urgent,
+    tenant_id, CreateTime, UpdateTime
+)
+SELECT '8010', morder_no, product_code, 'R',
+       need_number, 0, 0, @now, DATE_ADD(@now, INTERVAL 14 DAY), bill_no,
+       0, 1, 1, 0, 0, @tenant_id, @now, @now
+FROM tmp_s2_uat_morder;
+
+INSERT INTO srm_pr_main (
+    Id, pr_billno, pr_purchaseid, pr_purchasenumber, pr_purchasename,
+    pr_rqty, pr_aqty, pr_sqty, icitem_id, icitem_name,
+    state, pr_type, currencytype,
+    create_by, create_by_name, create_time, update_by, update_by_name, update_time,
+    tenant_id, factory_id, IsDeleted, IsRequireGoods
+)
+SELECT p.voucher, p.pr_billno, p.mo_id, p.morder_no, p.morder_no,
+       p.pr_rqty, 0, 0, 0, p.icitem_code,
+       1, 1, 0,
+       @operator_id, @operator_name, @now, @operator_id, @operator_name, @now,
+       @tenant_id, @factory_id, 0, 0
+FROM tmp_s3_uat_pr p;
+
+INSERT INTO PurOrdMaster (
+    OwnerApplication, APAcct, CostCtr, APSubAcct, Bank, BillTo, BlanketOrd, Buyer, CloseDate,
+    CommentIndex, Confirming, Consignment, Contact, Contract, CreditTermsInt, CreditTerms, Curr,
+    CycleCode, DeliverTo, Disc, Domain, DueDate, DutyType, BlanketStart, BlanketEnd, ExchRate,
+    ERSOption, EstVal, Sequence, ExchRate1, ExchRate2, RateType, FixedPrice, FixedRate, FOB, Frt,
+    FSMType, FSTID, InvoicesVia, EMTPO, Language, MaxAgingDays, PurOrd, OrdDate, PartialOK,
+    AmtPrepaid, LastPriceDt, PricingDate, PrintPO, Project, DiscTbl, PriceTbl, ERSPriceListOption,
+    PST, PSTID, Recurr, `Release`, Rel, ReqBy, Revision, Remark, Scheduled, SchedulesVia,
+    ServiceCharge, ShipTo, ShipVia, Site, SecondarySOCrHold, PrimarySO, SpecialCharge, Status,
+    Taxable, TaxClass, TaxDate, TaxEnvironment, Tax1, Tax2, Tax3, TaxUsage, TermsofTrade,
+    TransportDays, Typed, Ufld1, Ufld2, EnteredBy, Supp, Transm, BusinessID, CreateUser,
+    UpdateUser, CreateTime, UpdateTime, EffTime, IsActive, IsConfirm, Potype, Department,
+    IsChanged, TaxIn, Amt, `Usage`, CustAddress, CustContact, CustPhone, SalesOrd, CustPO,
+    IsPriceChanged, CustName, Rev, RoleNo, InvoiceType, PricingMethod, ERPfld1, ERPWorkOrd,
+    WorkOrd, tenant_id
+)
+SELECT
+    m.OwnerApplication, m.APAcct, m.CostCtr, m.APSubAcct, m.Bank, m.BillTo, m.BlanketOrd, @operator_name, m.CloseDate,
+    m.CommentIndex, m.Confirming, m.Consignment, m.Contact, m.Contract, m.CreditTermsInt, m.CreditTerms, m.Curr,
+    m.CycleCode, m.DeliverTo, m.Disc, m.Domain, m.DueDate, m.DutyType, m.BlanketStart, m.BlanketEnd, m.ExchRate,
+    m.ERSOption, m.EstVal, m.Sequence, m.ExchRate1, m.ExchRate2, m.RateType, m.FixedPrice, m.FixedRate, m.FOB, m.Frt,
+    m.FSMType, m.FSTID, m.InvoicesVia, m.EMTPO, m.Language, m.MaxAgingDays, h.pur_ord, @now, m.PartialOK,
+    m.AmtPrepaid, m.LastPriceDt, m.PricingDate, m.PrintPO, m.Project, m.DiscTbl, m.PriceTbl, m.ERSPriceListOption,
+    m.PST, m.PSTID, m.Recurr, m.`Release`, m.Rel, m.ReqBy, m.Revision, CONCAT('UAT:', @batch_no), m.Scheduled, m.SchedulesVia,
+    m.ServiceCharge, m.ShipTo, m.ShipVia, m.Site, m.SecondarySOCrHold, m.PrimarySO, m.SpecialCharge, m.Status,
+    m.Taxable, m.TaxClass, m.TaxDate, m.TaxEnvironment, m.Tax1, m.Tax2, m.Tax3, m.TaxUsage, m.TermsofTrade,
+    m.TransportDays, m.Typed, m.Ufld1, m.Ufld2, m.EnteredBy, 'VEN00060', m.Transm, m.BusinessID, @operator_name,
+    @operator_name, @now, @now, m.EffTime, m.IsActive, m.IsConfirm, 'PT', m.Department,
+    m.IsChanged, m.TaxIn, m.Amt, m.`Usage`, m.CustAddress, m.CustContact, m.CustPhone, h.sales_ord, m.CustPO,
+    m.IsPriceChanged, m.CustName, m.Rev, m.RoleNo, m.InvoiceType, m.PricingMethod, m.ERPfld1, m.ERPWorkOrd,
+    h.work_ord, @tenant_id
+FROM tmp_s3_uat_po_hdr h
+CROSS JOIN (SELECT * FROM PurOrdMaster WHERE PurOrd='PW202605100002' AND tenant_id=@tenant_id LIMIT 1) m;
+
+INSERT INTO PurOrdDetail (
+    QtyBO, RctCost, CreditTermsInt, UpdateCurrentCost, CumReceived1, CumReceived2, CumReceived3, CumReceived4,
+    Disc, FixedPrice, InspectReq, SingleLot, SupplyPer, PurOrd, PST, PackingSlipQty, PayUMConv, PurCost,
+    RctQty, QtyOrded, QtyReceived, QtyReturned, Active, QtyReleased, RctUMConversion, Scheduled, ScheduledChanged,
+    SchedMRPReq, SafetyDays, SafetyHours, StdCost, Taxable, TaxIn, MaxTaxableAmt, TransportHours, UMConversion, VAT,
+    IsActive, IsConfirm, Potype, IsChanged, TaxRate, IsRounding, ReceiptQty, BarCodeQty, IsClosed, QtyReturnedRefund, CumQtyBO,
+    Line, ItemNum, UM, DueDate, LotSerial, PurOrdRecID, Status, WorkOrd,
+    CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id
+)
+SELECT
+    0,0,0,0,0,0,0,0,0,0,0,0,0,pl.pur_ord,0,0,1,0,0,pl.qty,0,0,1,0,1,0,0,0,0,0,0,1,1,0,0,1,0,
+    1,1,'PT',0,0,0,0,0,0,0,0,
+    pl.line_no, pl.item_num, 'EA', DATE_ADD(@now, INTERVAL 14 DAY), '', 0, 'O', pl.work_ord,
+    @operator_name, @now, @operator_name, @now, @tenant_id
+FROM tmp_s3_uat_po_line pl;
+
+SET @ds_seq := 800;
+INSERT INTO srm_polist_ds (
+    Id, domain, icdsid, dsnum, status, itemnum, um, purgroup,
+    suppliercode, supplier, ponumber, poline, schedqty, needdate, remarks, tenant_id
+)
+SELECT
+    @id_base+(@ds_seq:=@ds_seq+1),
+    '8010', @id_base+800, CONCAT('DS-', pl.pur_ord, '-', pl.line_no),
+    'P', pl.item_num, 'EA', 'PG01', 'VEN00060', 'VEN00060',
+    pl.pur_ord, pl.line_no, pl.qty, DATE_ADD(@now, INTERVAL 14 DAY), '', @tenant_id
+FROM tmp_s3_uat_po_line pl
+CROSS JOIN (SELECT @ds_seq:=800) init;
+
+INSERT INTO scm_shd (id, po_billno, shddh, sh_purchase_num, estimated_delivery_date, tjrxm, tjrq, state)
+SELECT ship_id, po_billno, shddh, 'VEN00060', DATE_ADD(@now, INTERVAL 7 DAY), @operator_name, DATE_FORMAT(@now,'%Y-%m-%d'), 0
+FROM tmp_s4_uat_ship;
+
+SET @zb_seq := 700;
+INSERT INTO scm_shdzb (id, glid, sh_material_code, sh_delivery_quantity, po_bill, po_billline)
+SELECT @id_base+(@zb_seq:=@zb_seq+1), CAST(s.ship_id AS CHAR), pl.item_num, pl.qty, pl.pur_ord, CAST(pl.line_no AS CHAR)
+FROM tmp_s3_uat_po_line pl
+JOIN tmp_s4_uat_ship s ON s.po_billno = pl.pur_ord
+CROSS JOIN (SELECT @zb_seq:=700) init;
+
+COMMIT;
+
+SELECT 'crm_seorder' AS tbl, COUNT(*) cnt FROM crm_seorder WHERE tenant_id=@tenant_id AND bill_from LIKE CONCAT('UAT导入:',@batch_no,'%');
+SELECT 'crm_seorderentry' AS tbl, COUNT(*) cnt FROM crm_seorderentry WHERE tenant_id=@tenant_id AND bill_no IN (SELECT bill_no FROM tmp_s1_uat_so);
+SELECT 'mes_morder' AS tbl, COUNT(*) cnt FROM mes_morder WHERE tenant_id=@tenant_id AND morder_no LIKE 'M5000%';
+SELECT 'srm_pr_main' AS tbl, COUNT(*) cnt FROM srm_pr_main WHERE tenant_id=@tenant_id AND pr_billno LIKE 'PR-UAT-20260604-%';
+SELECT 'PurOrdMaster' AS tbl, COUNT(*) cnt FROM PurOrdMaster WHERE tenant_id=@tenant_id AND Remark LIKE CONCAT('%',@batch_no,'%');
+SELECT 'scm_shd' AS tbl, COUNT(*) cnt FROM scm_shd WHERE shddh LIKE 'SH-UAT-20260604-%';
+
+SELECT so.bill_no, COUNT(DISTINCT se.Id) line_cnt, COUNT(DISTINCT mo.Id) morder_cnt, COUNT(DISTINCT pom.PurOrd) po_cnt
+FROM crm_seorder so
+LEFT JOIN crm_seorderentry se ON se.seorder_id=so.Id AND se.tenant_id=@tenant_id
+LEFT JOIN mes_moentry me ON me.soentry_id=se.Id AND me.tenant_id=@tenant_id
+LEFT JOIN mes_morder mo ON mo.Id=me.moentry_moid AND mo.tenant_id=@tenant_id
+LEFT JOIN PurOrdMaster pom ON pom.SalesOrd=so.bill_no AND pom.tenant_id=@tenant_id
+LEFT JOIN PurOrdDetail pd ON pd.PurOrd=pom.PurOrd AND pd.tenant_id=@tenant_id
+WHERE so.tenant_id=@tenant_id AND so.bill_from LIKE CONCAT('UAT导入:',@batch_no,'%')
+GROUP BY so.bill_no;

+ 402 - 0
doc/plan/sql/S1S4_UAT_P0_试导SQL草案_20260604.sql

@@ -0,0 +1,402 @@
+-- =============================================================================
+-- S1-S4 全局 UAT P0 试导 SQL 草案
+-- 批次:S1S4_UAT_20260604_RQ_V1
+-- 租户:797403760988229(AIDOP)  |  禁止:1300000000888(Demo)
+-- 依据:doc/plan/S1-S4全局UAT场景测试数据生成方案.md
+--
+-- 【重要】第一阶段:Section 0 为只读检查(可执行);Section 1-4 为 DML 草案(默认注释)。
+--         正式写库前必须:① 从 dopdemorq 灌入 tmp_* 表  ② 人工审阅  ③ 取消注释后执行
+-- =============================================================================
+
+-- -----------------------------------------------------------------------------
+-- Section 0:只读检查(安全可执行)
+-- -----------------------------------------------------------------------------
+
+SET @tenant_aidop := 797403760988229;
+SET @tenant_demo  := 1300000000888;
+SET @batch_no     := 'S1S4_UAT_20260604_RQ_V1';
+
+-- 0.1 租户隔离:AIDOP vs Demo
+SELECT 'crm_seorder' AS tbl, tenant_id, COUNT(*) AS cnt
+FROM crm_seorder WHERE tenant_id IN (@tenant_aidop, @tenant_demo)
+GROUP BY tenant_id;
+
+SELECT 'mes_morder' AS tbl, tenant_id, COUNT(*) AS cnt
+FROM mes_morder WHERE tenant_id IN (@tenant_aidop, @tenant_demo)
+GROUP BY tenant_id;
+
+SELECT 'PurOrdMaster' AS tbl, tenant_id, COUNT(*) AS cnt
+FROM PurOrdMaster WHERE tenant_id IN (@tenant_aidop, @tenant_demo)
+GROUP BY tenant_id;
+
+-- 0.2 P0 单号冲突(应为空)
+SELECT bill_no, tenant_id, COUNT(*) AS cnt
+FROM crm_seorder
+WHERE bill_no IN (
+    'MPO482024102300001', 'MPO482025010900002', 'MPO482025012100001',
+    'MPO482024120200003', 'MPO482025010800003'
+)
+GROUP BY bill_no, tenant_id;
+
+-- 0.3 现有 AIDOP 主线(导入后用于对比,不应与 P0 批次混淆)
+SELECT bill_no, bill_from, custom_no, date
+FROM crm_seorder
+WHERE tenant_id = @tenant_aidop;
+
+-- 0.4 全局链路验收探针(导入后执行;当前仅结构预览)
+/*
+SELECT so.bill_no, COUNT(DISTINCT se.Id) AS line_cnt,
+       COUNT(DISTINCT mo.Id) AS morder_cnt,
+       COUNT(DISTINCT pm.PurOrd) AS po_cnt
+FROM crm_seorder so
+LEFT JOIN crm_seorderentry se ON se.seorder_id = so.Id AND se.tenant_id = @tenant_aidop
+LEFT JOIN mes_moentry me ON me.soentry_id = se.Id AND me.tenant_id = @tenant_aidop
+LEFT JOIN mes_morder mo ON mo.Id = me.moentry_moid AND mo.tenant_id = @tenant_aidop
+LEFT JOIN PurOrdMaster pom ON pom.SalesOrd = so.bill_no AND pom.tenant_id = @tenant_aidop
+LEFT JOIN PurOrdDetail pm ON pm.PurOrd = pom.PurOrd AND pm.tenant_id = @tenant_aidop
+WHERE so.tenant_id = @tenant_aidop
+  AND so.bill_from LIKE CONCAT('UAT导入:', @batch_no, '%')
+GROUP BY so.bill_no;
+*/
+
+
+-- -----------------------------------------------------------------------------
+-- Section 1:全局变量与 ID 映射(DML 草案 — 默认注释)
+-- -----------------------------------------------------------------------------
+
+/*
+SET @tenant_id    := 797403760988229;
+SET @batch_no     := 'S1S4_UAT_20260604_RQ_V1';
+SET @operator_id  := 1300000000111;
+SET @operator_name:= 'UAT数据导入';
+SET @now          := NOW();
+SET @factory_id   := 797403760988229;
+SET @id_base      := 9106000400000001;   -- 新 ID 基址,避开现有 800xxx 段
+
+-- 全局 ID 映射表(会话级)
+DROP TEMPORARY TABLE IF EXISTS tmp_s1s4_uat_id_map;
+CREATE TEMPORARY TABLE tmp_s1s4_uat_id_map (
+    batch_no    VARCHAR(64)  NOT NULL,
+    entity_name VARCHAR(64)  NOT NULL,
+    source_key  VARCHAR(128) NOT NULL,
+    target_id   BIGINT       NOT NULL,
+    ref_key     VARCHAR(128) NULL,
+    PRIMARY KEY (batch_no, entity_name, source_key)
+);
+
+-- P0 五单:销售订单 ID 预分配
+INSERT INTO tmp_s1s4_uat_id_map VALUES
+(@batch_no,'crm_seorder','MPO482024102300001',@id_base+1,'MPO482024102300001'),
+(@batch_no,'crm_seorder','MPO482025010900002',@id_base+2,'MPO482025010900002'),
+(@batch_no,'crm_seorder','MPO482025012100001',@id_base+3,'MPO482025012100001'),
+(@batch_no,'crm_seorder','MPO482024120200003',@id_base+4,'MPO482024120200003'),
+(@batch_no,'crm_seorder','MPO482025010800003',@id_base+5,'MPO482025010800003');
+
+-- 订单明细 ID:每单 2 行 => @id_base+101 .. +110
+-- 工单 ID:每明细 1 工单 => @id_base+201 .. +210
+-- 采购订单号:PO-UAT-001 .. PO-UAT-005
+*/
+
+
+-- -----------------------------------------------------------------------------
+-- Section 2:S1 销售订单(链路起点)
+-- -----------------------------------------------------------------------------
+
+/*
+-- 2.1 中间表:从 dopdemorq 抽取后灌入(字段为占位,须替换)
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so;
+CREATE TEMPORARY TABLE tmp_s1_uat_so (
+    bill_no      VARCHAR(64)  NOT NULL PRIMARY KEY,
+    target_id    BIGINT       NOT NULL,
+    custom_no    VARCHAR(64)  NULL,
+    custom_name  VARCHAR(128) NULL,
+    order_date   DATETIME     NULL,
+    delivery_date DATETIME    NULL,
+    urgent       INT          DEFAULT 0,
+    status       INT          DEFAULT 1
+);
+
+INSERT INTO tmp_s1_uat_so VALUES
+('MPO482024102300001', @id_base+1,  'CUST0005', 'ET0005', '2024-10-23', '2024-11-30', 0, 1),
+('MPO482025010900002', @id_base+2,  'CUST0005', 'ET0005', '2025-01-09', '2025-02-28', 0, 1),
+('MPO482025012100001', @id_base+3,  'CUST0005', 'ET0005', '2025-01-21', '2025-03-15', 1, 1),
+('MPO482024120200003', @id_base+4,  'CUST0005', 'ET0005', '2024-12-02', '2025-01-20', 0, 1),
+('MPO482025010800003', @id_base+5,  'CUST0005', 'ET0005', '2025-01-08', '2025-02-20', 0, 1);
+
+INSERT INTO crm_seorder (
+    Id, bill_no, order_type, custom_no, custom_name,
+    date, rdate, urgent, bill_from, closed, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT
+    target_id, bill_no, 1, custom_no, custom_name,
+    order_date, delivery_date, urgent,
+    CONCAT('UAT导入:', @batch_no),
+    0, 0,
+    @operator_name, @now, @operator_name, @now,
+    @tenant_id, @factory_id
+FROM tmp_s1_uat_so;
+
+-- 2.2 订单明细(每单 2 行;item_number/qty 须从旧库替换)
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so_line;
+CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
+    target_id       BIGINT NOT NULL PRIMARY KEY,
+    bill_no         VARCHAR(64) NOT NULL,
+    entry_seq       INT NOT NULL,
+    item_number     VARCHAR(64) NULL,
+    item_name       VARCHAR(128) NULL,
+    qty             DECIMAL(18,4) NULL,
+    plan_date       DATETIME NULL
+);
+
+-- 示例:MPO482024102300001 两行
+INSERT INTO tmp_s1_uat_so_line VALUES
+(@id_base+101,'MPO482024102300001',1,'ITEM-P0-01','成品A',100,'2024-11-15'),
+(@id_base+102,'MPO482024102300001',2,'ITEM-P0-02','成品B', 50,'2024-11-20');
+-- ... 其余 8 行按同模式从 dopdemorq 补全
+
+INSERT INTO crm_seorderentry (
+    Id, seorder_id, bill_no, entry_seq, item_number, item_name,
+    qty, plan_date, date, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id, seorderentry_id
+)
+SELECT
+    l.target_id, m.target_id, l.bill_no, l.entry_seq,
+    l.item_number, l.item_name, l.qty, l.plan_date, s.order_date, 0,
+    @operator_name, @now, @operator_name, @now,
+    @tenant_id, @factory_id, l.target_id
+FROM tmp_s1_uat_so_line l
+JOIN tmp_s1_uat_id_map m ON m.entity_name='crm_seorder' AND m.ref_key=l.bill_no AND m.batch_no=@batch_no
+JOIN tmp_s1_uat_so s ON s.bill_no = l.bill_no;
+*/
+
+
+-- -----------------------------------------------------------------------------
+-- Section 3:S2 工单(必须来源于 S1 订单明细)
+-- -----------------------------------------------------------------------------
+
+/*
+-- 3.1 mes_morder + mes_moentry:soentry_id 关联 crm_seorderentry.Id
+DROP TEMPORARY TABLE IF EXISTS tmp_s2_uat_morder;
+CREATE TEMPORARY TABLE tmp_s2_uat_morder (
+    target_mo_id    BIGINT NOT NULL PRIMARY KEY,
+    target_me_id    BIGINT NOT NULL,
+    soentry_id      BIGINT NOT NULL,
+    bill_no         VARCHAR(64) NOT NULL,
+    morder_no       VARCHAR(128) NOT NULL,
+    product_code    VARCHAR(128) NULL,
+    need_number     DECIMAL(23,10) NULL
+);
+
+INSERT INTO tmp_s2_uat_morder VALUES
+(@id_base+201, @id_base+301, @id_base+101, 'MPO482024102300001', 'WO-UAT-2024-001', 'ITEM-P0-01', 100),
+(@id_base+202, @id_base+302, @id_base+102, 'MPO482024102300001', 'WO-UAT-2024-002', 'ITEM-P0-02',  50);
+-- ... 其余 8 工单
+
+INSERT INTO mes_morder (
+    Id, morder_no, morder_date, morder_state, product_code, product_name,
+    need_number, morder_production_number, IsDeleted, urgent,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT
+    target_mo_id, morder_no, @now, 'Released', product_code, product_code,
+    need_number, need_number, 0, 0,
+    @operator_name, @now, @operator_name, @now,
+    @tenant_id, @factory_id
+FROM tmp_s2_uat_morder;
+
+INSERT INTO mes_moentry (
+    Id, moentry_moid, moentry_mono, soentry_id, fbill_no,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, tenant_id, factory_id
+)
+SELECT
+    target_me_id, target_mo_id, morder_no, soentry_id, bill_no,
+    need_number, need_number, 0,
+    @operator_name, @now, @tenant_id, @factory_id
+FROM tmp_s2_uat_morder;
+
+-- 3.2 WorkOrdMaster:供 S2 排程/日计划页(WorkOrd = morder_no)
+INSERT INTO WorkOrdMaster (
+    Domain, WorkOrd, ItemNum, Status, QtyOrded, QtyCompleted, LbrVar,
+    OrdDate, DueDate, SalesJob, tenant_id, CreateTime, UpdateTime
+)
+SELECT
+    CAST(@factory_id AS CHAR), morder_no, product_code, 'R',
+    need_number, 0, 0,
+    @now, DATE_ADD(@now, INTERVAL 14 DAY), bill_no,
+    @tenant_id, @now, @now
+FROM tmp_s2_uat_morder;
+*/
+
+
+-- -----------------------------------------------------------------------------
+-- Section 4:S3 物料需求 / 采购(必须来源于 S2 工单)
+-- -----------------------------------------------------------------------------
+
+/*
+-- 4.1 采购申请 srm_pr_main(每条工单至少 1 条缺料申请)
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_pr;
+CREATE TEMPORARY TABLE tmp_s3_uat_pr (
+    voucher         BIGINT NOT NULL PRIMARY KEY,
+    pr_billno       VARCHAR(64) NOT NULL,
+    morder_no       VARCHAR(128) NOT NULL,
+    icitem_name     VARCHAR(255) NULL,
+    pr_rqty         DECIMAL(18,4) NULL
+);
+
+INSERT INTO tmp_s3_uat_pr VALUES
+(@id_base+401, 'PR-UAT-001', 'WO-UAT-2024-001', '原料M1', 200),
+(@id_base+402, 'PR-UAT-002', 'WO-UAT-2024-001', '原料M2', 100);
+-- ... 按工单扩展
+
+INSERT INTO srm_pr_main (
+    voucher, Id, pr_billno, pr_purchaseid, pr_purchasenumber, pr_purchasename,
+    icitem_id, icitem_name, pr_rqty, pr_aqty, state, pr_type, currencytype,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id, IsDeleted, Remark
+)
+SELECT
+    voucher, voucher, pr_billno, 0, morder_no, morder_no,
+    0, icitem_name, pr_rqty, 0, 1, 1, 0,
+    @operator_name, @now, @operator_name, @now,
+    @tenant_id, @factory_id, 0, CONCAT('UAT:', @batch_no)
+FROM tmp_s3_uat_pr;
+
+-- 4.2 采购订单 PurOrdMaster / PurOrdDetail(SalesOrd + WorkOrd 回指 S1/S2)
+-- PO-UAT-001 关联 MPO482024102300001 + WO-UAT-2024-001
+INSERT INTO PurOrdMaster (
+    PurOrd, OrdDate, DueDate, Supp, Potype, Status, SalesOrd, WorkOrd,
+    Remark, Domain, tenant_id, CreateTime, UpdateTime,
+    Confirming, Consignment, CommentIndex, CreditTermsInt, Disc, ExchRate,
+    Sequence, ExchRate1, ExchRate2, FixedPrice, FixedRate, Frt, EMTPO,
+    MaxAgingDays, PartialOK, AmtPrepaid, PrintPO, ERSPriceListOption,
+    PST, Recurr, ReleaseFlag, Rel, Revision, Scheduled, Taxable,
+    BusinessID, IsActive, IsConfirm, IsChanged, TaxIn, Rev
+)
+VALUES (
+    'PO-UAT-001', @now, DATE_ADD(@now, INTERVAL 21 DAY), 'VEN00060', 'PT', 'O',
+    'MPO482024102300001', 'WO-UAT-2024-001',
+    CONCAT('UAT:', @batch_no), CAST(@factory_id AS CHAR), @tenant_id, @now, @now,
+    0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+);
+
+INSERT INTO PurOrdDetail (
+    PurOrd, Line, ItemNum, QtyOrded, DueDate, PurCost, Status,
+    Domain, tenant_id, CreateTime, UpdateTime,
+    QtyBO, CommentIndex, Consignment, CreditTermsInt, Disc, Op, ProjectLine,
+    ERSPriceListOption, ReqLine, Rel, NextReleaseID, PrimarySOLine,
+    Scheduled, ScheduledChanged, SchedMRPReq, ShipSchedWeeks, StdCost,
+    Taxable, TaxIn, MaxTaxableAmt, TransportHours, UMConversion, VAT,
+    BusinessID, IsActive, IsConfirm, Potype, IsChanged, TaxRate,
+    IsRounding, ReceiptQty, BarCodeQty, IsClosed, QtyReturnedRefund, CumQtyBO,
+    PurOrdRecID
+)
+VALUES
+('PO-UAT-001', 1, 'RAW-M1', 200, DATE_ADD(@now, INTERVAL 14 DAY), 10, 'O',
+ CAST(@factory_id AS CHAR), @tenant_id, @now, @now,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'PT',0,0,0,0,0,0,0,0,0,0),
+('PO-UAT-001', 2, 'RAW-M2', 100, DATE_ADD(@now, INTERVAL 14 DAY), 10, 'O',
+ CAST(@factory_id AS CHAR), @tenant_id, @now, @now,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'PT',0,0,0,0,0,0,0,0,0,0);
+
+-- 4.3 交货计划 srm_polist_ds(ponumber 指向 PurOrd)
+INSERT INTO srm_polist_ds (
+    Id, domain, icdsid, dsnum, status, itemnum, um, purgroup,
+    suppliercode, supplier, ponumber, poline, schedqty, needdate, tenant_id
+)
+VALUES
+(@id_base+501, CAST(@factory_id AS CHAR), @id_base+501, 'DS-UAT-001', 'P',
+ 'RAW-M1', 'EA', 'PG01', 'VEN00060', '供应商A', 'PO-UAT-001', 1, 200, DATE_ADD(@now, INTERVAL 14 DAY), @tenant_id),
+(@id_base+502, CAST(@factory_id AS CHAR), @id_base+502, 'DS-UAT-002', 'P',
+ 'RAW-M2', 'EA', 'PG01', 'VEN00060', '供应商A', 'PO-UAT-001', 2, 100, DATE_ADD(@now, INTERVAL 14 DAY), @tenant_id);
+*/
+
+
+-- -----------------------------------------------------------------------------
+-- Section 5:S4 交货 / 发货 / 退货(必须来源于 S3 采购订单)
+-- -----------------------------------------------------------------------------
+
+/*
+-- 5.1 供应商发货 scm_shd / scm_shdzb(po_billno = PurOrd)
+-- 注:scm_shd 表结构以 UAT 实库为准(可能无 tenant_id 列)
+INSERT INTO scm_shd (
+    id, po_billno, shddh, sh_purchase_num, sh_purchase_name,
+    estimated_delivery_date, tjrxm, tjrq
+)
+VALUES (
+    @id_base+601, 'PO-UAT-001', 'SH-UAT-001', 'VEN00060', '供应商A',
+    DATE_ADD(@now, INTERVAL 7 DAY), @operator_name, DATE_FORMAT(@now,'%Y-%m-%d')
+);
+
+INSERT INTO scm_shdzb (
+    id, glid, sh_material_code, sh_material_name,
+    sh_delivery_quantity, po_bill, po_line
+)
+VALUES
+(@id_base+701, CAST(@id_base+601 AS CHAR), 'RAW-M1', '原料M1', 200, 'PO-UAT-001', '1'),
+(@id_base+702, CAST(@id_base+601 AS CHAR), 'RAW-M2', '原料M2', 100, 'PO-UAT-001', '2');
+
+-- 5.2 采购退货 PurOrdRctMaster(OrdNbr 指向 PurOrd;IQC 不合格样例)
+INSERT INTO PurOrdRctMaster (
+    Receiver, OrdNbr, Supp, RctDate, Status, Remark, tenant_id, CreateTime
+)
+VALUES (
+    'RT-UAT-001', 'PO-UAT-001', 'VEN00060', @now, 'O',
+    CONCAT('UAT IQC退货:', @batch_no), @tenant_id, @now
+);
+*/
+
+
+-- -----------------------------------------------------------------------------
+-- Section 6:导入后串联验收 SQL(只读,导入完成后执行)
+-- -----------------------------------------------------------------------------
+
+-- 6.1 租户合规:不得出现 Demo 租户新数据
+SELECT 'crm_seorder_demo' AS chk, COUNT(*) AS cnt
+FROM crm_seorder
+WHERE tenant_id = @tenant_demo
+  AND bill_from LIKE CONCAT('UAT导入:', @batch_no, '%');
+
+-- 6.2 S1→S2:每单明细至少 1 工单
+SELECT so.bill_no,
+       COUNT(DISTINCT se.Id)  AS line_cnt,
+       COUNT(DISTINCT mo.Id)  AS morder_cnt
+FROM crm_seorder so
+JOIN crm_seorderentry se
+  ON se.seorder_id = so.Id AND se.tenant_id = @tenant_aidop AND se.IsDeleted = 0
+LEFT JOIN mes_moentry me
+  ON me.soentry_id = se.Id AND me.tenant_id = @tenant_aidop AND me.IsDeleted = 0
+LEFT JOIN mes_morder mo
+  ON mo.Id = me.moentry_moid AND mo.tenant_id = @tenant_aidop AND mo.IsDeleted = 0
+WHERE so.tenant_id = @tenant_aidop
+  AND so.bill_from LIKE CONCAT('UAT导入:', @batch_no, '%')
+GROUP BY so.bill_no;
+
+-- 6.3 S2→S3:工单能找到采购申请
+SELECT mo.morder_no, COUNT(pr.voucher) AS pr_cnt
+FROM mes_morder mo
+LEFT JOIN srm_pr_main pr
+  ON pr.pr_purchasenumber = mo.morder_no AND pr.tenant_id = @tenant_aidop
+WHERE mo.tenant_id = @tenant_aidop
+  AND mo.morder_no LIKE 'WO-UAT-%'
+GROUP BY mo.morder_no;
+
+-- 6.4 S3→S4:采购订单能找到发货单(scm_shd 当前无 tenant_id,按 po_billno 关联)
+SELECT pom.PurOrd, COUNT(sh.id) AS ship_cnt
+FROM PurOrdMaster pom
+LEFT JOIN scm_shd sh ON sh.po_billno = pom.PurOrd
+WHERE pom.tenant_id = @tenant_aidop
+  AND pom.Remark LIKE CONCAT('%', @batch_no, '%')
+GROUP BY pom.PurOrd;
+
+-- 6.5 KPI 探针(MDP 跑批后)
+SELECT module_code, metric_code, COUNT(*) AS rows_count, MAX(biz_date) AS latest_biz_date
+FROM ado_s9_kpi_value_l1_day
+WHERE module_code IN ('S1','S2','S3','S4')
+  AND is_deleted = 0
+GROUP BY module_code, metric_code
+ORDER BY module_code, metric_code;

+ 271 - 0
doc/plan/sql/S1S4_UAT_P0_试导数据填充_20260604.sql

@@ -0,0 +1,271 @@
+-- =============================================================================
+-- S1-S4 P0 试导数据填充(dopdemorq 实抽 → tmp 表)
+-- 批次:S1S4_UAT_20260604_RQ_V1 | 租户:797403760988229
+-- 抽数记录:doc/plan/S1S4_UAT_P0_抽数记录_20260604.md
+--
+-- 用法:
+--   1) 仅验证 tmp:执行 Section A(含末尾 ROLLBACK 的试跑块)
+--   2) 正式写库:人工确认后执行 Section B(取消注释),勿执行 ROLLBACK
+-- =============================================================================
+
+-- -----------------------------------------------------------------------------
+-- Section A:变量 + 映射 + tmp 实数据(可先单独执行到 SELECT 校验)
+-- -----------------------------------------------------------------------------
+
+SET @tenant_id     := 797403760988229;
+SET @batch_no      := 'S1S4_UAT_20260604_RQ_V1';
+SET @operator_id   := 1300000000111;
+SET @operator_name := 'UAT数据导入';
+SET @now           := NOW();
+SET @factory_id    := 797403760988229;
+SET @id_base       := 9106000400000001;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1s4_uat_id_map;
+CREATE TEMPORARY TABLE tmp_s1s4_uat_id_map (
+    batch_no     VARCHAR(64)  NOT NULL,
+    entity_name  VARCHAR(64)  NOT NULL,
+    source_key   VARCHAR(128) NOT NULL,
+    target_id    BIGINT       NOT NULL,
+    ref_key      VARCHAR(128) NULL,
+    PRIMARY KEY (batch_no, entity_name, source_key)
+);
+
+-- 销售订单(5 单;第 5 单用 MPO482025011300004 替换不存在的 010800003)
+INSERT INTO tmp_s1s4_uat_id_map (batch_no, entity_name, source_key, target_id, ref_key) VALUES
+(@batch_no,'crm_seorder','MPO482024102300001',@id_base+1,'MPO482024102300001'),
+(@batch_no,'crm_seorder','MPO482025010900002',@id_base+2,'MPO482025010900002'),
+(@batch_no,'crm_seorder','MPO482024120200003',@id_base+3,'MPO482024120200003'),
+(@batch_no,'crm_seorder','MPO482025012100001',@id_base+4,'MPO482025012100001'),
+(@batch_no,'crm_seorder','MPO482025011300004',@id_base+5,'MPO482025011300004');
+
+-- 订单明细(旧库 soentry Id → 新 Id)
+INSERT INTO tmp_s1s4_uat_id_map VALUES
+(@batch_no,'crm_seorderentry','604078133665861',@id_base+101,'MPO482024102300001'),
+(@batch_no,'crm_seorderentry','604078133665862',@id_base+102,'MPO482024102300001'),
+(@batch_no,'crm_seorderentry','631771616395333',@id_base+103,'MPO482025010900002'),
+(@batch_no,'crm_seorderentry','631771616399429',@id_base+104,'MPO482025010900002'),
+(@batch_no,'crm_seorderentry','618329124159557',@id_base+105,'MPO482024120200003'),
+(@batch_no,'crm_seorderentry','636029208526917',@id_base+106,'MPO482025012100001'),
+(@batch_no,'crm_seorderentry','636029208526918',@id_base+107,'MPO482025012100001'),
+(@batch_no,'crm_seorderentry','633180644831301',@id_base+108,'MPO482025011300004'),
+(@batch_no,'crm_seorderentry','633180644831302',@id_base+109,'MPO482025011300004');
+
+-- 工单(保留旧库 morder_no 作 ref_key)
+INSERT INTO tmp_s1s4_uat_id_map VALUES
+(@batch_no,'mes_morder','M500029406',@id_base+201,'604078133665861'),
+(@batch_no,'mes_morder','M500029407',@id_base+202,'604078133665862'),
+(@batch_no,'mes_morder','M500067189',@id_base+203,'631771616395333'),
+(@batch_no,'mes_morder','M500067190',@id_base+204,'631771616399429'),
+(@batch_no,'mes_morder','M500053856',@id_base+205,'618329124159557'),
+(@batch_no,'mes_morder','M500077552',@id_base+206,'636029208526917'),
+(@batch_no,'mes_morder','M500077553',@id_base+207,'636029208526918'),
+(@batch_no,'mes_morder','M500070779',@id_base+208,'633180644831301'),
+(@batch_no,'mes_morder','M500070780',@id_base+209,'633180644831302');
+
+-- 采购订单(合成 PO,按销售订单分组)
+INSERT INTO tmp_s1s4_uat_id_map VALUES
+(@batch_no,'PurOrdMaster','PO-UAT-20260604-01',@id_base+301,'MPO482024102300001'),
+(@batch_no,'PurOrdMaster','PO-UAT-20260604-02',@id_base+302,'MPO482025010900002'),
+(@batch_no,'PurOrdMaster','PO-UAT-20260604-03',@id_base+303,'MPO482024120200003'),
+(@batch_no,'PurOrdMaster','PO-UAT-20260604-04',@id_base+304,'MPO482025012100001'),
+(@batch_no,'PurOrdMaster','PO-UAT-20260604-05',@id_base+305,'MPO482025011300004');
+
+-- S1 订单头
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so;
+CREATE TEMPORARY TABLE tmp_s1_uat_so (
+    bill_no       VARCHAR(64) NOT NULL PRIMARY KEY,
+    target_id     BIGINT NOT NULL,
+    custom_no     VARCHAR(64) NULL,
+    custom_name   VARCHAR(128) NULL,
+    order_date    DATETIME NULL,
+    delivery_date DATETIME NULL,
+    urgent        INT DEFAULT 0
+);
+INSERT INTO tmp_s1_uat_so VALUES
+('MPO482024102300001',@id_base+1,'CUST0005','WKQXGFYXGE','2024-10-23','2024-10-23',1),
+('MPO482025010900002',@id_base+2,'CUST0005','WKQXGFYXGE','2025-01-09','2025-01-09',1),
+('MPO482024120200003',@id_base+3,'CUST0005','WKQXGFYXGE','2024-12-02','2024-12-02',1),
+('MPO482025012100001',@id_base+4,'CUST0005','WKQXGFYXGE','2025-01-21','2025-01-21',1),
+('MPO482025011300004',@id_base+5,'CUST0005','WKQXGFYXGE','2025-01-13','2025-01-13',1);
+
+-- S1 订单明细(dopdemorq 实抽)
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so_line;
+CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
+    target_id    BIGINT NOT NULL PRIMARY KEY,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no      VARCHAR(64) NOT NULL,
+    entry_seq    INT NOT NULL,
+    item_number  VARCHAR(64) NULL,
+    qty          DECIMAL(18,4) NULL,
+    plan_date    DATETIME NULL
+);
+INSERT INTO tmp_s1_uat_so_line VALUES
+(@id_base+101,'604078133665861','MPO482024102300001',1,'3121C0035',1500,'2024-10-29 00:00:00'),
+(@id_base+102,'604078133665862','MPO482024102300001',2,'1A0C885',3500,'2024-10-29 00:00:00'),
+(@id_base+103,'631771616395333','MPO482025010900002',1,'3121C0035',850,'2025-01-18 00:00:00'),
+(@id_base+104,'631771616399429','MPO482025010900002',2,'3124C0015',850,'2025-01-21 00:00:00'),
+(@id_base+105,'618329124159557','MPO482024120200003',1,'1AB9275',800,'2024-12-03 00:00:00'),
+(@id_base+106,'636029208526917','MPO482025012100001',1,'91C0D2C',600,'2025-02-13 00:00:00'),
+(@id_base+107,'636029208526918','MPO482025012100001',2,'91CC0231',100,'2025-02-13 00:00:00'),
+(@id_base+108,'633180644831301','MPO482025011300004',1,'322AD001',5500,'2025-02-11 00:00:00'),
+(@id_base+109,'633180644831302','MPO482025011300004',2,'3221C0031',5500,'2025-02-18 00:00:00');
+
+-- S2 工单(dopdemorq 实抽)
+DROP TEMPORARY TABLE IF EXISTS tmp_s2_uat_morder;
+CREATE TEMPORARY TABLE tmp_s2_uat_morder (
+    target_mo_id  BIGINT NOT NULL PRIMARY KEY,
+    target_me_id  BIGINT NOT NULL,
+    source_entry  VARCHAR(32) NOT NULL,
+    bill_no       VARCHAR(64) NOT NULL,
+    morder_no     VARCHAR(128) NOT NULL,
+    product_code  VARCHAR(128) NULL,
+    need_number   DECIMAL(23,10) NULL
+);
+INSERT INTO tmp_s2_uat_morder VALUES
+(@id_base+201,@id_base+401,'604078133665861','MPO482024102300001','M500029406','32100035',1500),
+(@id_base+202,@id_base+402,'604078133665862','MPO482024102300001','M500029407','1000885',3500),
+(@id_base+203,@id_base+403,'631771616395333','MPO482025010900002','M500067189','32100035',850),
+(@id_base+204,@id_base+404,'631771616399429','MPO482025010900002','M500067190','32400015',850),
+(@id_base+205,@id_base+405,'618329124159557','MPO482024120200003','M500053856','1009275',800),
+(@id_base+206,@id_base+406,'636029208526917','MPO482025012100001','M500077552','93000230',600),
+(@id_base+207,@id_base+407,'636029208526918','MPO482025012100001','M500077553','93000231',100),
+(@id_base+208,@id_base+408,'633180644831301','MPO482025011300004','M500070779','32100001',5500),
+(@id_base+209,@id_base+409,'633180644831302','MPO482025011300004','M500070780','32100031',5500);
+
+-- S3 采购申请(每工单 1 条,物料编码取工单 product_code)
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_pr;
+CREATE TEMPORARY TABLE tmp_s3_uat_pr (
+    voucher       BIGINT NOT NULL PRIMARY KEY,
+    pr_billno     VARCHAR(64) NOT NULL,
+    morder_no     VARCHAR(128) NOT NULL,
+    bill_no       VARCHAR(64) NOT NULL,
+    icitem_code   VARCHAR(64) NULL,
+    pr_rqty       DECIMAL(18,4) NULL
+);
+INSERT INTO tmp_s3_uat_pr VALUES
+(@id_base+501,'PR-UAT-20260604-01','M500029406','MPO482024102300001','32100035',1500),
+(@id_base+502,'PR-UAT-20260604-02','M500029407','MPO482024102300001','1000885',3500),
+(@id_base+503,'PR-UAT-20260604-03','M500067189','MPO482025010900002','32100035',850),
+(@id_base+504,'PR-UAT-20260604-04','M500067190','MPO482025010900002','32400015',850),
+(@id_base+505,'PR-UAT-20260604-05','M500053856','MPO482024120200003','1009275',800),
+(@id_base+506,'PR-UAT-20260604-06','M500077552','MPO482025012100001','93000230',600),
+(@id_base+507,'PR-UAT-20260604-07','M500077553','MPO482025012100001','93000231',100),
+(@id_base+508,'PR-UAT-20260604-08','M500070779','MPO482025011300004','32100001',5500),
+(@id_base+509,'PR-UAT-20260604-09','M500070780','MPO482025011300004','32100031',5500);
+
+-- S3 采购订单行(每 PO 2 行:成品料号 + 原料占位)
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_line;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_line (
+    pur_ord    VARCHAR(48) NOT NULL,
+    line_no    INT NOT NULL,
+    sales_ord  VARCHAR(64) NOT NULL,
+    work_ord   VARCHAR(128) NULL,
+    item_num   VARCHAR(60) NOT NULL,
+    qty        DECIMAL(15,5) NOT NULL,
+    PRIMARY KEY (pur_ord, line_no)
+);
+INSERT INTO tmp_s3_uat_po_line VALUES
+('PO-UAT-20260604-01',1,'MPO482024102300001','M500029406','3121C0035',1500),
+('PO-UAT-20260604-01',2,'MPO482024102300001','M500029407','1A0C885',3500),
+('PO-UAT-20260604-02',1,'MPO482025010900002','M500067189','3121C0035',850),
+('PO-UAT-20260604-02',2,'MPO482025010900002','M500067190','3124C0015',850),
+('PO-UAT-20260604-03',1,'MPO482024120200003','M500053856','1AB9275',800),
+('PO-UAT-20260604-03',2,'MPO482024120200003','M500053856','RAW-SUB-01',200),
+('PO-UAT-20260604-04',1,'MPO482025012100001','M500077552','91C0D2C',600),
+('PO-UAT-20260604-04',2,'MPO482025012100001','M500077553','91CC0231',100),
+('PO-UAT-20260604-05',1,'MPO482025011300004','M500070779','322AD001',5500),
+('PO-UAT-20260604-05',2,'MPO482025011300004','M500070780','3221C0031',5500);
+
+-- S4 发货(3 张,覆盖前 3 个 PO)
+DROP TEMPORARY TABLE IF EXISTS tmp_s4_uat_ship;
+CREATE TEMPORARY TABLE tmp_s4_uat_ship (
+    ship_id     BIGINT NOT NULL PRIMARY KEY,
+    po_billno   VARCHAR(48) NOT NULL,
+    shddh       VARCHAR(64) NOT NULL,
+    supp_code   VARCHAR(32) NOT NULL
+);
+INSERT INTO tmp_s4_uat_ship VALUES
+(@id_base+601,'PO-UAT-20260604-01','SH-UAT-20260604-01','VEN00060'),
+(@id_base+602,'PO-UAT-20260604-02','SH-UAT-20260604-02','VEN00060'),
+(@id_base+603,'PO-UAT-20260604-03','SH-UAT-20260604-03','VEN00060');
+
+-- A.1 tmp 链路自检(只读)
+SELECT 'tmp_so' AS chk, COUNT(*) AS cnt FROM tmp_s1_uat_so;
+SELECT 'tmp_line' AS chk, COUNT(*) AS cnt FROM tmp_s1_uat_so_line;
+SELECT 'tmp_morder' AS chk, COUNT(*) AS cnt FROM tmp_s2_uat_morder;
+SELECT l.bill_no, l.item_number, m.morder_no, m.need_number
+FROM tmp_s1_uat_so_line l
+JOIN tmp_s2_uat_morder m ON m.source_entry = l.source_entry
+ORDER BY l.bill_no, l.entry_seq;
+
+
+-- -----------------------------------------------------------------------------
+-- Section B:正式写入业务表(默认注释 — 确认后取消整段注释)
+-- -----------------------------------------------------------------------------
+
+/*
+START TRANSACTION;
+
+INSERT INTO crm_seorder (
+    Id, bill_no, order_type, custom_no, custom_name,
+    date, rdate, urgent, bill_from, closed, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT target_id, bill_no, 1, custom_no, custom_name,
+       order_date, delivery_date, urgent,
+       CONCAT('UAT导入:', @batch_no), 0, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id
+FROM tmp_s1_uat_so;
+
+INSERT INTO crm_seorderentry (
+    Id, seorder_id, bill_no, entry_seq, item_number,
+    qty, plan_date, date, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id, seorderentry_id
+)
+SELECT l.target_id, s.target_id, l.bill_no, l.entry_seq, l.item_number,
+       l.qty, l.plan_date, s.order_date, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id, l.target_id
+FROM tmp_s1_uat_so_line l
+JOIN tmp_s1_uat_so s ON s.bill_no = l.bill_no;
+
+INSERT INTO mes_morder (
+    Id, morder_no, morder_date, morder_state, product_code, product_name,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, update_by_name, update_time,
+    tenant_id, factory_id
+)
+SELECT target_mo_id, morder_no, @now, 'Released', product_code, product_code,
+       need_number, need_number, 0,
+       @operator_name, @now, @operator_name, @now,
+       @tenant_id, @factory_id
+FROM tmp_s2_uat_morder;
+
+INSERT INTO mes_moentry (
+    Id, moentry_moid, moentry_mono, soentry_id, fbill_no,
+    need_number, morder_production_number, IsDeleted,
+    create_by_name, create_time, tenant_id, factory_id
+)
+SELECT m.target_me_id, m.target_mo_id, m.morder_no, l.target_id, m.bill_no,
+       m.need_number, m.need_number, 0,
+       @operator_name, @now, @tenant_id, @factory_id
+FROM tmp_s2_uat_morder m
+JOIN tmp_s1_uat_so_line l ON l.source_entry = m.source_entry;
+
+INSERT INTO WorkOrdMaster (
+    Domain, WorkOrd, ItemNum, Status, QtyOrded, QtyCompleted, LbrVar,
+    OrdDate, DueDate, SalesJob, tenant_id, CreateTime, UpdateTime
+)
+SELECT CAST(@factory_id AS CHAR), morder_no, product_code, 'R',
+       need_number, 0, 0, @now, DATE_ADD(@now, INTERVAL 14 DAY), bill_no,
+       @tenant_id, @now, @now
+FROM tmp_s2_uat_morder;
+
+-- PurOrdMaster / Detail / srm_pr_main / scm_shd 等见 S1S4_UAT_P0_试导SQL草案_20260604.sql Section 4-5
+-- 执行前请核对 PurOrdDetail 必填默认值
+
+COMMIT;
+*/

+ 22 - 0
doc/plan/sql/S1S4_UAT_P0补发货_PO04_PO05.sql

@@ -0,0 +1,22 @@
+-- 补 S4 发货单:PO-UAT-20260604-04 / PO-UAT-20260604-05
+SET @tenant_id := 797403760988229;
+SET @id_base := 9106000400000001;
+SET @operator_name := 'UAT数据导入';
+SET @now := NOW();
+
+INSERT INTO scm_shd (id, po_billno, shddh, sh_purchase_num, estimated_delivery_date, tjrxm, tjrq, state)
+VALUES
+(@id_base+604, 'PO-UAT-20260604-04', 'SH-UAT-20260604-04', 'VEN00060', DATE_ADD(@now, INTERVAL 7 DAY), @operator_name, DATE_FORMAT(@now,'%Y-%m-%d'), 0),
+(@id_base+605, 'PO-UAT-20260604-05', 'SH-UAT-20260604-05', 'VEN00060', DATE_ADD(@now, INTERVAL 7 DAY), @operator_name, DATE_FORMAT(@now,'%Y-%m-%d'), 0);
+
+INSERT INTO scm_shdzb (id, glid, sh_material_code, sh_delivery_quantity, po_bill, po_billline)
+SELECT @id_base+707, CAST(@id_base+604 AS CHAR), '91C0D2C', 600, 'PO-UAT-20260604-04', '1'
+UNION ALL SELECT @id_base+708, CAST(@id_base+604 AS CHAR), '91CC0231', 100, 'PO-UAT-20260604-04', '2'
+UNION ALL SELECT @id_base+709, CAST(@id_base+605 AS CHAR), '322AD001', 5500, 'PO-UAT-20260604-05', '1'
+UNION ALL SELECT @id_base+710, CAST(@id_base+605 AS CHAR), '3221C0031', 5500, 'PO-UAT-20260604-05', '2';
+
+SELECT pom.PurOrd, COUNT(sh.id) ship_cnt
+FROM PurOrdMaster pom
+LEFT JOIN scm_shd sh ON sh.po_billno = pom.PurOrd
+WHERE pom.tenant_id = @tenant_id AND pom.PurOrd LIKE 'PO-UAT-20260604-%'
+GROUP BY pom.PurOrd ORDER BY pom.PurOrd;

+ 27 - 0
doc/plan/sql/S1S4_UAT_S1_mdp_entity_product_design_20260605.sql

@@ -0,0 +1,27 @@
+-- S1 MDP 补登记:产品设计三实体(与 S1MdpEntityConfig 对齐)
+-- 目标库:aidopdev,tenant_id=0,source_code=AIDOPDEV_MYSQL
+SET @tenant_id := 0;
+SET @source_id := (SELECT id FROM mdp_source WHERE tenant_id = @tenant_id AND source_code = 'AIDOPDEV_MYSQL' LIMIT 1);
+
+INSERT INTO mdp_entity
+(tenant_id, source_id, entity_code, entity_name, entity_type, source_table_name, target_table_name, sync_mode, incr_column, batch_size, status, remark)
+VALUES
+(@tenant_id, @source_id, 'S1_PRODUCT_DESIGN', 'S1产品设计主表', 'TABLE', 'ado_product_design', 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, '产品设计主表,进入订单标准层'),
+(@tenant_id, @source_id, 'S1_PRODUCT_DESIGN_BOM', 'S1产品设计BOM', 'TABLE', 'ado_product_design_bom', 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, '产品设计BOM,进入订单标准层'),
+(@tenant_id, @source_id, 'S1_PRODUCT_DESIGN_ROUTING', 'S1产品设计工艺路线', 'TABLE', 'ado_product_design_routing', 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, '产品设计工艺路线,进入订单标准层')
+ON DUPLICATE KEY UPDATE
+    source_id = VALUES(source_id),
+    entity_name = VALUES(entity_name),
+    entity_type = VALUES(entity_type),
+    source_table_name = VALUES(source_table_name),
+    target_table_name = VALUES(target_table_name),
+    sync_mode = VALUES(sync_mode),
+    incr_column = VALUES(incr_column),
+    batch_size = VALUES(batch_size),
+    status = VALUES(status),
+    remark = VALUES(remark),
+    update_time = CURRENT_TIMESTAMP;
+
+SELECT entity_code, source_table_name, status
+FROM mdp_entity
+WHERE entity_code IN ('S1_PRODUCT_DESIGN', 'S1_PRODUCT_DESIGN_BOM', 'S1_PRODUCT_DESIGN_ROUTING');

+ 105 - 0
doc/plan/sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql

@@ -0,0 +1,105 @@
+-- 将已导入的 S1-S4 UAT 数据从 tenant_id=1300000000001 迁至 AIDOP 租户 797403760988229
+-- 状态:2026-06-05 已在 aidopdev 执行成功(crm_seorder 50 条 @797403760988229)
+-- 幂等:仅更新仍留在旧租户且带 S1S4_UAT 批次标记的数据
+
+SET @old_tid  := 1300000000001;
+SET @new_tid  := 797403760988229;
+SET @factory  := 797403760988229;
+
+START TRANSACTION;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_uat_bills;
+CREATE TEMPORARY TABLE tmp_uat_bills AS
+SELECT bill_no, Id AS so_id
+FROM crm_seorder
+WHERE tenant_id = @old_tid
+  AND bill_from LIKE '%S1S4_UAT%';
+
+DROP TEMPORARY TABLE IF EXISTS tmp_uat_pos;
+CREATE TEMPORARY TABLE tmp_uat_pos AS
+SELECT DISTINCT PurOrd
+FROM PurOrdMaster
+WHERE tenant_id = @old_tid
+  AND (Remark LIKE '%S1S4_UAT%' OR SalesOrd IN (SELECT bill_no FROM tmp_uat_bills));
+
+DROP TEMPORARY TABLE IF EXISTS tmp_uat_mo;
+CREATE TEMPORARY TABLE tmp_uat_mo AS
+SELECT DISTINCT mo.Id AS mo_id, mo.morder_no
+FROM mes_morder mo
+INNER JOIN mes_moentry me ON me.moentry_moid = mo.Id AND me.tenant_id = @old_tid
+INNER JOIN crm_seorderentry se ON se.Id = me.soentry_id
+WHERE se.bill_no IN (SELECT bill_no FROM tmp_uat_bills)
+  AND mo.tenant_id = @old_tid;
+
+UPDATE crm_seorder
+SET tenant_id = @new_tid, factory_id = @factory
+WHERE tenant_id = @old_tid
+  AND bill_from LIKE '%S1S4_UAT%';
+
+UPDATE crm_seorderentry e
+INNER JOIN tmp_uat_bills b ON e.bill_no = b.bill_no
+SET e.tenant_id = @new_tid, e.factory_id = @factory
+WHERE e.tenant_id = @old_tid;
+
+UPDATE mes_moentry me
+INNER JOIN crm_seorderentry se ON se.Id = me.soentry_id
+INNER JOIN tmp_uat_bills b ON se.bill_no = b.bill_no
+SET me.tenant_id = @new_tid, me.factory_id = @factory
+WHERE me.tenant_id = @old_tid;
+
+UPDATE mes_morder mo
+INNER JOIN tmp_uat_mo t ON mo.Id = t.mo_id
+SET mo.tenant_id = @new_tid, mo.factory_id = @factory
+WHERE mo.tenant_id = @old_tid;
+
+UPDATE WorkOrdMaster w
+SET w.tenant_id = @new_tid
+WHERE w.tenant_id = @old_tid
+  AND (w.SalesJob IN (SELECT bill_no FROM tmp_uat_bills)
+       OR w.WorkOrd IN (SELECT morder_no FROM tmp_uat_mo));
+
+UPDATE srm_pr_main
+SET tenant_id = @new_tid, factory_id = @factory
+WHERE tenant_id = @old_tid
+  AND pr_billno LIKE 'PR-UAT-%';
+
+UPDATE PurOrdMaster
+SET tenant_id = @new_tid
+WHERE tenant_id = @old_tid
+  AND PurOrd IN (SELECT PurOrd FROM tmp_uat_pos);
+
+UPDATE PurOrdDetail pd
+INNER JOIN tmp_uat_pos p ON pd.PurOrd = p.PurOrd
+SET pd.tenant_id = @new_tid
+WHERE pd.tenant_id = @old_tid;
+
+UPDATE srm_polist_ds
+SET tenant_id = @new_tid
+WHERE tenant_id = @old_tid
+  AND ponumber LIKE 'PO-UAT-%';
+
+UPDATE mdp_std_so
+SET tenant_id = @new_tid
+WHERE tenant_id = @old_tid
+  AND order_no IN (SELECT bill_no FROM tmp_uat_bills);
+
+UPDATE dwd_ship_trans
+SET tenant_id = @new_tid
+WHERE tenant_id = @old_tid
+  AND order_no IN (SELECT bill_no FROM tmp_uat_bills);
+
+UPDATE dwd_order_schedule_trans
+SET tenant_id = @new_tid
+WHERE tenant_id = @old_tid
+  AND sales_order_no IN (SELECT bill_no FROM tmp_uat_bills);
+
+COMMIT;
+
+SELECT tenant_id, COUNT(*) AS so_cnt
+FROM crm_seorder
+WHERE bill_from LIKE '%S1S4_UAT%'
+GROUP BY tenant_id;
+
+SELECT COUNT(*) AS aidop_uat_so
+FROM crm_seorder
+WHERE tenant_id = @new_tid AND bill_from LIKE '%S1S4_UAT%';

+ 629 - 0
doc/plan/sql/_extract_full.tsv

@@ -0,0 +1,629 @@
+SO|MPO482024102400001|604438174724165||WKQXGFYXGE|NULL|1
+SO|MPO482024120200001|618270138114117||WKQXGFYXGE|NULL|0
+SO|MPO482024120200002|618290059870277||WKQXGFYXGE|NULL|0
+SO|MPO482024120400002|619057592856645||WKQXGFYXGE|NULL|0
+SO|MPO482025010700001|630994141876293||WKQXGFYXGE|NULL|1
+SO|MPO482025010700002|631069572898885||WKQXGFYXGE|NULL|1
+SO|MPO482025010900001|631769475362885||WKQXGFYXGE|NULL|1
+SO|MPO482025011000001|632121330212933||WKQXGFYXGE|NULL|1
+SO|MPO482025011000002|632124505305157||WKQXGFYXGE|NULL|1
+SO|MPO482025011000003|632125638139973||WKQXGFYXGE|NULL|1
+SO|MPO482025011300002|633173728645189||WKQXGFYXGE|NULL|1
+SO|MPO482025011300003|633178117517381||WKQXGFYXGE|NULL|1
+SO|MPO482025011300005|633197800923205||WKQXGFYXGE|NULL|1
+SO|MPO482025011300006|633206942003269||WKQXGFYXGE|NULL|1
+SO|MPO482025011400001|633515236827205||WKQXGFYXGE|NULL|1
+SO|MPO482025011400002|633520967856197||WKQXGFYXGE|NULL|1
+SO|MPO482025022100001|646977498820677||WKQXGFYXGE|2025-02-26 00:00:00.000|1
+SO|MPO482025032900001|659719948849221||WKQXGFYXGE|NULL|0
+SO|MPO482025041300001|665010080100421||WKQXGFYXGE|NULL|0
+SO|MPO482025042800001|670272718237765||WKQXGFYXGE|NULL|0
+SO|MPO482025051800001|677416088444997||WKQXGFYXGE|NULL|0
+SO|MPO482025062100002|689366514073669||WKQXGFYXGE|NULL|0
+SO|MPO482025062100003|689369826627653||WKQXGFYXGE|NULL|0
+SO|MPO482025062600003|691329579536453||WKQXGFYXGE|NULL|0
+SO|MPO482025081500001|708842855108677||WKQXGFYXGE|NULL|0
+SO|MPO482025081500002|708853129998405||WKQXGFYXGE|NULL|0
+SO|MPO482025082900002|713850858373189||WKQXGFYXGE|NULL|0
+SO|MPO482025090400005|716009093087301||WKQXGFYXGE|NULL|0
+SO|MPO482025091800003|720949559136325||WKQXGFYXGE|NULL|0
+SO|MPO482025091900001|721256686583877||WKQXGFYXGE|NULL|0
+SO|MPO482025092200002|722351549325381||WKQXGFYXGE|NULL|0
+SO|MPO482026012100001|765148659920965|||2026-01-21 00:00:00.000|0
+SO|MPO482026020300001|769809189359685|10000000|Èð±´µÂ|2026-02-03 00:00:00.000|0
+SO|SO241020240923001|1958480382326104094|CUST0005|ET0005|2024-09-23 00:00:00.000|0
+SO|SO241020241014001|1958480382326104264|CUST0005|ET0005|2024-10-14 00:00:00.000|0
+SO|SO241020241015003|1958480382326104285|CUST0005|ET0005|2024-10-15 00:00:00.000|0
+SO|SO241020241018001|1958902016386269184|CUST0005|ET0005|2024-10-18 00:00:00.000|0
+SO|SO241020241019001|1958956122157088768|CUST0005|ET0005|2024-10-19 00:00:00.000|0
+SO|SO241020241021002|1959718646913695744|CUST0005|ET0005|2024-10-21 00:00:00.000|0
+SO|SO241020241022001|1960006795304894464|CUST0005|ET0005|2024-10-22 00:00:00.000|0
+SO|SO241020241102001|1963915047889534976|CUST0005|ET0005|2024-11-02 00:00:00.000|0
+SO|SO241020241102004|1963971671127752704|CUST0005|ET0005|2024-11-02 00:00:00.000|0
+SO|SO241020241104001|1964653664643579904|CUST0005|ET0005|2024-11-04 00:00:00.000|0
+SO|SO241020241219001|1981045424231809024|CUST0005|ET0005|2024-12-19 00:00:00.000|0
+SO|SO241020250114003|1990491416446369792|CUST0005|ET0005|2025-01-14 00:00:00.000|0
+LINE|MPO482024102400001|604438178041925|1|91DC0292|4500.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178041926|2|1A03D23|3500.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178046021|3|1A0C329|400000.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178046022|4|1A0C655|100000.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178046023|5|A2C7114|250000.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178046024|6|A2C7115|600000.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178050117|7|A2B4199|6000.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178050118|8|1A0C588|10000.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178050119|9|1A03G94|2500.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178050120|10|91CC0286|1500.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024102400001|604438178054213|11|91DC0218|800.00000000|2024-10-31 00:00:00.000
+LINE|MPO482024120200001|618270140751941|1|91CC0229|60.00000000|2024-12-06 00:00:00.000
+LINE|MPO482024120200002|618290062549061|1|91DC0218|2000.00000000|2024-12-30 00:00:00.000
+LINE|MPO482024120400002|619057595396165|1|91CC0237|200.00000000|2024-12-12 00:00:00.000
+LINE|MPO482025010700001|630994145116229|1|A2C7114|250000.00000000|2025-01-10 00:00:00.000
+LINE|MPO482025010700002|631069575503941|1|1A0C329|100000.00000000|2025-01-15 00:00:00.000
+LINE|MPO482025010900001|631769478479941|1|91CC0312|500.00000000|2025-01-24 00:00:00.000
+LINE|MPO482025010900001|631769478479942|2|1A03D23|600.00000000|2025-01-14 00:00:00.000
+LINE|MPO482025010900001|631769478484037|3|91CC0231|100.00000000|2025-01-23 00:00:00.000
+LINE|MPO482025010900001|631769478484038|4|91CC0286|800.00000000|2025-02-06 00:00:00.000
+LINE|MPO482025011000001|632121332793413|1|91C0D058|400.00000000|2025-02-05 00:00:00.000
+LINE|MPO482025011000002|632124508205125|1|A2B8361|1000.00000000|2025-02-05 00:00:00.000
+LINE|MPO482025011000003|632125640785989|1|A2B8184|700.00000000|2025-02-05 00:00:00.000
+LINE|MPO482025011300002|633173731577925|1|A2B4199|4000.00000000|2025-02-17 00:00:00.000
+LINE|MPO482025011300003|633178120278085|1|1A03D23|5000.00000000|2025-02-27 00:00:00.000
+LINE|MPO482025011300005|633197803688005|1|ABC431|10000.00000000|2025-02-27 00:00:00.000
+LINE|MPO482025011300005|633197803688006|2|1A0C432|10000.00000000|2025-02-27 00:00:00.000
+LINE|MPO482025011300006|633206945230917|1|ABC419|35000.00000000|2025-02-17 00:00:00.000
+LINE|MPO482025011400001|633515239526469|1|1A0C293|650000.00000000|2025-02-27 00:00:00.000
+LINE|MPO482025011400001|633515239526470|2|1A0C329|200000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025011400002|633520970641477|1|91DC0215|1500.00000000|2025-02-28 00:00:00.000
+LINE|MPO482025022100001|646977501577285|1|91CC0179|5000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025022100001|646977501577286|2|91CC0287|10000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025022100001|646977501581381|3|91CC0288|10000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025022100001|646977501581382|4|91CC0187|5000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025022100001|646977501581383|5|91CC0233|1500.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025022100001|646977501581384|6|91DC0218|3000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025022100001|646977501581385|7|A21C096|10000.00000000|2025-02-26 00:00:00.000
+LINE|MPO482025032900001|659719952244805|1|91CC0177|5000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025032900001|659719952244806|2|91CC0179|5000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025032900001|659719952248901|3|91CC0287|4000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025032900001|659719952248902|4|91DC0217|2000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025032900001|659719952248903|5|91DC0219|9000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025032900001|659719952248904|6|91C0D2D|2000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025032900001|659719952252997|7|AB47111|200000.00000000|2025-04-03 00:00:00.000
+LINE|MPO482025041300001|665010090852421|1|352AD0A|1.00000000|2025-04-18 00:00:00.000
+LINE|MPO482025041300001|665010090852422|2|3521C0014|1.00000000|2025-04-18 00:00:00.000
+LINE|MPO482025041300001|665010090852423|3|3151C0033|1.00000000|2025-04-18 00:00:00.000
+LINE|MPO482025041300001|665010090856517|4|3151C0034|1.00000000|2025-04-18 00:00:00.000
+LINE|MPO482025042800001|670272721616965|1|3221C0031|7000.00000000|2025-04-30 00:00:00.000
+LINE|MPO482025051800001|677416091480133|1|3521C0015|1.00000000|2025-05-23 00:00:00.000
+LINE|MPO482025051800001|677416091480134|2|3521C0015|1.00000000|2025-05-23 00:00:00.000
+LINE|MPO482025051800001|677416091480135|3|3521C0015|1.00000000|2025-05-23 00:00:00.000
+LINE|MPO482025051800001|677416091480136|4|3521C0015|1.00000000|2025-05-23 00:00:00.000
+LINE|MPO482025051800001|677416091480137|5|3521C0015|1.00000000|2025-05-28 00:00:00.000
+LINE|MPO482025051800001|677416091484229|6|3521C0015|1.00000000|2025-05-28 00:00:00.000
+LINE|MPO482025051800001|677416091484230|7|3521C0015|1.00000000|2025-05-28 00:00:00.000
+LINE|MPO482025051800001|677416091484231|8|3521C0015|1.00000000|2025-05-28 00:00:00.000
+LINE|MPO482025051800001|677416091484232|9|3521C0015|1.00000000|2025-05-28 00:00:00.000
+LINE|MPO482025051800001|677416091484233|10|3521C0015|1.00000000|2025-05-28 00:00:00.000
+LINE|MPO482025062100002|689366516133957|1|3151C0034|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516133958|2|3151C0034|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516133959|3|3151C0034|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516138053|4|3151C0034|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516138054|5|3151C0034|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516138055|6|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516138056|7|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516142149|8|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516142150|9|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516142151|10|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516142152|11|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100002|689366516142153|12|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829818437|1|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829818438|2|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829818439|3|3521C0016|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829818440|4|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829822533|5|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829822534|6|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829822535|7|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829822536|8|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829826629|9|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829826630|10|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829826631|11|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829826632|12|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062100003|689369829826633|13|352AD0A|1.00000000|2025-06-27 00:00:00.000
+LINE|MPO482025062600003|691329582436421|1|91CC0178|4000.00000000|2025-07-04 00:00:00.000
+LINE|MPO482025062600003|691329582436422|2|91CC0285|2000.00000000|2025-07-04 00:00:00.000
+LINE|MPO482025062600003|691329582436423|3|91CC0286|4000.00000000|2025-07-04 00:00:00.000
+LINE|MPO482025062600003|691329582440517|4|A2B8361|4000.00000000|2025-07-04 00:00:00.000
+LINE|MPO482025081500001|708842858610757|1|1A0C273|200.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500001|708842858610758|2|1A0C275|272.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500001|708842858610759|3|1A004C4|960000.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500001|708842858610760|4|ABC419|1000.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500001|708842858610761|5|ABC431|2000.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500001|708842858610762|6|1A0C432|1000.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500001|708842858610763|7|1A0C588|29000.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500001|708842858614853|8|1A0C595|670000.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500001|708842858614854|9|AB32A4|111.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132763205|1|A21C092|550.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132763206|2|A21C093|60.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132763207|3|91B0D033|38.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132767301|4|91C0D058|558.00000000|2025-08-22 00:00:00.000
+LINE|MPO482025081500002|708853132767302|5|91C0D074|2522.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500002|708853132767303|6|91C0DA8|69.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132771397|7|93B0D1A|185.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132771398|8|91CC0123|2.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132771399|9|91CC0229|862.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132771400|10|91CC0262|200.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132771401|11|91CC0286|3000.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132775493|12|91CC0312|300.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132775494|13|91C0DD4|100.00000000|2025-08-22 00:00:00.000
+LINE|MPO482025081500002|708853132775495|14|91CC0412|58.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132775496|15|91C0DE2|400.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132775497|16|91C0DE3|1050.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132779589|17|91C0DE6|400.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132779590|18|91C0DE7|1000.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500002|708853132779591|19|91C0DE9|350.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132779592|20|91C0D5A|1100.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500002|708853132779593|21|91CC0518|1250.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132783685|22|91CC0521|3000.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132783686|23|91CC0524|1500.00000000|2025-08-29 00:00:00.000
+LINE|MPO482025081500002|708853132783687|24|91CC0525|3000.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132783688|25|91FC0339|600.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132783689|26|1AB9259|5000.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500002|708853132783690|27|3124C0015|8000.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132787781|28|3151C0032|1.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132787782|29|1A0C452|1000.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132787783|30|1A03G82|3000.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132787784|31|91CC0319|160000.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132787785|32|AB37A2|16000.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132791877|33|91CC0248|500.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132791878|34|91C00EN|60000.00000000|2025-08-21 00:00:00.000
+LINE|MPO482025081500002|708853132791879|35|AB37A3|130000.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132791880|36|91CC0517|100.00000000|2025-08-28 00:00:00.000
+LINE|MPO482025081500002|708853132791881|37|3151C0034|1.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500002|708853132791882|38|3151C0034|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132791883|39|3151C0034|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132791884|40|3151C0034|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132791885|41|3151C0034|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132795973|42|3151C0033|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132795974|43|3151C0033|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132795975|44|3151C0033|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132795976|45|3151C0033|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132795977|46|3151C0033|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132795978|47|3151C0033|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132795979|48|3151C0033|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132795980|49|3151C0033|1.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500002|708853132795981|50|3521C0015|1.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500002|708853132795982|51|3521C0015|1.00000000|2025-08-19 00:00:00.000
+LINE|MPO482025081500002|708853132795983|52|3521C0015|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132800069|53|3521C0015|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132800070|54|3521C0015|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132800071|55|3521C0015|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132800072|56|3521C0015|1.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500002|708853132800073|57|3521C0015|1.00000000|2025-08-20 00:00:00.000
+LINE|MPO482025081500002|708853132800074|58|3521C0015|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132800075|59|3521C0015|1.00000000|2025-08-27 00:00:00.000
+LINE|MPO482025081500002|708853132800076|60|3521C0015|1.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025081500002|708853132800077|61|3521C0015|1.00000000|2025-08-19 00:00:00.000
+LINE|MPO482025081500002|708853132804165|62|3521C0015|1.00000000|2025-08-26 00:00:00.000
+LINE|MPO482025082900002|713850861281349|1|91C0D2G|5000.00000000|2025-08-31 00:00:00.000
+LINE|MPO482025082900002|713850861281350|2|93BC0311|510.00000000|2025-08-30 00:00:00.000
+LINE|MPO482025082900002|713850861281351|3|91CC0312|500.00000000|2025-08-30 00:00:00.000
+LINE|MPO482025082900002|713850861285445|4|91CC0233|400.00000000|2025-08-30 00:00:00.000
+LINE|MPO482025082900002|713850861285446|5|91CC0232|1500.00000000|2025-08-30 00:00:00.000
+LINE|MPO482025090400005|716009096228933|1|91CC0312|5000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025090400005|716009096228934|2|93BC0311|5000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091800003|720949568118853|1|91CC0483|1900.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091800003|720949568118854|2|91CC0312|100.00000000|2025-09-25 00:00:00.000
+LINE|MPO482025091800003|720949568118855|3|93BC0311|600.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091800003|720949568122949|4|91CC0313|100.00000000|2025-09-29 00:00:00.000
+LINE|MPO482025091800003|720949568122950|5|91CC0229|700.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689414213|1|91CC0182|10000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689414214|2|312CD009|10000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689414215|3|3123C0012|10000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689414216|4|3123C0026|3000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689414217|5|3123C0027|3000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689418309|6|3123C0028|3000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689418310|7|3123C0035|10000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689418311|8|3123C0046|3000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689422405|9|3123C0047|3000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689422406|10|3123C0048|3000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689422407|11|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689422408|12|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689426501|13|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689426502|14|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689426503|15|3521C0016|1.00000000|2025-09-24 00:00:00.000
+LINE|MPO482025091900001|721256689426504|16|3521C0016|1.00000000|2025-09-25 00:00:00.000
+LINE|MPO482025091900001|721256689426505|17|3521C0016|1.00000000|2025-09-25 00:00:00.000
+LINE|MPO482025091900001|721256689430597|18|3521C0016|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689430598|19|3521C0016|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689430599|20|3521C0016|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689430600|21|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689434693|22|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689434694|23|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689434695|24|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689434696|25|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689438789|26|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025091900001|721256689438790|27|3521C0015|1.00000000|2025-09-30 00:00:00.000
+LINE|MPO482025092200002|722351552172101|1|91CC0283|20000.00000000|2025-09-30 00:00:00.000
+LINE|MPO482026012100001|765148661813317|1|1A0044F|1000.00000000|2026-01-25 00:00:00.000
+LINE|MPO482026012100001|765148661813318|2|1A0045H|1000.00000000|2026-01-25 00:00:00.000
+LINE|MPO482026012100001|765148661813319|3|1A0047E|1000.00000000|2026-01-25 00:00:00.000
+LINE|MPO482026020300001|769809191923781|1|1A0044F|100.00000000|2026-02-09 00:00:00.000
+LINE|SO241020240923001|1958480382326104095|1|91CC0232|400.00000000|2024-09-23 17:36:13.000
+LINE|SO241020240923001|1958480382326104096|2|91CC0287|567.00000000|2024-09-23 17:36:23.000
+LINE|SO241020240923001|1958480382326104097|3|91CC0288|256.00000000|2024-09-23 17:36:38.000
+LINE|SO241020240923001|1958480382326104098|4|91C0D3A|400.00000000|2024-09-23 17:36:55.000
+LINE|SO241020240923001|1958480382326104099|5|91CC0312|590.00000000|2024-09-23 17:37:10.000
+LINE|SO241020240923001|1958480382326104100|6|91DC0219|1216.00000000|2024-09-23 17:37:40.000
+LINE|SO241020240923001|1958480382326104101|7|91DC0284|1104.00000000|2024-09-23 17:37:58.000
+LINE|SO241020240923001|1958480382326104102|8|91DC0292|1415.00000000|2024-09-23 17:38:21.000
+LINE|SO241020240923001|1958480382326104103|9|91C0DC8|1200.00000000|2024-09-23 17:53:47.000
+LINE|SO241020240923001|1958480382326104104|10|1A03D23|511.00000000|2024-09-23 17:54:41.000
+LINE|SO241020240923001|1958480382326104105|11|91CC0228|1695.00000000|2024-09-23 17:54:51.000
+LINE|SO241020240923001|1958480382326104106|12|91DC0213|210.00000000|2024-09-24 09:07:26.000
+LINE|SO241020241014001|1958480382326104265|1|AB04C1|100.00000000|2024-10-14 16:24:39.000
+LINE|SO241020241014001|1958480382326104266|2|1AB2737|66.00000000|2024-10-14 16:24:52.000
+LINE|SO241020241014001|1958480382326104267|3|A2B5613|190.00000000|2024-10-14 16:25:17.000
+LINE|SO241020241014001|1958480382326104268|4|1A03G94|83.00000000|2024-10-14 16:25:40.000
+LINE|SO241020241014001|1958480382326104269|5|1A03G96|4208.00000000|2024-10-14 16:25:51.000
+LINE|SO241020241014001|1958480382326104270|6|AB37A2|1000.00000000|2024-10-14 16:26:17.000
+LINE|SO241020241014001|1958480382326104271|7|A2C7113|115000.00000000|2024-10-14 16:26:36.000
+LINE|SO241020241014001|1958480382326104272|8|A2C7114|120000.00000000|2024-10-14 16:28:00.000
+LINE|SO241020241014001|1958480382326104273|9|A2C7115|280000.00000000|2024-10-14 16:28:17.000
+LINE|SO241020241014001|1958480382326104274|10|A2C7116|10000.00000000|2024-10-14 16:28:31.000
+LINE|SO241020241014001|1958480382326104275|11|A2C7117|30000.00000000|2024-10-14 16:28:44.000
+LINE|SO241020241014001|1958480382326104276|12|A2B8361|400.00000000|2024-10-14 16:29:26.000
+LINE|SO241020241014001|1958480382326104277|13|1AB9259|418.00000000|2024-10-14 16:29:43.000
+LINE|SO241020241014001|1958480382326104278|14|A21C096|1088.00000000|2024-10-14 16:30:04.000
+LINE|SO241020241014001|1958480382326104279|15|91C0D058|300.00000000|2024-10-14 16:30:25.000
+LINE|SO241020241014001|1958480382326104280|16|91CC0283|1107.00000000|2024-10-14 16:30:41.000
+LINE|SO241020241015003|1958480382326104286|1|91CC0229|1000.00000000|2024-10-15 17:40:11.000
+LINE|SO241020241015003|1958480382326104287|2|91FC0339|600.00000000|2024-10-15 17:40:33.000
+LINE|SO241020241015003|1958480382326104288|3|91CC0319|7000.00000000|2024-10-15 17:40:45.000
+LINE|SO241020241015003|1958480382326104289|4|91DC0284|1635.00000000|2024-10-15 17:40:58.000
+LINE|SO241020241015003|1958480382326104290|5|91DC0219|975.00000000|2024-10-15 17:41:16.000
+LINE|SO241020241015003|1958480382326104291|6|91CC0283|368.00000000|2024-10-15 17:41:28.000
+LINE|SO241020241015003|1958480382326104292|7|1A03G96|822.00000000|2024-10-15 17:41:41.000
+LINE|SO241020241015003|1958480382326104293|8|91C0D2G|1200.00000000|2024-10-15 17:41:54.000
+LINE|SO241020241015003|1958480382326104294|9|1A03G82|10000.00000000|2024-10-15 17:42:06.000
+LINE|SO241020241015003|1958480382326104295|10|ABC431|6614.00000000|2024-10-15 17:42:20.000
+LINE|SO241020241015003|1958480382326104296|11|1A0C432|7810.00000000|2024-10-15 17:42:33.000
+LINE|SO241020241015003|1958480382326104297|12|1A0387B|341.00000000|2024-10-15 17:42:48.000
+LINE|SO241020241015003|1958480382326104298|13|91C0DC8|400.00000000|2024-10-15 17:43:01.000
+LINE|SO241020241015003|1958480382326104299|14|1A03D23|958.00000000|2024-10-15 17:43:24.000
+LINE|SO241020241015003|1958480382326104300|15|91CC0235|200.00000000|2024-10-15 17:43:37.000
+LINE|SO241020241015003|1958480382326104301|16|91CC0179|300.00000000|2024-10-15 17:43:54.000
+LINE|SO241020241018001|1958902016386269185|1|91C0DC9|280.00000000|2024-10-18 17:34:58.000
+LINE|SO241020241018001|1958902016386269186|2|ABC431|4000.00000000|2024-10-18 17:35:20.000
+LINE|SO241020241018001|1958902016386269187|3|1A0C432|4200.00000000|2024-10-18 17:35:29.000
+LINE|SO241020241018001|1958902016386269188|4|1A0C595|200000.00000000|2024-10-18 17:35:44.000
+LINE|SO241020241018001|1958902016386269189|5|1A0C689|400.00000000|2024-10-18 17:36:00.000
+LINE|SO241020241018001|1958902016386269190|6|1AB2755|101.00000000|2024-10-18 17:36:12.000
+LINE|SO241020241018001|1958902016386269191|7|AB3D14|50000.00000000|2024-10-18 17:36:23.000
+LINE|SO241020241018001|1958902016386269192|8|A2B5613|1783.00000000|2024-10-18 17:36:38.000
+LINE|SO241020241018001|1958902016386269193|9|1A03G96|1473.00000000|2024-10-18 17:36:50.000
+LINE|SO241020241018001|1958902016386269194|10|91DC0214|600.00000000|2024-10-18 17:37:10.000
+LINE|SO241020241018001|1958902016386269195|11|91DC0219|202.00000000|2024-10-18 17:37:23.000
+LINE|SO241020241018001|1958902016386269196|12|AB3B81|256.00000000|2024-10-18 17:38:03.000
+LINE|SO241020241018001|1958902016386269197|13|91CC0177|81.00000000|2024-10-18 17:38:14.000
+LINE|SO241020241018001|1958902016386269198|14|91C0D2D|400.00000000|2024-10-18 17:38:28.000
+LINE|SO241020241018001|1958902016386269199|15|91CC0283|1044.00000000|2024-10-18 17:38:38.000
+LINE|SO241020241018001|1958902016386269200|16|91CC0236|400.00000000|2024-10-18 17:38:50.000
+LINE|SO241020241018001|1958902016386269201|17|91DC0284|1082.00000000|2024-10-18 17:39:00.000
+LINE|SO241020241018001|1958902016386269202|18|91DC0292|202.00000000|2024-10-18 17:39:14.000
+LINE|SO241020241019001|1958956122157088769|1|91CC0187|54.00000000|2024-10-19 16:25:13.000
+LINE|SO241020241019001|1958956122157088770|2|91FC0339|11.00000000|2024-10-19 16:25:29.000
+LINE|SO241020241019001|1958956122157088771|3|91CC0228|131.00000000|2024-10-19 16:25:40.000
+LINE|SO241020241019001|1958956122157088772|4|91C0D051|1.00000000|2024-10-19 16:25:52.000
+LINE|SO241020241019001|1958956122157088773|5|A21C092|15.00000000|2024-10-19 16:25:59.000
+LINE|SO241020241021002|1959718646913695745|1|1A039D8|350.00000000|2024-10-21 18:33:52.000
+LINE|SO241020241021002|1959718646913695746|2|91CC0283|716.00000000|2024-10-21 18:34:04.000
+LINE|SO241020241021002|1959718646913695747|3|91DC0292|967.00000000|2024-10-21 18:34:17.000
+LINE|SO241020241021002|1959718646917890048|4|91DC0284|640.00000000|2024-10-21 18:53:13.000
+LINE|SO241020241021002|1959718646917890049|5|1A03D23|1134.00000000|2024-10-21 18:53:36.000
+LINE|SO241020241021002|1959718646917890050|6|91CC0229|1800.00000000|2024-10-21 18:53:49.000
+LINE|SO241020241021002|1959718646917890051|7|91CC0241|200.00000000|2024-10-21 18:54:00.000
+LINE|SO241020241021002|1959718646917890052|8|91CC0278|70.00000000|2024-10-21 18:54:18.000
+LINE|SO241020241021002|1959718646917890053|9|91DC0215|587.00000000|2024-10-21 19:38:04.000
+LINE|SO241020241021002|1959729971345752064|10|91DC0215|587.00000000|2024-10-21 19:38:04.000
+LINE|SO241020241022001|1960006795304894465|1|91CC0235|600.00000000|2024-10-22 14:01:07.000
+LINE|SO241020241102001|1963915047889534977|1|91CC0287|313.00000000|2024-11-02 08:44:39.000
+LINE|SO241020241102001|1963915047889534978|2|91CC0288|454.00000000|2024-11-02 08:44:50.000
+LINE|SO241020241102001|1963915047889534979|3|91CC0319|340.00000000|2024-11-02 08:45:03.000
+LINE|SO241020241102001|1963915047889534980|4|91FC0339|900.00000000|2024-11-02 08:45:17.000
+LINE|SO241020241102001|1963915047889534981|5|91DC0284|813.00000000|2024-11-02 08:45:28.000
+LINE|SO241020241102001|1963915047889534982|6|91DC0218|180.00000000|2024-11-02 08:45:41.000
+LINE|SO241020241102001|1963915047889534983|7|91DC0219|92.00000000|2024-11-02 08:45:54.000
+LINE|SO241020241102001|1963915047889534984|8|91CC0234|200.00000000|2024-11-02 08:46:06.000
+LINE|SO241020241102001|1963915047889534985|9|AB3B81|218.00000000|2024-11-02 08:46:33.000
+LINE|SO241020241102004|1963971671127752705|1|A2B4199|1596.00000000|2024-11-02 12:32:48.000
+LINE|SO241020241102004|1963971671127752706|2|1A03G96|489.00000000|2024-11-02 12:33:02.000
+LINE|SO241020241102004|1963971671127752707|3|AB37A2|2000.00000000|2024-11-02 12:33:20.000
+LINE|SO241020241102004|1963971671127752708|4|AB37A3|5000.00000000|2024-11-02 12:33:30.000
+LINE|SO241020241102004|1963971671127752709|5|A2C7116|35000.00000000|2024-11-02 12:33:45.000
+LINE|SO241020241102004|1963971671127752710|6|A2C7117|15000.00000000|2024-11-02 12:33:58.000
+LINE|SO241020241102004|1963971671131947008|7|1A0387B|130.00000000|2024-11-02 12:34:15.000
+LINE|SO241020241102004|1963971671131947009|8|91CC0177|300.00000000|2024-11-02 12:34:28.000
+LINE|SO241020241102004|1963971671131947010|9|91CC0178|525.00000000|2024-11-02 12:34:42.000
+LINE|SO241020241102004|1963971671131947011|10|91CC0179|1200.00000000|2024-11-02 12:34:55.000
+LINE|SO241020241102004|1963971671131947012|11|91CC0228|2367.00000000|2024-11-02 12:35:09.000
+LINE|SO241020241104001|1964653664643579905|1|91CC0229|900.00000000|2024-11-04 09:41:34.000
+LINE|SO241020241104001|1964653664643579906|2|AB3A76|1815.00000000|2024-11-04 09:41:49.000
+LINE|SO241020241104001|1964653664643579907|3|A2B8414|300.00000000|2024-11-04 09:41:59.000
+LINE|SO241020241104001|1964653664643579908|4|91DC0284|263.00000000|2024-11-04 09:43:50.000
+LINE|SO241020241104001|1964653664643579909|5|91F0D061|121.00000000|2024-11-04 09:44:13.000
+LINE|SO241020241104001|1964653664643579910|6|91DC0219|2030.00000000|2024-11-04 09:44:50.000
+LINE|SO241020241104001|1964653664643579911|7|91DC0218|318.00000000|2024-11-04 09:45:09.000
+LINE|SO241020241104001|1964653664643579912|8|91CC0231|200.00000000|2024-11-04 09:45:30.000
+LINE|SO241020241104001|1964653664643579913|9|91CC0233|800.00000000|2024-11-04 09:45:42.000
+LINE|SO241020241219001|1981045424231809025|1|91DC0218|400.00000000|2024-12-19 15:13:21.000
+LINE|SO241020241219001|1981045424231809026|2|91DC0219|1312.00000000|2024-12-19 15:13:31.000
+LINE|SO241020241219001|1981045424231809027|3|1A004C4|436000.00000000|2024-12-19 15:14:15.000
+LINE|SO241020241219001|1981045424231809028|4|ABC419|3200.00000000|2024-12-19 15:14:29.000
+LINE|SO241020241219001|1981045424231809029|5|ABC431|1600.00000000|2024-12-19 15:14:42.000
+LINE|SO241020241219001|1981045424231809030|6|1A0C432|1400.00000000|2024-12-19 15:14:53.000
+LINE|SO241020241219001|1981045424231809031|7|1A0044F|1753.00000000|2024-12-19 15:15:05.000
+LINE|SO241020241219001|1981045424231809032|8|1A03D23|743.00000000|2024-12-19 15:15:19.000
+LINE|SO241020241219001|1981045424231809033|9|A2B4199|1746.00000000|2024-12-19 15:15:32.000
+LINE|SO241020241219001|1981045424231809034|10|1A03G96|1960.00000000|2024-12-19 15:15:46.000
+LINE|SO241020241219001|1981045424231809035|11|A2B8184|100.00000000|2024-12-19 15:15:59.000
+LINE|SO241020241219001|1981045424231809036|12|A2B8361|400.00000000|2024-12-19 15:16:10.000
+LINE|SO241020241219001|1981045424231809037|13|91CC0188|1700.00000000|2024-12-19 15:16:23.000
+LINE|SO241020241219001|1981045424231809038|14|91CC0228|2315.00000000|2024-12-19 15:16:34.000
+LINE|SO241020241219001|1981045424231809039|15|91CC0232|800.00000000|2024-12-19 15:16:46.000
+LINE|SO241020241219001|1981045424231809040|16|91CC0233|400.00000000|2024-12-19 15:16:57.000
+LINE|SO241020241219001|1981045424231809041|17|91CC0234|100.00000000|2024-12-19 15:17:08.000
+LINE|SO241020241219001|1981045424231809042|18|91CC0283|1890.00000000|2024-12-19 15:17:24.000
+LINE|SO241020241219001|1981045424231809043|19|91CC0319|3500.00000000|2024-12-19 15:17:36.000
+LINE|SO241020250114003|1990491416446369793|1|1A03G94|1686.00000000|2025-01-14 16:53:10.000
+LINE|SO241020250114003|1990491416446369794|2|AB37A3|2000.00000000|2025-01-14 16:53:26.000
+LINE|SO241020250114003|1990491416446369795|3|A2B8361|400.00000000|2025-01-14 16:53:37.000
+LINE|SO241020250114003|1990491416446369796|4|1AB9275|1017.00000000|2025-01-14 16:53:48.000
+LINE|SO241020250114003|1990491416446369797|5|A21C092|2063.00000000|2025-01-14 16:53:59.000
+LINE|SO241020250114003|1990491416446369798|6|A21C096|1000.00000000|2025-01-14 16:54:12.000
+LINE|SO241020250114003|1990491416446369799|7|91C0D051|299.00000000|2025-01-14 16:54:35.000
+LINE|SO241020250114003|1990491416446369800|8|91C0D053|300.00000000|2025-01-14 16:54:50.000
+LINE|SO241020250114003|1990491416446369801|9|91C0D074|400.00000000|2025-01-14 16:55:01.000
+WO|MPO482024102400001|604438178041925|M500029670|94000292|4500.0000000000
+WO|MPO482024102400001|604438178041926|M500029671|1004023|3500.0000000000
+WO|MPO482024102400001|604438178046021|M500029672|1000329|400000.0000000000
+WO|MPO482024102400001|604438178046022|M500029673|1000655|100000.0000000000
+WO|MPO482024102400001|604438178046023|M500029674|1007114|250000.0000000000
+WO|MPO482024102400001|604438178046024|M500029675|1007115|600000.0000000000
+WO|MPO482024102400001|604438178050117|M500029676|1004199|6000.0000000000
+WO|MPO482024102400001|604438178050118|M500029677|1000588|10000.0000000000
+WO|MPO482024102400001|604438178050119|M500029678|1007094|2500.0000000000
+WO|MPO482024102400001|604438178050120|M500029679|93000286|1500.0000000000
+WO|MPO482024102400001|604438178050120|M500029680|32400015|1470.0000000000
+WO|MPO482024102400001|604438178054213|M500029682|94000218|800.0000000000
+WO|MPO482024120200001|618270140751941|M500053217|93000229|60.0000000000
+WO|MPO482024120200002|618290062549061|M500053390|94000218|2000.0000000000
+WO|MPO482024120400002|619057595396165|M500055223|93000237|200.0000000000
+WO|MPO482025010700001|630994145116229|M500061078|1007114|250000.0000000000
+WO|MPO482025010700002|631069575503941|M500061979|1000329|100000.0000000000
+WO|MPO482025010900001|631769478479941|M500067184|93000312|500.0000000000
+WO|MPO482025010900001|631769478479942|M500067185|1004023|600.0000000000
+WO|MPO482025010900001|631769478484037|M500067186|93000231|100.0000000000
+WO|MPO482025010900001|631769478484038|M500067187|93000286|800.0000000000
+WO|MPO482025011000001|632121332793413|M500068611|93000058|400.0000000000
+WO|MPO482025011000002|632124508205125|M500068948|1008361|1000.0000000000
+WO|MPO482025011000003|632125640785989|M500069117|1008184|700.0000000000
+WO|MPO482025011300002|633173731577925|M500070459|1004199|4000.0000000000
+WO|MPO482025011300003|633178120278085|M500070619|1004023|5000.0000000000
+WO|MPO482025011300005|633197803688005|M500070942|1000431|10000.0000000000
+WO|MPO482025011300005|633197803688006|M500070943|1000432|10000.0000000000
+WO|MPO482025011300006|633206945230917|M500070944|1000419|35000.0000000000
+WO|MPO482025011400001|633515239526469|M500072258|1000293|650000.0000000000
+WO|MPO482025011400001|633515239526470|M500072259|1000329|200000.0000000000
+WO|MPO482025011400002|633520970641477|M500072882|94000215|1500.0000000000
+WO|MPO482025022100001|646977501577285|M500085317|93000179|5000.0000000000
+WO|MPO482025022100001|646977501577286|M500085318|93000287|10000.0000000000
+WO|MPO482025022100001|646977501577286|M500085319|32400026|10000.0000000000
+WO|MPO482025022100001|646977501577286|M500085320|32400029|10000.0000000000
+WO|MPO482025022100001|646977501577286|M500085321|35100015|1.0000000000
+WO|MPO482025022100001|646977501581381|M500085323|93000288|-9988.0000000000
+WO|MPO482025022100001|646977501581381|M500085324|32400025|10000.0000000000
+WO|MPO482025022100001|646977501581381|M500085325|32400028|10050.0000000000
+WO|MPO482025022100001|646977501581381|M500085326|35100016|1.0000000000
+WO|MPO482025022100001|646977501581382|M500085328|93000187|5000.0000000000
+WO|MPO482025022100001|646977501581383|M500085329|93000233|1500.0000000000
+WO|MPO482025022100001|646977501581384|M500085330|94000218|3000.0000000000
+WO|MPO482025022100001|646977501581385|M500085331|1010096|10000.0000000000
+WO|MPO482025032900001|659719952244805|M500089559|93000177|5000.0000000000
+WO|MPO482025032900001|659719952244806|M500089560|93000179|5000.0000000000
+WO|MPO482025032900001|659719952244806|M500089561|32100033|10000.0000000000
+WO|MPO482025032900001|659719952244806|M500089562|32100034|11000.0000000000
+WO|MPO482025032900001|659719952248901|M500089563|93000287|4000.0000000000
+WO|MPO482025032900001|659719952248901|M500089564|32400026|4500.0000000000
+WO|MPO482025032900001|659719952248901|M500089565|32400029|4000.0000000000
+WO|MPO482025032900001|659719952248901|M500089566|35100015|1.0000000000
+WO|MPO482025032900001|659719952248902|M500089568|94000217|2000.0000000000
+WO|MPO482025032900001|659719952248903|M500089569|94000219|9000.0000000000
+WO|MPO482025032900001|659719952248904|M500089570|93000240|2000.0000000000
+WO|MPO482025032900001|659719952252997|M500089573|1007111|200000.0000000000
+WO|MPO482025041300001|665010090852421|M500090472|35100010|1.0000000000
+WO|MPO482025041300001|665010090852422|M500090473|35100014|1.0000000000
+WO|MPO482025041300001|665010090852423|M500090474|35100033|1.0000000000
+WO|MPO482025041300001|665010090856517|M500090475|35100034|1.0000000000
+WO|MPO482025042800001|670272721616965|M500093527|32100031|7000.0000000000
+WO|MPO482025051800001|677416091480133|M500101110|35100015|1.0000000000
+WO|MPO482025051800001|677416091480134|M500101111|35100015|1.0000000000
+WO|MPO482025051800001|677416091480135|M500101112|35100015|1.0000000000
+WO|MPO482025051800001|677416091480136|M500101113|35100015|1.0000000000
+WO|MPO482025051800001|677416091480137|M500101114|35100015|1.0000000000
+WO|MPO482025051800001|677416091484229|M500101115|35100015|1.0000000000
+WO|MPO482025051800001|677416091484230|M500101116|35100015|1.0000000000
+WO|MPO482025051800001|677416091484231|M500101117|35100015|1.0000000000
+WO|MPO482025051800001|677416091484232|M500101118|35100015|1.0000000000
+WO|MPO482025051800001|677416091484233|M500101119|35100015|1.0000000000
+WO|MPO482025062100002|689366516133957|M500108428|35100034|1.0000000000
+WO|MPO482025062100002|689366516133958|M500108429|35100034|1.0000000000
+WO|MPO482025062100002|689366516133959|M500108430|35100034|1.0000000000
+WO|MPO482025062100002|689366516138053|M500108431|35100034|1.0000000000
+WO|MPO482025062100002|689366516138054|M500108432|35100034|1.0000000000
+WO|MPO482025062100002|689366516138055|M500108433|35100016|1.0000000000
+WO|MPO482025062100002|689366516138056|M500108434|35100016|1.0000000000
+WO|MPO482025062100002|689366516142149|M500108435|35100016|1.0000000000
+WO|MPO482025062100002|689366516142150|M500108436|35100016|1.0000000000
+WO|MPO482025062100002|689366516142151|M500108437|35100016|1.0000000000
+WO|MPO482025062100002|689366516142152|M500108438|35100016|1.0000000000
+WO|MPO482025062100002|689366516142153|M500108439|35100016|1.0000000000
+WO|MPO482025062100003|689369829818437|M500108487|35100016|1.0000000000
+WO|MPO482025062100003|689369829818438|M500108488|35100016|1.0000000000
+WO|MPO482025062100003|689369829818439|M500108489|35100016|1.0000000000
+WO|MPO482025062100003|689369829818440|M500108490|35100010|1.0000000000
+WO|MPO482025062100003|689369829822533|M500108491|35100010|1.0000000000
+WO|MPO482025062100003|689369829822534|M500108492|35100010|1.0000000000
+WO|MPO482025062100003|689369829822535|M500108493|35100010|1.0000000000
+WO|MPO482025062100003|689369829822536|M500108494|35100010|1.0000000000
+WO|MPO482025062100003|689369829826629|M500108495|35100010|1.0000000000
+WO|MPO482025062100003|689369829826630|M500108496|35100010|1.0000000000
+WO|MPO482025062100003|689369829826631|M500108497|35100010|1.0000000000
+WO|MPO482025062100003|689369829826632|M500108498|35100010|1.0000000000
+WO|MPO482025062100003|689369829826633|M500108499|35100010|1.0000000000
+WO|MPO482025062600003|691329582436421|M500109125|93000178|3000.0000000000
+WO|MPO482025062600003|691329582436422|M500109126|93000285|-3074.0000000000
+WO|MPO482025062600003|691329582436422|M500109127|32400014|3100.0000000000
+WO|MPO482025062600003|691329582436422|M500109128|32400038|3100.0000000000
+WO|MPO482025062600003|691329582436423|M500109130|93000286|5000.0000000000
+WO|MPO482025062600003|691329582436423|M500109131|32100035|5100.0000000000
+WO|MPO482025062600003|691329582436423|M500109132|32400015|5100.0000000000
+WO|MPO482025062600003|691329582440517|M500109134|1008361|4000.0000000000
+WO|MPO482025081500001|708842858610757|M500123310|1000273|200.0000000000
+WO|MPO482025081500001|708842858610758|M500123311|1000275|272.0000000000
+WO|MPO482025081500001|708842858610759|M500123312|1000304|360000.0000000000
+WO|MPO482025081500001|708842858610760|M500123313|1000419|1000.0000000000
+WO|MPO482025081500001|708842858610761|M500123314|1000431|2000.0000000000
+WO|MPO482025081500001|708842858610762|M500123315|1000432|-2000.0000000000
+WO|MPO482025081500001|708842858610763|M500123316|1000588|-29000.0000000000
+WO|MPO482025081500001|708842858614853|M500123317|1000595|670000.0000000000
+WO|MPO482025081500001|708842858614854|M500123318|1002104|-113.0000000000
+WO|MPO482025081500002|708853132763205|M500123386|1010092|550.0000000000
+WO|MPO482025081500002|708853132763206|M500123387|1010093|1.0000000000
+WO|MPO482025081500002|708853132763207|M500123388|92000033|38.0000000000
+WO|MPO482025081500002|708853132767301|M500123389|93000058|558.0000000000
+WO|MPO482025081500002|708853132767302|M500123390|93000074|2522.0000000000
+WO|MPO482025081500002|708853132767303|M500123391|93000108|69.0000000000
+WO|MPO482025081500002|708853132767303|M500123392|35100032|1.0000000000
+WO|MPO482025081500002|708853132771397|M500123393|93000110|185.0000000000
+WO|MPO482025081500002|708853132771398|M500123395|93000123|2.0000000000
+WO|MPO482025081500002|708853132771399|M500123396|93000229|862.0000000000
+WO|MPO482025081500002|708853132771400|M500123399|93000262|200.0000000000
+WO|MPO482025081500002|708853132771400|M500123401|32300026|200.0000000000
+WO|MPO482025081500002|708853132771401|M500123403|93000286|3232.0000000000
+WO|MPO482025081500002|708853132771401|M500123404|32400015|-3015.0000000000
+WO|MPO482025081500002|708853132775493|M500123405|93000312|300.0000000000
+WO|MPO482025081500002|708853132775494|M500123407|93000404|500.0000000000
+WO|MPO482025081500002|708853132775495|M500123408|93000412|800.0000000000
+WO|MPO482025081500002|708853132775496|M500123409|93000502|400.0000000000
+WO|MPO482025081500002|708853132775497|M500123411|93000503|1050.0000000000
+WO|MPO482025081500002|708853132779589|M500123413|93000506|1.0000000000
+WO|MPO482025081500002|708853132779590|M500123414|93000507|1000.0000000000
+WO|MPO482025081500002|708853132779591|M500123415|93000509|350.0000000000
+WO|MPO482025081500002|708853132779592|M500123416|93000510|1100.0000000000
+WO|MPO482025081500002|708853132779593|M500123417|93000518|1250.0000000000
+WO|MPO482025081500002|708853132783685|M500123418|93000521|3000.0000000000
+WO|MPO482025081500002|708853132783686|M500123419|93000524|1500.0000000000
+WO|MPO482025081500002|708853132783687|M500123420|93000525|3000.0000000000
+WO|MPO482025081500002|708853132783688|M500123421|96000339|6000.0000000000
+WO|MPO482025081500002|708853132783689|M500123422|1009259|5000.0000000000
+WO|MPO482025081500002|708853132783689|M500123423|32100042|-20000.0000000000
+WO|MPO482025081500002|708853132783690|M500123425|32400015|-8000.0000000000
+WO|MPO482025081500002|708853132787781|M500123426|35100032|1.0000000000
+WO|MPO482025081500002|708853132787782|M500123427|1000452|1000.0000000000
+WO|MPO482025081500002|708853132791880|M500123430|93000517|100.0000000000
+WO|MPO482025081500002|708853132791881|M500123431|35100034|1.0000000000
+WO|MPO482025081500002|708853132791882|M500123432|35100034|-1.0000000000
+WO|MPO482025081500002|708853132791883|M500123433|35100034|1.0000000000
+WO|MPO482025081500002|708853132791884|M500123434|35100034|1.0000000000
+WO|MPO482025081500002|708853132791885|M500123435|35100034|1.0000000000
+WO|MPO482025081500002|708853132795973|M500123436|35100033|1.0000000000
+WO|MPO482025081500002|708853132795974|M500123437|35100033|1.0000000000
+WO|MPO482025081500002|708853132795975|M500123438|35100033|1.0000000000
+WO|MPO482025081500002|708853132795976|M500123439|35100033|1.0000000000
+WO|MPO482025081500002|708853132795977|M500123440|35100033|1.0000000000
+WO|MPO482025081500002|708853132795978|M500123441|35100033|-1.0000000000
+WO|MPO482025081500002|708853132795979|M500123442|35100033|1.0000000000
+WO|MPO482025081500002|708853132795980|M500123443|35100033|1.0000000000
+WO|MPO482025081500002|708853132795981|M500123444|35100015|1.0000000000
+WO|MPO482025081500002|708853132795982|M500123445|35100015|1.0000000000
+WO|MPO482025081500002|708853132795983|M500123446|35100015|1.0000000000
+WO|MPO482025081500002|708853132800069|M500123447|35100015|1.0000000000
+WO|MPO482025081500002|708853132800070|M500123448|35100015|1.0000000000
+WO|MPO482025081500002|708853132800071|M500123449|35100015|1.0000000000
+WO|MPO482025081500002|708853132800072|M500123450|35100015|1.0000000000
+WO|MPO482025081500002|708853132800073|M500123451|35100015|1.0000000000
+WO|MPO482025081500002|708853132800074|M500123452|35100015|1.0000000000
+WO|MPO482025081500002|708853132800075|M500123453|35100015|1.0000000000
+WO|MPO482025081500002|708853132800076|M500123454|35100015|1.0000000000
+WO|MPO482025081500002|708853132800077|M500123455|35100015|1.0000000000
+WO|MPO482025081500002|708853132804165|M500123456|35100015|1.0000000000
+WO|MPO482025082900002|713850861281349|M500124855|93000270|5000.0000000000
+WO|MPO482025082900002|713850861281350|M500124858|93000311|510.0000000000
+WO|MPO482025082900002|713850861281351|M500124861|93000312|500.0000000000
+WO|MPO482025082900002|713850861285445|M500124864|93000233|600.0000000000
+WO|MPO482025082900002|713850861285446|M500124867|93000232|1500.0000000000
+WO|MPO482025090400005|716009096228933|M500125396|32300021|5000.0000000000
+WO|MPO482025090400005|716009096228934|M500125401|32300021|5000.0000000000
+WO|MPO482025091800003|720949568118853|M500130059|93000483|1900.0000000000
+WO|MPO482025091800003|720949568118853|M500130060|32300021|1900.0000000000
+WO|MPO482025091800003|720949568118853|M500130061|32300065|1900.0000000000
+WO|MPO482025091800003|720949568118854|M500130062|93000312|100.0000000000
+WO|MPO482025091800003|720949568118854|M500130063|32300021|100.0000000000
+WO|MPO482025091800003|720949568118855|M500130066|93000311|600.0000000000
+WO|MPO482025091800003|720949568118855|M500130067|32300021|600.0000000000
+WO|MPO482025091800003|720949568122949|M500130068|93000313|100.0000000000
+WO|MPO482025091800003|720949568122950|M500130070|93000229|700.0000000000
+WO|MPO482025091900001|721256689414213|M500130445|93000182|10000.0000000000
+WO|MPO482025091900001|721256689414214|M500130446|32300009|10000.0000000000
+WO|MPO482025091900001|721256689414215|M500130447|32300012|10000.0000000000
+WO|MPO482025091900001|721256689414216|M500130448|32300026|-2980.0000000000
+WO|MPO482025091900001|721256689414217|M500130449|32300027|-2968.0000000000
+WO|MPO482025091900001|721256689418309|M500130450|32300028|3000.0000000000
+WO|MPO482025091900001|721256689418310|M500130451|32300035|10000.0000000000
+WO|MPO482025091900001|721256689418311|M500130452|32300046|3000.0000000000
+WO|MPO482025091900001|721256689422405|M500130453|32300047|2108.0000000000
+WO|MPO482025091900001|721256689422406|M500130454|32300048|-10000.0000000000
+WO|MPO482025091900001|721256689422407|M500130455|35100015|1.0000000000
+WO|MPO482025091900001|721256689422408|M500130456|35100015|1.0000000000
+WO|MPO482025091900001|721256689426501|M500130457|35100015|1.0000000000
+WO|MPO482025091900001|721256689426502|M500130458|35100015|1.0000000000
+WO|MPO482025091900001|721256689426503|M500130459|35100016|1.0000000000
+WO|MPO482025091900001|721256689426504|M500130460|35100016|1.0000000000
+WO|MPO482025091900001|721256689426505|M500130461|35100016|1.0000000000
+WO|MPO482025091900001|721256689430597|M500130462|35100016|1.0000000000
+WO|MPO482025091900001|721256689430598|M500130463|35100016|1.0000000000
+WO|MPO482025091900001|721256689430599|M500130464|35100016|1.0000000000
+WO|MPO482025091900001|721256689430600|M500130465|35100015|1.0000000000
+WO|MPO482025091900001|721256689434693|M500130466|35100015|1.0000000000
+WO|MPO482025091900001|721256689434694|M500130467|35100015|1.0000000000
+WO|MPO482025091900001|721256689434695|M500130468|35100015|1.0000000000
+WO|MPO482025091900001|721256689434696|M500130469|35100015|1.0000000000
+WO|MPO482025091900001|721256689438789|M500130470|35100015|1.0000000000
+WO|MPO482025091900001|721256689438790|M500130471|35100015|1.0000000000
+WO|MPO482025092200002|722351552172101|M500130840|93000283|20000.0000000000
+WO|MPO482026012100001|765148661813317|M500103886|1A0044F|1000.0000000000
+WO|MPO482026012100001|765148661813317|M500103887|322AD001|1000.0000000000
+WO|MPO482026012100001|765148661813317|M500103888|3221C0031|1000.0000000000
+WO|MPO482026012100001|765148661813318|M500103889|1A0045H|1000.0000000000
+WO|MPO482026012100001|765148661813318|M500103890|3521C0018|2.0000000000
+WO|MPO482026012100001|765148661813319|M500103891|1A0047E|1000.0000000000
+WO|MPO482026020300001|769809191923781|M500105944|1A0044F|100.0000000000
+WO|MPO482026020300001|769809191923781|M500105945|322AD001|100.0000000000
+WO|MPO482026020300001|769809191923781|M500105946|3221C0031|100.0000000000
+WO|SO241020241014001|1958480382326104272|M500028977|1007114|120000.0000000000
+WO|SO241020241014001|1958480382326104273|M500028978|1007115|30000.0000000000
+WO|SO241020241015003|1958480382326104295|M500028992|1000431|5000.0000000000
+WO|SO241020241015003|1958480382326104296|M500028993|1000432|5000.0000000000
+WO|SO241020241018001|1958902016386269188|M500029021|1000595|92000.0000000000
+WO|SO241020241018001|1958902016386269193|M500029024|1007096|7000.0000000000
+WO|SO241020241018001|1958902016386269196|M500029027|1002081|1256.0000000000
+WO|SO241020241018001|1958902016386269200|M500029034|93000236|140.0000000000
+WO|SO241020241019001|1958956122157088771|M500029040|93000228|3000.0000000000
+WO|SO241020241022001|1960006795304894465|M500029272|93000235|600.0000000000
+WO|SO241020241102001|1963915047889534981|M500033844|94000284|10000.0000000000
+WO|SO241020241102001|1963915047889534985|M500033846|1002081|1200.0000000000
+WO|SO241020241102004|1963971671131947011|M500033849|93000179|2000.0000000000
+WO|SO241020241104001|1964653664643579905|M500033851|93000229|6000.0000000000
+WO|SO241020241104001|1964653664643579907|M500033853|1008414|176.0000000000
+WO|SO241020241104001|1964653664643579908|M500033854|94000284|10000.0000000000
+WO|SO241020241104001|1964653664643579910|M500033856|94000219|11000.0000000000
+WO|SO241020241104001|1964653664643579913|M500033857|93000233|1000.0000000000

+ 24 - 0
doc/plan/sql/_extract_p0.tsv

@@ -0,0 +1,24 @@
+SO|MPO482024102300001|604078130520133||WKQXGFYXGE|2024-10-23 00:00:00.000|1
+SO|MPO482024120200003|618329121550405||WKQXGFYXGE|2024-12-02 00:00:00.000|1
+SO|MPO482025010900002|631771613847621||WKQXGFYXGE|2025-01-09 00:00:00.000|1
+SO|MPO482025011300004|633180642168901||WKQXGFYXGE|2025-01-13 00:00:00.000|1
+SO|MPO482025012100001|636029205446725||WKQXGFYXGE|2025-01-21 00:00:00.000|1
+LINE|MPO482024102300001|604078133665861|1|3121C0035|1500.00000000|2024-10-29 00:00:00.000
+LINE|MPO482024102300001|604078133665862|2|1A0C885|3500.00000000|2024-10-29 00:00:00.000
+LINE|MPO482024120200003|618329124159557|1|1AB9275|800.00000000|2024-12-03 00:00:00.000
+LINE|MPO482025010900002|631771616395333|1|3121C0035|850.00000000|2025-01-18 00:00:00.000
+LINE|MPO482025010900002|631771616399429|2|3124C0015|850.00000000|2025-01-21 00:00:00.000
+LINE|MPO482025011300004|633180644831301|1|322AD001|5500.00000000|2025-02-11 00:00:00.000
+LINE|MPO482025011300004|633180644831302|2|3221C0031|5500.00000000|2025-02-18 00:00:00.000
+LINE|MPO482025012100001|636029208526917|1|91C0D2C|600.00000000|2025-02-13 00:00:00.000
+LINE|MPO482025012100001|636029208526918|2|91CC0231|100.00000000|2025-02-13 00:00:00.000
+WO|MPO482024102300001|604078133665861|M500029406|32100035|1500.0000000000
+WO|MPO482024102300001|604078133665862|M500029407|1000885|3500.0000000000
+WO|MPO482024120200003|618329124159557|M500053856|1009275|800.0000000000
+WO|MPO482025010900002|631771616395333|M500067189|32100035|850.0000000000
+WO|MPO482025010900002|631771616399429|M500067190|32400015|850.0000000000
+WO|MPO482025011300004|633180644831301|M500070779|32100001|5500.0000000000
+WO|MPO482025011300004|633180644831302|M500070780|32100031|5500.0000000000
+WO|MPO482025011300004|633180644831302|M500070781|35100010|1.0000000000
+WO|MPO482025012100001|636029208526917|M500077552|93000230|600.0000000000
+WO|MPO482025012100001|636029208526918|M500077553|93000231|100.0000000000

+ 233 - 0
doc/plan/sql/tools/Generate-S1S4FullUatSql.ps1

@@ -0,0 +1,233 @@
+# Generate S1-S4 FULL UAT MySQL write script from dopdemorq extract.
+# Usage: .\Generate-S1S4FullUatSql.ps1 -SqlServerPassword '<sa-password>'
+param(
+    [string]$SqlServer = '123.60.180.165',
+    [string]$SqlUser = 'sa',
+    [string]$SqlPassword,
+    [string]$SqlDatabase = 'dopdemorq',
+    [string]$BillListFile = "$PSScriptRoot\S1S4_FULL_bill_list.txt",
+    [string]$OutSql = "$PSScriptRoot\..\S1S4_UAT_FULL_execute_write.sql",
+    [string]$OutTsv = "$PSScriptRoot\..\_extract_full.tsv",
+    [long]$IdBase = 9106000500000001,
+    [string]$BatchNo = 'S1S4_UAT_FULL_20260605_V1'
+)
+
+$ErrorActionPreference = 'Stop'
+if (-not $SqlPassword) { throw 'SqlPassword is required (do not commit to git).' }
+
+function Escape-Sql([string]$s) {
+    if ($null -eq $s) { return '' }
+    return ($s -replace "'", "''")
+}
+
+$bills = Get-Content $BillListFile | Where-Object { $_.Trim() -ne '' } | ForEach-Object { $_.Trim() }
+$billValues = ($bills | ForEach-Object { "(N'$(Escape-Sql $_)')" }) -join ",`n"
+
+$template = Get-Content "$PSScriptRoot\extract_full_from_dopdemorq.sql" -Raw
+$extractSql = $template -replace "INSERT INTO @bills\(bill_no\) VALUES \(N'__PLACEHOLDER__'\);", "INSERT INTO @bills(bill_no) VALUES $billValues;"
+$extractFile = Join-Path $env:TEMP "s1s4_full_extract.sql"
+Set-Content -Path $extractFile -Value $extractSql -Encoding UTF8
+
+$sqlcmd = 'C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\SQLCMD.EXE'
+& $sqlcmd -S $SqlServer -U $SqlUser -P $SqlPassword -d $SqlDatabase -i $extractFile -W -h-1 -s"|" -o $OutTsv
+if ($LASTEXITCODE -ne 0) { throw "sqlcmd failed with exit $LASTEXITCODE" }
+
+$soRows = @(); $lineRows = @(); $woRows = @()
+Get-Content $OutTsv | ForEach-Object {
+    $line = $_.Trim()
+    if ($line -eq '' -or $line -match '^-+$' -or $line -match 'rows affected') { return }
+    $p = $line -split '\|'
+    if ($p.Count -lt 2) { return }
+    switch ($p[0]) {
+        'SO' { $soRows += [pscustomobject]@{ bill_no=$p[1]; src_id=$p[2]; custom_no=$p[3]; custom_name=$p[4]; order_date=$p[5]; urgent=[int]$p[6] } }
+        'LINE' { $lineRows += [pscustomobject]@{ bill_no=$p[1]; src_entry=$p[2]; entry_seq=[int]$p[3]; item_number=$p[4]; qty=$p[5]; plan_date=$p[6] } }
+        'WO' { $woRows += [pscustomobject]@{ bill_no=$p[1]; src_entry=$p[2]; morder_no=$p[3]; product_code=$p[4]; need_number=$p[5] } }
+    }
+}
+
+$soByBill = @{}
+$idx = 0
+foreach ($so in ($soRows | Sort-Object bill_no)) {
+    if ($soByBill.ContainsKey($so.bill_no)) { continue }
+    $idx++
+    $soByBill[$so.bill_no] = [pscustomobject]@{
+        bill_no = $so.bill_no
+        target_id = $IdBase + $idx
+        custom_no = if ($so.custom_no) { $so.custom_no } else { 'CUST0005' }
+        custom_name = if ($so.custom_name) { $so.custom_name } else { 'WKQXGFYXGE' }
+        order_date = if ($so.order_date -and $so.order_date -ne 'NULL') { $so.order_date } else { '2025-06-01 00:00:00.000' }
+        delivery_date = if ($so.order_date -and $so.order_date -ne 'NULL') { $so.order_date } else { '2025-06-15 00:00:00.000' }
+        urgent = $so.urgent
+        po_seq = $idx
+    }
+}
+
+$missing = $bills | Where-Object { -not $soByBill.ContainsKey($_) }
+Write-Host "Extracted orders: $($soByBill.Count) / $($bills.Count)"
+if ($missing.Count -gt 0) { Write-Host "Missing in dopdemorq: $($missing -join ', ')" }
+
+$lineIdx = 0; $moIdx = 0; $linesOut = @(); $mosOut = @(); $prsOut = @(); $poLinesOut = @()
+$woByEntry = @{}
+foreach ($w in $woRows) { $woByEntry[$w.src_entry] = $w }
+
+foreach ($bill in ($soByBill.Keys | Sort-Object)) {
+    $so = $soByBill[$bill]
+    $lines = $lineRows | Where-Object { $_.bill_no -eq $bill } | Sort-Object entry_seq, src_entry
+    $poNo = ('PO-UAT-FULL-20260605-{0:D3}' -f $so.po_seq)
+    $prSeq = 0
+    $poLineNo = 0
+    foreach ($ln in $lines) {
+        $lineIdx++
+        $targetLine = $IdBase + 10000 + $lineIdx
+        $planDt = if ($ln.plan_date -and $ln.plan_date -ne 'NULL') { $ln.plan_date } else { $so.order_date }
+        $linesOut += "($targetLine,'$(Escape-Sql $ln.src_entry)','$($so.bill_no)',$($ln.entry_seq),'$(Escape-Sql $ln.item_number)',$($ln.qty),'$planDt')"
+        $wo = $woByEntry[$ln.src_entry]
+        if ($wo) {
+            $moIdx++
+            $targetMo = $IdBase + 20000 + $moIdx
+            $targetMe = $IdBase + 40000 + $moIdx
+            $mosOut += "($targetMo,$targetMe,'$(Escape-Sql $ln.src_entry)','$($so.bill_no)','$(Escape-Sql $wo.morder_no)','$(Escape-Sql $wo.product_code)',$($wo.need_number))"
+            $prSeq++
+            $prBill = 'PR-UAT-FULL-20260605-{0:D3}' -f $prSeq
+            $prsOut += "($($IdBase + 50000 + $moIdx),'$prBill','$(Escape-Sql $wo.morder_no)','$($so.bill_no)','$(Escape-Sql $wo.product_code)',$($wo.need_number),$targetMo)"
+            $poLineNo++
+            $poLinesOut += "('$poNo',$poLineNo,'$($so.bill_no)','$(Escape-Sql $wo.morder_no)','$(Escape-Sql $ln.item_number)',$($ln.qty))"
+        }
+    }
+    if ($poLineNo -eq 0 -and $lines.Count -gt 0) {
+        $ln = $lines[0]
+        $moIdx++
+        $synMo = "UAT-MO-$($so.po_seq.ToString('D4'))"
+        $targetMo = $IdBase + 20000 + $moIdx
+        $targetMe = $IdBase + 40000 + $moIdx
+        $mosOut += "($targetMo,$targetMe,'$(Escape-Sql $ln.src_entry)','$($so.bill_no)','$synMo','$(Escape-Sql $ln.item_number)',$($ln.qty))"
+        $prBill = 'PR-UAT-FULL-20260605-001'
+        $prsOut += "($($IdBase + 50000 + $moIdx),'$prBill','$synMo','$($so.bill_no)','$(Escape-Sql $ln.item_number)',$($ln.qty),$targetMo)"
+        $poLinesOut += "('$poNo',1,'$($so.bill_no)','$synMo','$(Escape-Sql $ln.item_number)',$($ln.qty))"
+    }
+}
+
+$soIns = ($soByBill.Values | Sort-Object target_id | ForEach-Object {
+    "('$($_.bill_no)',$($_.target_id),'$(Escape-Sql $_.custom_no)','$(Escape-Sql $_.custom_name)','$($_.order_date)','$($_.delivery_date)',$($_.urgent))"
+}) -join ",`n"
+
+$shipIns = ($soByBill.Values | Sort-Object po_seq | ForEach-Object {
+    $shipId = $IdBase + 60000 + $_.po_seq
+    $poNo = ('PO-UAT-FULL-20260605-{0:D3}' -f $_.po_seq)
+    $shNo = ('SH-UAT-FULL-20260605-{0:D3}' -f $_.po_seq)
+    "($shipId,'$poNo','$shNo')"
+}) -join ",`n"
+
+$header = @"
+-- S1-S4 FULL UAT write (AIDOP tenant 797403760988229)
+-- Batch: $BatchNo
+-- Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
+-- Orders: $($soByBill.Count)
+
+SET @tenant_id     := 797403760988229;
+SET @batch_no      := '$BatchNo';
+SET @operator_id   := 1300000000111;
+SET @operator_name := 'UAT数据导入';
+SET @now           := NOW();
+SET @factory_id    := 797403760988229;
+SET @id_base       := $IdBase;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so;
+CREATE TEMPORARY TABLE tmp_s1_uat_so (
+    bill_no VARCHAR(64) NOT NULL PRIMARY KEY,
+    target_id BIGINT NOT NULL,
+    custom_no VARCHAR(64) NULL,
+    custom_name VARCHAR(128) NULL,
+    order_date DATETIME NULL,
+    delivery_date DATETIME NULL,
+    urgent INT DEFAULT 0
+);
+INSERT INTO tmp_s1_uat_so VALUES
+$soIns;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s1_uat_so_line;
+CREATE TEMPORARY TABLE tmp_s1_uat_so_line (
+    target_id BIGINT NOT NULL PRIMARY KEY,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    entry_seq INT NOT NULL,
+    item_number VARCHAR(64) NULL,
+    qty DECIMAL(18,4) NULL,
+    plan_date DATETIME NULL
+);
+INSERT INTO tmp_s1_uat_so_line VALUES
+$($linesOut -join ",`n");
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s2_uat_morder;
+CREATE TEMPORARY TABLE tmp_s2_uat_morder (
+    target_mo_id BIGINT NOT NULL PRIMARY KEY,
+    target_me_id BIGINT NOT NULL,
+    source_entry VARCHAR(32) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    morder_no VARCHAR(128) NOT NULL,
+    product_code VARCHAR(128) NULL,
+    need_number DECIMAL(23,10) NULL
+);
+INSERT INTO tmp_s2_uat_morder VALUES
+$($mosOut -join ",`n");
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_pr;
+CREATE TEMPORARY TABLE tmp_s3_uat_pr (
+    voucher BIGINT NOT NULL PRIMARY KEY,
+    pr_billno VARCHAR(64) NOT NULL,
+    morder_no VARCHAR(128) NOT NULL,
+    bill_no VARCHAR(64) NOT NULL,
+    icitem_code VARCHAR(64) NULL,
+    pr_rqty DECIMAL(18,4) NULL,
+    mo_id BIGINT NOT NULL
+);
+INSERT INTO tmp_s3_uat_pr VALUES
+$($prsOut -join ",`n");
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_line;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_line (
+    pur_ord VARCHAR(48) NOT NULL,
+    line_no INT NOT NULL,
+    sales_ord VARCHAR(64) NOT NULL,
+    work_ord VARCHAR(128) NULL,
+    item_num VARCHAR(60) NOT NULL,
+    qty DECIMAL(15,5) NOT NULL,
+    PRIMARY KEY (pur_ord, line_no)
+);
+INSERT INTO tmp_s3_uat_po_line VALUES
+$($poLinesOut -join ",`n");
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s3_uat_po_hdr;
+CREATE TEMPORARY TABLE tmp_s3_uat_po_hdr (
+    pur_ord VARCHAR(48) NOT NULL PRIMARY KEY,
+    sales_ord VARCHAR(64) NOT NULL,
+    work_ord VARCHAR(128) NULL
+);
+INSERT INTO tmp_s3_uat_po_hdr
+SELECT pur_ord, MIN(sales_ord), MIN(work_ord) FROM tmp_s3_uat_po_line GROUP BY pur_ord;
+
+DROP TEMPORARY TABLE IF EXISTS tmp_s4_uat_ship;
+CREATE TEMPORARY TABLE tmp_s4_uat_ship (
+    ship_id BIGINT NOT NULL PRIMARY KEY,
+    po_billno VARCHAR(48) NOT NULL,
+    shddh VARCHAR(64) NOT NULL
+);
+INSERT INTO tmp_s4_uat_ship VALUES
+$shipIns;
+
+"@
+
+$body = Get-Content "$PSScriptRoot\S1S4_UAT_FULL_write_body.sql" -Raw -ErrorAction SilentlyContinue
+if (-not $body) {
+    $body = Get-Content "$PSScriptRoot\..\S1S4_UAT_P0_execute_write.sql" -Raw
+    $start = $body.IndexOf('START TRANSACTION;')
+    $body = $body.Substring($start)
+    $body = $body -replace 'PR-UAT-20260604-', 'PR-UAT-FULL-20260605-'
+    $body = $body -replace 'PO-UAT-20260604-', 'PO-UAT-FULL-20260605-'
+    $body = $body -replace 'SH-UAT-20260604-', 'SH-UAT-FULL-20260605-'
+    $body = $body -replace "CONCAT\('UAT导入:', @batch_no\)", "CONCAT('UAT导入:', @batch_no)"
+    $body = $body -replace "Remark, CONCAT\('UAT:', @batch_no\)", "Remark, CONCAT('UAT:', @batch_no)"
+}
+
+Set-Content -Path $OutSql -Value ($header + $body) -Encoding UTF8
+Write-Host "Wrote $OutSql"

+ 69 - 0
doc/plan/sql/tools/S1S4_FULL_bill_list.txt

@@ -0,0 +1,69 @@
+MPO482025042800001
+SO241020241018001
+SO241020241015003
+SO241020241021002
+10014153
+10015150
+10015151
+MPO482025043000001
+MPO482025012000003
+MPO482025042800002
+15002336
+MPO482024041100002
+10014130
+MPO482024121400001
+MPO482024060400002
+MPO482024052700001
+MPO482024053100002
+MPO482024091800004
+15002337
+MPO482024052900002
+MPO482024061500001
+MPO482024051600003
+MPO482024120200004
+MPO482024082800001
+15002328
+MPO482024081900004
+MPO482023121900001
+10014160
+MPO482025081500002
+MPO482025091900001
+SO241020241219001
+MPO482025081500001
+MPO482025041300001
+MPO482025062100003
+SO241020240923001
+MPO482025062100002
+MPO482024102400001
+MPO482025051800001
+SO241020250114003
+MPO482025092200002
+MPO482025022100001
+MPO482025032900001
+MPO482025091800003
+MPO482025082900002
+MPO482025062600003
+MPO482025090400005
+MPO482026020300001
+MPO482026012100001
+SO241020241104001
+SO241020241102001
+SO241020241102004
+SO241020241022001
+SO241020241019001
+SO241020241014001
+MPO482025011400002
+MPO482025011400001
+MPO482025011300006
+MPO482025011300005
+MPO482025011300003
+MPO482025011300002
+MPO482025011000003
+MPO482025011000002
+MPO482025011000001
+MPO482025010900001
+MPO482025010700002
+MPO482025010700001
+MPO482024120400002
+MPO482024120200002
+MPO482024120200001

+ 39 - 0
doc/plan/sql/tools/extract_full_from_dopdemorq.sql

@@ -0,0 +1,39 @@
+SET NOCOUNT ON;
+DECLARE @bills TABLE (bill_no NVARCHAR(64) PRIMARY KEY);
+-- bill list injected by PowerShell
+
+INSERT INTO @bills(bill_no) VALUES (N'__PLACEHOLDER__');
+
+SELECT 'SO' AS kind,
+       o.bill_no,
+       CAST(o.Id AS NVARCHAR(32)) AS src_id,
+       ISNULL(o.custom_no, N'') AS custom_no,
+       ISNULL(o.custom_name, N'') AS custom_name,
+       CONVERT(VARCHAR(23), o.[date], 121) AS order_date,
+       ISNULL(o.urgent, 0) AS urgent
+FROM crm_seorder o
+WHERE o.bill_no IN (SELECT bill_no FROM @bills)
+  AND ISNULL(o.IsDeleted, 0) = 0;
+
+SELECT 'LINE' AS kind,
+       e.bill_no,
+       CAST(e.Id AS NVARCHAR(32)) AS src_entry,
+       ISNULL(e.entry_seq, ROW_NUMBER() OVER (PARTITION BY e.bill_no ORDER BY e.Id)) AS entry_seq,
+       ISNULL(e.item_number, N'') AS item_number,
+       ISNULL(e.qty, 0) AS qty,
+       CONVERT(VARCHAR(23), ISNULL(e.plan_date, e.[date]), 121) AS plan_date
+FROM crm_seorderentry e
+WHERE e.bill_no IN (SELECT bill_no FROM @bills)
+  AND ISNULL(e.IsDeleted, 0) = 0;
+
+SELECT 'WO' AS kind,
+       e.bill_no,
+       CAST(e.Id AS NVARCHAR(32)) AS src_entry,
+       mo.morder_no,
+       ISNULL(mo.product_code, e.item_number) AS product_code,
+       ISNULL(mo.need_number, e.qty) AS need_number
+FROM crm_seorderentry e
+INNER JOIN mes_moentry me ON me.soentry_id = e.Id AND ISNULL(me.IsDeleted, 0) = 0
+INNER JOIN mes_morder mo ON mo.Id = me.moentry_moid AND ISNULL(mo.IsDeleted, 0) = 0
+WHERE e.bill_no IN (SELECT bill_no FROM @bills)
+  AND ISNULL(e.IsDeleted, 0) = 0;

+ 1 - 1
doc/plan/数据库迁移/S1/S1-任务交接记忆.md

@@ -60,7 +60,7 @@
   - `id=440 batch=S1_MDP_FULL_20260525154551 stage=21 std=17 dwd=8 duration=6158ms`(首次成功)
 - ✅ `id=442` 已清理为 `FAILED`(`end_time=2026-05-25 16:45:11`,`error_message='env:db disconnected during AUTO run'`)。原因:15:53 远端 MySQL 瞬断(`Unable to connect to any of the specified MySQL hosts` / `远程主机强迫关闭了一个现有的连接`),`MarkTransformRunFailedAsync` 自身也写不了,留成孤儿 RUNNING。属环境抖动,**非代码问题**。
 - ✅ 各层行数:`mdp_stg_so=17 / mdp_stg_ship_trans=2 / mdp_std_so=8 / mdp_std_ship_trans=1 / dwd_ship_trans=8`,多轮稳定
-- ✅ 数据租户分布:`mdp_std_so` / `dwd_ship_trans` 各跨两租户 `1300000000001` 与 `797403760988229`
+- ✅ 数据租户分布:`mdp_std_so` / `dwd_ship_trans` 各跨两租户 `1300000000001` 与 `797403760988229`(**S1–S4 UAT 50 单** 2026-06-05 起仅归属 `797403760988229`,见 `doc/plan/sql/S1S4_UAT_迁移至AIDOP租户_20260605.sql`)
 - ✅ `ado_s9_kpi_value_l1_day` 中 `module_code='S1'` 顶部 9 条由本轮 batch 写入(S1_L1_001/002/003 × 两租户)
 
 ### 2.2.1 前端核对(API 通路已验,页面待人工核对)

+ 360 - 0
server/Admin.NET.Web.Entry/UpdateScripts/1.0.150.sql

@@ -0,0 +1,360 @@
+-- 1.0.150.sql
+-- S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1
+-- 本体生产「工序明细 / 损失因素 / 操作员表现」三表 DDL + 幂等 DELETE + 221 行 INSERT SEED。
+--
+-- DDL:3 个 CREATE TABLE IF NOT EXISTS(与 CodeFirst 实体一致;CodeFirst 已建表时 no-op)。
+-- DML:3 个幂等 DELETE(仅本批 SEED,保护 IMPORT/AGG)+ 3 个 INSERT(baseline 13 行 + order-level 208 行 = 221 行)。
+-- 与 procurement 1.0.148.sql 同模式;启动时由 Admin.NET UpdateScripts 模块自动按版本号执行。
+--
+-- 字段精度与实体一致:
+--   process.pi_days / actual_days  DECIMAL(6,3)
+--   process.achievement_rate       DECIMAL(5,4)
+--   loss_factor.ratio_pct          DECIMAL(5,2)
+--   loss_factor.loss_hours         DECIMAL(8,2)
+--   operator.avg_hours             DECIMAL(6,2)
+--
+-- order_id IS NULL 表示 baseline 行(scenario_code=BASELINE_PPT);
+-- order_id IS NOT NULL 表示订单级行(scenario_code=ORDER_LEVEL)。
+
+CREATE TABLE IF NOT EXISTS ado_s8_order_flow_manufacturing_process (
+    id BIGINT NOT NULL,
+    order_id BIGINT NULL,
+    order_code VARCHAR(64) NULL,
+    process_code VARCHAR(16) NOT NULL,
+    process_name VARCHAR(32) NOT NULL,
+    pi_days DECIMAL(6,3) NOT NULL DEFAULT 0,
+    actual_days DECIMAL(6,3) NOT NULL DEFAULT 0,
+    cycle_status VARCHAR(16) NOT NULL DEFAULT 'green',
+    plan_qty INT NULL,
+    achievement_rate DECIMAL(5,4) NULL,
+    achievement_status VARCHAR(16) NOT NULL DEFAULT '',
+    sort_no INT NOT NULL DEFAULT 0,
+    scenario_code VARCHAR(16) NOT NULL DEFAULT 'BASELINE_PPT',
+    data_source VARCHAR(16) NOT NULL DEFAULT 'SEED',
+    tenant_id BIGINT NOT NULL DEFAULT 1,
+    factory_id BIGINT NOT NULL DEFAULT 1,
+    created_at DATETIME NOT NULL,
+    updated_at DATETIME NULL,
+    is_deleted TINYINT(1) NOT NULL DEFAULT 0,
+    PRIMARY KEY (id),
+    KEY idx_order_flow_mfg_process_baseline (tenant_id, factory_id, process_code),
+    KEY idx_order_flow_mfg_process_order    (tenant_id, factory_id, order_code),
+    KEY idx_order_flow_mfg_process_scenario (tenant_id, factory_id, scenario_code, is_deleted)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
+  COMMENT='S8 订单执行链路本体生产工序明细';
+
+CREATE TABLE IF NOT EXISTS ado_s8_order_flow_manufacturing_loss_factor (
+    id BIGINT NOT NULL,
+    order_id BIGINT NULL,
+    order_code VARCHAR(64) NULL,
+    factor_code VARCHAR(32) NOT NULL,
+    factor_name VARCHAR(32) NOT NULL,
+    count_value INT NULL,
+    ratio_pct DECIMAL(5,2) NULL,
+    loss_hours DECIMAL(8,2) NULL,
+    sort_no INT NOT NULL DEFAULT 0,
+    scenario_code VARCHAR(16) NOT NULL DEFAULT 'BASELINE_PPT',
+    data_source VARCHAR(16) NOT NULL DEFAULT 'SEED',
+    tenant_id BIGINT NOT NULL DEFAULT 1,
+    factory_id BIGINT NOT NULL DEFAULT 1,
+    created_at DATETIME NOT NULL,
+    updated_at DATETIME NULL,
+    is_deleted TINYINT(1) NOT NULL DEFAULT 0,
+    PRIMARY KEY (id),
+    KEY idx_order_flow_mfg_loss_baseline (tenant_id, factory_id, factor_code),
+    KEY idx_order_flow_mfg_loss_order    (tenant_id, factory_id, order_code),
+    KEY idx_order_flow_mfg_loss_scenario (tenant_id, factory_id, scenario_code, is_deleted)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
+  COMMENT='S8 订单执行链路本体生产损失因素';
+
+CREATE TABLE IF NOT EXISTS ado_s8_order_flow_manufacturing_operator (
+    id BIGINT NOT NULL,
+    order_id BIGINT NULL,
+    order_code VARCHAR(64) NULL,
+    operator_code VARCHAR(32) NOT NULL,
+    operator_name VARCHAR(64) NOT NULL,
+    avg_hours DECIMAL(6,2) NOT NULL DEFAULT 0,
+    status VARCHAR(16) NOT NULL DEFAULT 'green',
+    sort_no INT NOT NULL DEFAULT 0,
+    scenario_code VARCHAR(16) NOT NULL DEFAULT 'BASELINE_PPT',
+    data_source VARCHAR(16) NOT NULL DEFAULT 'SEED',
+    tenant_id BIGINT NOT NULL DEFAULT 1,
+    factory_id BIGINT NOT NULL DEFAULT 1,
+    created_at DATETIME NOT NULL,
+    updated_at DATETIME NULL,
+    is_deleted TINYINT(1) NOT NULL DEFAULT 0,
+    PRIMARY KEY (id),
+    KEY idx_order_flow_mfg_operator_baseline (tenant_id, factory_id, operator_code),
+    KEY idx_order_flow_mfg_operator_order    (tenant_id, factory_id, order_code),
+    KEY idx_order_flow_mfg_operator_scenario (tenant_id, factory_id, scenario_code, is_deleted)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
+  COMMENT='S8 订单执行链路本体生产操作员表现';
+
+-- ============================================================
+-- 幂等 DELETE:仅本批 SEED(BASELINE_PPT + ORDER_LEVEL);不触 IMPORT/AGG。
+-- 重复 source 此 SQL 不会重复堆叠。
+-- ============================================================
+
+DELETE FROM ado_s8_order_flow_manufacturing_process
+WHERE tenant_id = 1 AND factory_id = 1 AND is_deleted = 0
+  AND data_source = 'SEED'
+  AND scenario_code IN ('BASELINE_PPT', 'ORDER_LEVEL');
+
+DELETE FROM ado_s8_order_flow_manufacturing_loss_factor
+WHERE tenant_id = 1 AND factory_id = 1 AND is_deleted = 0
+  AND data_source = 'SEED'
+  AND scenario_code IN ('BASELINE_PPT', 'ORDER_LEVEL');
+
+DELETE FROM ado_s8_order_flow_manufacturing_operator
+WHERE tenant_id = 1 AND factory_id = 1 AND is_deleted = 0
+  AND data_source = 'SEED'
+  AND scenario_code IN ('BASELINE_PPT', 'ORDER_LEVEL');
+
+-- ============================================================
+-- INSERT:baseline (5+5+3) + order-level (16 单 × (5+5+3) = 208) = 221 行
+-- 数据由 /tmp/gen_s8_body_production_seed_sql.py 生成(严格复刻
+-- S8OrderFlowManufacturingSeedData.cs 算法 + S8-...-FIX-1R TOTAL.rate 锚定)。
+--
+-- baseline 行:order_id=NULL,scenario_code='BASELINE_PPT',与 MANUFACTURING_DETAIL_FIXTURE 逐字段一致。
+-- order-level 行:order_id=OrderIdBase+spec.Idx,scenario_code='ORDER_LEVEL';
+--   每非 pending 单按 ratio=A/6.8 缩放 process/loss/operator;
+--   process TOTAL.rate=0.9000/yellow 锚定 fixture(不再 plan_qty 加权);
+--   守恒:Σ(P10..P40 actual) = TOTAL.actual = stage.actual_days;
+--   pending 单 016/017/018/019 不生成 order-level 行。
+-- ============================================================
+
+-- ─── ado_s8_order_flow_manufacturing_process: 85 行 ───
+INSERT INTO ado_s8_order_flow_manufacturing_process
+  (id, order_id, order_code, process_code, process_name, pi_days, actual_days, cycle_status, plan_qty, achievement_rate, achievement_status, sort_no, scenario_code, data_source, tenant_id, factory_id, created_at, updated_at, is_deleted)
+VALUES
+  (1329909160001, NULL, NULL, 'P10', '10工序', 1.000, 2.400, 'red', 45, 0.5500, 'red', 1, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909160002, NULL, NULL, 'P20', '20工序', 1.000, 0.800, 'green', 3, 0.9700, 'yellow', 2, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909160003, NULL, NULL, 'P30', '30工序', 2.500, 3.000, 'yellow', 15, 0.8500, 'green', 3, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909160004, NULL, NULL, 'P40', '40工序', 1.500, 0.600, 'green', 2, 0.9800, 'red', 4, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909160005, NULL, NULL, 'TOTAL', '合计', 6.000, 6.800, 'yellow', NULL, 0.9000, 'yellow', 5, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170001, 1329909100001, 'SO-2026-001', 'P10', '10工序', 1.000, 1.765, 'red', 33, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170002, 1329909100001, 'SO-2026-001', 'P20', '20工序', 1.000, 0.588, 'green', 2, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170003, 1329909100001, 'SO-2026-001', 'P30', '30工序', 2.500, 2.206, 'green', 11, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170004, 1329909100001, 'SO-2026-001', 'P40', '40工序', 1.500, 0.441, 'green', 1, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170005, 1329909100001, 'SO-2026-001', 'TOTAL', '合计', 6.000, 5.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170006, 1329909100002, 'SO-2026-002', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170007, 1329909100002, 'SO-2026-002', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170008, 1329909100002, 'SO-2026-002', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170009, 1329909100002, 'SO-2026-002', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170010, 1329909100002, 'SO-2026-002', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170011, 1329909100003, 'SO-2026-003', 'P10', '10工序', 1.000, 2.824, 'red', 53, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170012, 1329909100003, 'SO-2026-003', 'P20', '20工序', 1.000, 0.941, 'green', 4, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170013, 1329909100003, 'SO-2026-003', 'P30', '30工序', 2.500, 3.529, 'red', 18, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170014, 1329909100003, 'SO-2026-003', 'P40', '40工序', 1.500, 0.706, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170015, 1329909100003, 'SO-2026-003', 'TOTAL', '合计', 6.000, 8.000, 'red', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170016, 1329909100004, 'SO-2026-004', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170017, 1329909100004, 'SO-2026-004', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170018, 1329909100004, 'SO-2026-004', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170019, 1329909100004, 'SO-2026-004', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170020, 1329909100004, 'SO-2026-004', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170021, 1329909100005, 'SO-2026-005', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170022, 1329909100005, 'SO-2026-005', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170023, 1329909100005, 'SO-2026-005', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170024, 1329909100005, 'SO-2026-005', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170025, 1329909100005, 'SO-2026-005', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170026, 1329909100006, 'SO-2026-006', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170027, 1329909100006, 'SO-2026-006', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170028, 1329909100006, 'SO-2026-006', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170029, 1329909100006, 'SO-2026-006', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170030, 1329909100006, 'SO-2026-006', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170031, 1329909100007, 'SO-2026-007', 'P10', '10工序', 1.000, 2.824, 'red', 53, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170032, 1329909100007, 'SO-2026-007', 'P20', '20工序', 1.000, 0.941, 'green', 4, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170033, 1329909100007, 'SO-2026-007', 'P30', '30工序', 2.500, 3.529, 'red', 18, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170034, 1329909100007, 'SO-2026-007', 'P40', '40工序', 1.500, 0.706, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170035, 1329909100007, 'SO-2026-007', 'TOTAL', '合计', 6.000, 8.000, 'red', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170036, 1329909100008, 'SO-2026-008', 'P10', '10工序', 1.000, 2.824, 'red', 53, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170037, 1329909100008, 'SO-2026-008', 'P20', '20工序', 1.000, 0.941, 'green', 4, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170038, 1329909100008, 'SO-2026-008', 'P30', '30工序', 2.500, 3.529, 'red', 18, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170039, 1329909100008, 'SO-2026-008', 'P40', '40工序', 1.500, 0.706, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170040, 1329909100008, 'SO-2026-008', 'TOTAL', '合计', 6.000, 8.000, 'red', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170041, 1329909100009, 'SO-2026-009', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170042, 1329909100009, 'SO-2026-009', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170043, 1329909100009, 'SO-2026-009', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170044, 1329909100009, 'SO-2026-009', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170045, 1329909100009, 'SO-2026-009', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170046, 1329909100010, 'SO-2026-010', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170047, 1329909100010, 'SO-2026-010', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170048, 1329909100010, 'SO-2026-010', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170049, 1329909100010, 'SO-2026-010', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170050, 1329909100010, 'SO-2026-010', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170051, 1329909100011, 'SO-2026-011', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170052, 1329909100011, 'SO-2026-011', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170053, 1329909100011, 'SO-2026-011', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170054, 1329909100011, 'SO-2026-011', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170055, 1329909100011, 'SO-2026-011', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170056, 1329909100012, 'SO-2026-012', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170057, 1329909100012, 'SO-2026-012', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170058, 1329909100012, 'SO-2026-012', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170059, 1329909100012, 'SO-2026-012', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170060, 1329909100012, 'SO-2026-012', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170061, 1329909100013, 'SO-2026-013', 'P10', '10工序', 1.000, 2.824, 'red', 53, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170062, 1329909100013, 'SO-2026-013', 'P20', '20工序', 1.000, 0.941, 'green', 4, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170063, 1329909100013, 'SO-2026-013', 'P30', '30工序', 2.500, 3.529, 'red', 18, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170064, 1329909100013, 'SO-2026-013', 'P40', '40工序', 1.500, 0.706, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170065, 1329909100013, 'SO-2026-013', 'TOTAL', '合计', 6.000, 8.000, 'red', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170066, 1329909100014, 'SO-2026-014', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170067, 1329909100014, 'SO-2026-014', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170068, 1329909100014, 'SO-2026-014', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170069, 1329909100014, 'SO-2026-014', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170070, 1329909100014, 'SO-2026-014', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170071, 1329909100015, 'SO-2026-015', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170072, 1329909100015, 'SO-2026-015', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170073, 1329909100015, 'SO-2026-015', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170074, 1329909100015, 'SO-2026-015', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170075, 1329909100015, 'SO-2026-015', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170076, 1329909100020, 'SO-2026-020', 'P10', '10工序', 1.000, 2.118, 'red', 40, 0.5500, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170077, 1329909100020, 'SO-2026-020', 'P20', '20工序', 1.000, 0.706, 'green', 3, 0.9700, 'green', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170078, 1329909100020, 'SO-2026-020', 'P30', '30工序', 2.500, 2.647, 'yellow', 13, 0.8500, 'yellow', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170079, 1329909100020, 'SO-2026-020', 'P40', '40工序', 1.500, 0.529, 'green', 2, 0.9800, 'green', 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909170080, 1329909100020, 'SO-2026-020', 'TOTAL', '合计', 6.000, 6.000, 'green', NULL, 0.9000, 'yellow', 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0);
+
+-- ─── ado_s8_order_flow_manufacturing_loss_factor: 85 行 ───
+INSERT INTO ado_s8_order_flow_manufacturing_loss_factor
+  (id, order_id, order_code, factor_code, factor_name, count_value, ratio_pct, loss_hours, sort_no, scenario_code, data_source, tenant_id, factory_id, created_at, updated_at, is_deleted)
+VALUES
+  (1329909180001, NULL, NULL, 'MATERIAL', '材料影响', 9, 30.00, 9.00, 1, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909180002, NULL, NULL, 'EQUIPMENT', '设备影响', 6, 20.00, 4.50, 2, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909180003, NULL, NULL, 'QUALITY', '质量影响', 3, 10.00, 3.40, 3, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909180004, NULL, NULL, 'EFFICIENCY', '作业效率损失', 12, 40.00, 9.25, 4, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909180005, NULL, NULL, 'SUBTOTAL', '损失小计', 30, 100.00, 7.50, 5, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190001, 1329909100001, 'SO-2026-001', 'MATERIAL', '材料影响', 7, 30.00, 6.62, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190002, 1329909100001, 'SO-2026-001', 'EQUIPMENT', '设备影响', 4, 20.00, 3.31, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190003, 1329909100001, 'SO-2026-001', 'QUALITY', '质量影响', 2, 10.00, 2.50, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190004, 1329909100001, 'SO-2026-001', 'EFFICIENCY', '作业效率损失', 9, 40.00, 6.80, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190005, 1329909100001, 'SO-2026-001', 'SUBTOTAL', '损失小计', 22, 100.00, 5.51, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190006, 1329909100002, 'SO-2026-002', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190007, 1329909100002, 'SO-2026-002', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190008, 1329909100002, 'SO-2026-002', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190009, 1329909100002, 'SO-2026-002', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190010, 1329909100002, 'SO-2026-002', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190011, 1329909100003, 'SO-2026-003', 'MATERIAL', '材料影响', 11, 30.00, 10.59, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190012, 1329909100003, 'SO-2026-003', 'EQUIPMENT', '设备影响', 7, 20.00, 5.29, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190013, 1329909100003, 'SO-2026-003', 'QUALITY', '质量影响', 4, 10.00, 4.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190014, 1329909100003, 'SO-2026-003', 'EFFICIENCY', '作业效率损失', 14, 40.00, 10.88, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190015, 1329909100003, 'SO-2026-003', 'SUBTOTAL', '损失小计', 35, 100.00, 8.82, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190016, 1329909100004, 'SO-2026-004', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190017, 1329909100004, 'SO-2026-004', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190018, 1329909100004, 'SO-2026-004', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190019, 1329909100004, 'SO-2026-004', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190020, 1329909100004, 'SO-2026-004', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190021, 1329909100005, 'SO-2026-005', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190022, 1329909100005, 'SO-2026-005', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190023, 1329909100005, 'SO-2026-005', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190024, 1329909100005, 'SO-2026-005', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190025, 1329909100005, 'SO-2026-005', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190026, 1329909100006, 'SO-2026-006', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190027, 1329909100006, 'SO-2026-006', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190028, 1329909100006, 'SO-2026-006', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190029, 1329909100006, 'SO-2026-006', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190030, 1329909100006, 'SO-2026-006', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190031, 1329909100007, 'SO-2026-007', 'MATERIAL', '材料影响', 11, 30.00, 10.59, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190032, 1329909100007, 'SO-2026-007', 'EQUIPMENT', '设备影响', 7, 20.00, 5.29, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190033, 1329909100007, 'SO-2026-007', 'QUALITY', '质量影响', 4, 10.00, 4.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190034, 1329909100007, 'SO-2026-007', 'EFFICIENCY', '作业效率损失', 14, 40.00, 10.88, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190035, 1329909100007, 'SO-2026-007', 'SUBTOTAL', '损失小计', 35, 100.00, 8.82, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190036, 1329909100008, 'SO-2026-008', 'MATERIAL', '材料影响', 11, 30.00, 10.59, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190037, 1329909100008, 'SO-2026-008', 'EQUIPMENT', '设备影响', 7, 20.00, 5.29, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190038, 1329909100008, 'SO-2026-008', 'QUALITY', '质量影响', 4, 10.00, 4.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190039, 1329909100008, 'SO-2026-008', 'EFFICIENCY', '作业效率损失', 14, 40.00, 10.88, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190040, 1329909100008, 'SO-2026-008', 'SUBTOTAL', '损失小计', 35, 100.00, 8.82, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190041, 1329909100009, 'SO-2026-009', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190042, 1329909100009, 'SO-2026-009', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190043, 1329909100009, 'SO-2026-009', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190044, 1329909100009, 'SO-2026-009', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190045, 1329909100009, 'SO-2026-009', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190046, 1329909100010, 'SO-2026-010', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190047, 1329909100010, 'SO-2026-010', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190048, 1329909100010, 'SO-2026-010', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190049, 1329909100010, 'SO-2026-010', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190050, 1329909100010, 'SO-2026-010', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190051, 1329909100011, 'SO-2026-011', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190052, 1329909100011, 'SO-2026-011', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190053, 1329909100011, 'SO-2026-011', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190054, 1329909100011, 'SO-2026-011', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190055, 1329909100011, 'SO-2026-011', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190056, 1329909100012, 'SO-2026-012', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190057, 1329909100012, 'SO-2026-012', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190058, 1329909100012, 'SO-2026-012', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190059, 1329909100012, 'SO-2026-012', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190060, 1329909100012, 'SO-2026-012', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190061, 1329909100013, 'SO-2026-013', 'MATERIAL', '材料影响', 11, 30.00, 10.59, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190062, 1329909100013, 'SO-2026-013', 'EQUIPMENT', '设备影响', 7, 20.00, 5.29, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190063, 1329909100013, 'SO-2026-013', 'QUALITY', '质量影响', 4, 10.00, 4.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190064, 1329909100013, 'SO-2026-013', 'EFFICIENCY', '作业效率损失', 14, 40.00, 10.88, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190065, 1329909100013, 'SO-2026-013', 'SUBTOTAL', '损失小计', 35, 100.00, 8.82, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190066, 1329909100014, 'SO-2026-014', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190067, 1329909100014, 'SO-2026-014', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190068, 1329909100014, 'SO-2026-014', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190069, 1329909100014, 'SO-2026-014', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190070, 1329909100014, 'SO-2026-014', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190071, 1329909100015, 'SO-2026-015', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190072, 1329909100015, 'SO-2026-015', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190073, 1329909100015, 'SO-2026-015', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190074, 1329909100015, 'SO-2026-015', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190075, 1329909100015, 'SO-2026-015', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190076, 1329909100020, 'SO-2026-020', 'MATERIAL', '材料影响', 8, 30.00, 7.94, 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190077, 1329909100020, 'SO-2026-020', 'EQUIPMENT', '设备影响', 5, 20.00, 3.97, 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190078, 1329909100020, 'SO-2026-020', 'QUALITY', '质量影响', 3, 10.00, 3.00, 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190079, 1329909100020, 'SO-2026-020', 'EFFICIENCY', '作业效率损失', 11, 40.00, 8.16, 4, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909190080, 1329909100020, 'SO-2026-020', 'SUBTOTAL', '损失小计', 26, 100.00, 6.62, 5, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0);
+
+-- ─── ado_s8_order_flow_manufacturing_operator: 51 行 ───
+INSERT INTO ado_s8_order_flow_manufacturing_operator
+  (id, order_id, order_code, operator_code, operator_name, avg_hours, status, sort_no, scenario_code, data_source, tenant_id, factory_id, created_at, updated_at, is_deleted)
+VALUES
+  (1329909200001, NULL, NULL, 'OP_ZHANG', '张师傅', 20.00, 'red', 1, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909200002, NULL, NULL, 'OP_LI', '李师傅', 10.00, 'yellow', 2, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909200003, NULL, NULL, 'OP_WANG', '王师傅', 8.00, 'green', 3, 'BASELINE_PPT', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210001, 1329909100001, 'SO-2026-001', 'OP_ZHANG', '张师傅', 14.71, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210002, 1329909100001, 'SO-2026-001', 'OP_LI', '李师傅', 7.35, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210003, 1329909100001, 'SO-2026-001', 'OP_WANG', '王师傅', 5.88, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210004, 1329909100002, 'SO-2026-002', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210005, 1329909100002, 'SO-2026-002', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210006, 1329909100002, 'SO-2026-002', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210007, 1329909100003, 'SO-2026-003', 'OP_ZHANG', '张师傅', 23.53, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210008, 1329909100003, 'SO-2026-003', 'OP_LI', '李师傅', 11.76, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210009, 1329909100003, 'SO-2026-003', 'OP_WANG', '王师傅', 9.41, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210010, 1329909100004, 'SO-2026-004', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210011, 1329909100004, 'SO-2026-004', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210012, 1329909100004, 'SO-2026-004', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210013, 1329909100005, 'SO-2026-005', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210014, 1329909100005, 'SO-2026-005', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210015, 1329909100005, 'SO-2026-005', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210016, 1329909100006, 'SO-2026-006', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210017, 1329909100006, 'SO-2026-006', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210018, 1329909100006, 'SO-2026-006', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210019, 1329909100007, 'SO-2026-007', 'OP_ZHANG', '张师傅', 23.53, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210020, 1329909100007, 'SO-2026-007', 'OP_LI', '李师傅', 11.76, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210021, 1329909100007, 'SO-2026-007', 'OP_WANG', '王师傅', 9.41, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210022, 1329909100008, 'SO-2026-008', 'OP_ZHANG', '张师傅', 23.53, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210023, 1329909100008, 'SO-2026-008', 'OP_LI', '李师傅', 11.76, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210024, 1329909100008, 'SO-2026-008', 'OP_WANG', '王师傅', 9.41, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210025, 1329909100009, 'SO-2026-009', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210026, 1329909100009, 'SO-2026-009', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210027, 1329909100009, 'SO-2026-009', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210028, 1329909100010, 'SO-2026-010', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210029, 1329909100010, 'SO-2026-010', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210030, 1329909100010, 'SO-2026-010', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210031, 1329909100011, 'SO-2026-011', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210032, 1329909100011, 'SO-2026-011', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210033, 1329909100011, 'SO-2026-011', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210034, 1329909100012, 'SO-2026-012', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210035, 1329909100012, 'SO-2026-012', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210036, 1329909100012, 'SO-2026-012', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210037, 1329909100013, 'SO-2026-013', 'OP_ZHANG', '张师傅', 23.53, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210038, 1329909100013, 'SO-2026-013', 'OP_LI', '李师傅', 11.76, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210039, 1329909100013, 'SO-2026-013', 'OP_WANG', '王师傅', 9.41, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210040, 1329909100014, 'SO-2026-014', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210041, 1329909100014, 'SO-2026-014', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210042, 1329909100014, 'SO-2026-014', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210043, 1329909100015, 'SO-2026-015', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210044, 1329909100015, 'SO-2026-015', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210045, 1329909100015, 'SO-2026-015', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210046, 1329909100020, 'SO-2026-020', 'OP_ZHANG', '张师傅', 17.65, 'red', 1, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210047, 1329909100020, 'SO-2026-020', 'OP_LI', '李师傅', 8.82, 'yellow', 2, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0),
+  (1329909210048, 1329909100020, 'SO-2026-020', 'OP_WANG', '王师傅', 7.06, 'green', 3, 'ORDER_LEVEL', 'SEED', 1, 1, '2026-05-12 00:00:00', NULL, 0);

+ 15 - 0
server/Admin.NET.Web.Entry/UpdateScripts/1.0.151.sql

@@ -0,0 +1,15 @@
+-- ──────────────────────────────────────────────────────────────────────
+-- S0-SALES-MENU-TITLE-ALIGNMENT-1
+-- 对齐 S0 / 产销建模 3 项菜单显示文案到外部口径标准。
+--   1329002000001 客户管理       → 客户信息维护
+--   1329002000002 物料管理       → 物料维护列表
+--   1329002000003 订单优先规则   → 订单优先级配置
+-- 仅文案对齐;不动 path / name / component / icon / pid / type / id。
+-- 与 SysMenuSeedData.cs:BuildS0SalesMenus 同步;种子 [IncreSeed] 对已入库行不覆盖,
+-- 故需 SQL 显式 UPDATE 已部署实例的 SysMenu 行。
+-- 幂等:重复执行无副作用;行不存在时 UPDATE 返回 0 affected 不报错。
+-- ──────────────────────────────────────────────────────────────────────
+
+UPDATE SysMenu SET title='客户信息维护',   remark='S0 客户信息维护'   WHERE id=1329002000001;
+UPDATE SysMenu SET title='物料维护列表',   remark='S0 物料维护列表'   WHERE id=1329002000002;
+UPDATE SysMenu SET title='订单优先级配置', remark='S0 订单优先级配置' WHERE id=1329002000003;

+ 24 - 0
server/Admin.NET.Web.Entry/UpdateScripts/1.0.152.sql

@@ -0,0 +1,24 @@
+-- S1 MDP:补登记产品设计三实体(与 S1MdpEntityConfig 对齐)
+-- 幂等:ON DUPLICATE KEY UPDATE
+
+SET @tenant_id := 0;
+SET @source_id := (SELECT id FROM mdp_source WHERE tenant_id = @tenant_id AND source_code = 'AIDOPDEV_MYSQL' LIMIT 1);
+
+INSERT INTO mdp_entity
+(tenant_id, source_id, entity_code, entity_name, entity_type, source_table_name, target_table_name, sync_mode, incr_column, batch_size, status, remark)
+VALUES
+(@tenant_id, @source_id, 'S1_PRODUCT_DESIGN', 'S1产品设计主表', 'TABLE', 'ado_product_design', 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, '产品设计主表,进入订单标准层'),
+(@tenant_id, @source_id, 'S1_PRODUCT_DESIGN_BOM', 'S1产品设计BOM', 'TABLE', 'ado_product_design_bom', 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, '产品设计BOM,进入订单标准层'),
+(@tenant_id, @source_id, 'S1_PRODUCT_DESIGN_ROUTING', 'S1产品设计工艺路线', 'TABLE', 'ado_product_design_routing', 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, '产品设计工艺路线,进入订单标准层')
+ON DUPLICATE KEY UPDATE
+    source_id = VALUES(source_id),
+    entity_name = VALUES(entity_name),
+    entity_type = VALUES(entity_type),
+    source_table_name = VALUES(source_table_name),
+    target_table_name = VALUES(target_table_name),
+    sync_mode = VALUES(sync_mode),
+    incr_column = VALUES(incr_column),
+    batch_size = VALUES(batch_size),
+    status = VALUES(status),
+    remark = VALUES(remark),
+    update_time = CURRENT_TIMESTAMP;

+ 10 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/S8/AdoS8OrderFlowController.cs

@@ -60,4 +60,14 @@ public class AdoS8OrderFlowController : ControllerBase
     public async Task<IActionResult> ProductDesignDrawingsAsync(
         [FromQuery] AdoS8OrderFlowProductDesignDrawingsQueryDto query)
         => Ok(await _svc.GetProductDesignDrawingsAsync(query));
+
+    /// <summary>
+    /// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:本体生产透视。
+    /// scope=BASELINE_PPT 读三表 baseline 行;scope=CURRENT_FILTERED 按 orderCodes CSV 取订单级行并聚合。
+    /// orderCodes 为空(CURRENT_FILTERED)时返回空骨架,不静默 fallback baseline。
+    /// </summary>
+    [HttpGet("manufacturing-pivot")]
+    public async Task<IActionResult> ManufacturingPivotAsync(
+        [FromQuery] AdoS8OrderFlowManufacturingPivotQueryDto query)
+        => Ok(await _svc.GetManufacturingPivotAsync(query));
 }

+ 68 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Dto/S8/OrderFlow/AdoS8OrderFlowDtos.cs

@@ -351,3 +351,71 @@ public class AdoS8OrderFlowProductDesignDrawingsDto
 }
 
 #endregion
+
+#region 本体生产(设备制造) — S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1
+
+/// <summary>
+/// 本体生产「工序明细 / 损失因素 / 操作员表现」三表透视查询入参。
+/// orderCodes CSV:与产品设计 drawings API、采购透视 API 对齐,避免 axios brackets 与 ASP.NET Core List 绑定二义性。
+/// scope=BASELINE_PPT 时 orderCodes 忽略;scope=CURRENT_FILTERED 时 orderCodes 为空返回空骨架(不静默 fallback baseline)。
+/// </summary>
+public class AdoS8OrderFlowManufacturingPivotQueryDto
+{
+    public long? TenantId { get; set; }
+    public long? FactoryId { get; set; }
+    /// <summary>BASELINE_PPT | CURRENT_FILTERED</summary>
+    public string Scope { get; set; } = string.Empty;
+    /// <summary>逗号分隔订单号;scope=CURRENT_FILTERED 时使用。</summary>
+    public string? OrderCodes { get; set; }
+}
+
+/// <summary>
+/// 工序明细行:P10 / P20 / P30 / P40 / TOTAL。
+/// pi_days / actual_days 保留 decimal(6,3) 精度;plan_qty 在 TOTAL 行为 null。
+/// achievement_rate 在 TOTAL 行 baseline 来自 fixture(0.9000)、订单级按 plan_qty 加权平均;其它行 baseline 复用。
+/// </summary>
+public class AdoS8OrderFlowManufacturingProcessDto
+{
+    public string ProcessCode { get; set; } = string.Empty;
+    public string ProcessName { get; set; } = string.Empty;
+    public decimal PiDays { get; set; }
+    public decimal ActualDays { get; set; }
+    public string CycleStatus { get; set; } = string.Empty;
+    public int? PlanQty { get; set; }
+    public decimal? AchievementRate { get; set; }
+    public string AchievementStatus { get; set; } = string.Empty;
+    public int SortNo { get; set; }
+}
+
+/// <summary>损失因素行:MATERIAL / EQUIPMENT / QUALITY / EFFICIENCY / SUBTOTAL。</summary>
+public class AdoS8OrderFlowManufacturingLossFactorDto
+{
+    public string FactorCode { get; set; } = string.Empty;
+    public string FactorName { get; set; } = string.Empty;
+    public int? CountValue { get; set; }
+    public decimal? RatioPct { get; set; }
+    public decimal? LossHours { get; set; }
+    public int SortNo { get; set; }
+}
+
+/// <summary>操作员表现行:OP_ZHANG / OP_LI / OP_WANG。</summary>
+public class AdoS8OrderFlowManufacturingOperatorDto
+{
+    public string OperatorCode { get; set; } = string.Empty;
+    public string OperatorName { get; set; } = string.Empty;
+    public decimal AvgHours { get; set; }
+    public string Status { get; set; } = string.Empty;
+    public int SortNo { get; set; }
+}
+
+/// <summary>本体生产透视聚合结果:scope + 工序 / 损失 / 操作员 三组。</summary>
+public class AdoS8OrderFlowManufacturingPivotDto
+{
+    /// <summary>BASELINE_PPT | CURRENT_FILTERED</summary>
+    public string Scope { get; set; } = string.Empty;
+    public List<AdoS8OrderFlowManufacturingProcessDto> Processes { get; set; } = new();
+    public List<AdoS8OrderFlowManufacturingLossFactorDto> LossFactors { get; set; } = new();
+    public List<AdoS8OrderFlowManufacturingOperatorDto> Operators { get; set; } = new();
+}
+
+#endregion

+ 2 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S0/Manufacturing/AdoS0ProductStructure.cs

@@ -2,7 +2,9 @@ namespace Admin.NET.Plugin.AiDOP.Entity.S0.Manufacturing;
 
 /// <summary>
 /// 标准 BOM 行维护(复刻 ProductStructureMaster,路线 A)。
+/// 标 IgnoreTable 避免框架层 CodeFirst 介入 ProductStructureMaster legacy 表 schema(历史 NULL 数据触发 ALTER NOT NULL 失败)。
 /// </summary>
+[IgnoreTable]
 [SugarTable("ProductStructureMaster", "标准BOM行维护(复刻 ProductStructureMaster)")]
 [SugarIndex("ix_ProductStructureMaster_factory_parent", nameof(CompanyRefId), OrderByType.Asc, nameof(FactoryRefId), OrderByType.Asc, nameof(ParentMaterialId), OrderByType.Asc)]
 public class AdoS0ProductStructureMaster : ITenantIdFilter

+ 75 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowManufacturingLossFactor.cs

@@ -0,0 +1,75 @@
+namespace Admin.NET.Plugin.AiDOP.Entity.S8.OrderFlow;
+
+/// <summary>
+/// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:
+/// S8 订单执行链路本体生产「损失因素」表(baseline + 订单级 SEED)。
+///
+/// factor_code 取值:MATERIAL / EQUIPMENT / QUALITY / EFFICIENCY / SUBTOTAL(小计行 sort_no=5)。
+///   - count_value:baseline 9/6/3/12/30;订单级 round(baseline * ratio)。
+///   - ratio_pct:baseline 30/20/10/40/100,订单级保持结构(按用户规则原值复制)。
+///   - loss_hours:baseline 9.00/4.50/3.40/9.25/7.50(SUBTOTAL 7.50 来自 fixture,不是 4 因素之和);订单级 round(baseline*ratio,2)。
+/// </summary>
+[SugarTable("ado_s8_order_flow_manufacturing_loss_factor", "S8 订单执行链路本体生产损失因素")]
+[SugarIndex("idx_order_flow_mfg_loss_baseline", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(FactorCode), OrderByType.Asc)]
+[SugarIndex("idx_order_flow_mfg_loss_order", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(OrderCode), OrderByType.Asc)]
+[SugarIndex("idx_order_flow_mfg_loss_scenario", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(ScenarioCode), OrderByType.Asc, nameof(IsDeleted), OrderByType.Asc)]
+public class AdoS8OrderFlowManufacturingLossFactor
+{
+    [SugarColumn(ColumnName = "id", IsPrimaryKey = true, ColumnDataType = "bigint")]
+    public long Id { get; set; }
+
+    /// <summary>NULL = baseline 行;非 NULL = 订单级行。</summary>
+    [SugarColumn(ColumnName = "order_id", ColumnDataType = "bigint", IsNullable = true)]
+    public long? OrderId { get; set; }
+
+    /// <summary>NULL = baseline 行;非 NULL = 订单业务键。</summary>
+    [SugarColumn(ColumnName = "order_code", Length = 64, IsNullable = true)]
+    public string? OrderCode { get; set; }
+
+    /// <summary>因素编码:MATERIAL / EQUIPMENT / QUALITY / EFFICIENCY / SUBTOTAL。</summary>
+    [SugarColumn(ColumnName = "factor_code", Length = 32)]
+    public string FactorCode { get; set; } = string.Empty;
+
+    /// <summary>因素名称:材料影响 / 设备影响 / 质量影响 / 作业效率损失 / 损失小计。</summary>
+    [SugarColumn(ColumnName = "factor_name", Length = 32)]
+    public string FactorName { get; set; } = string.Empty;
+
+    /// <summary>件数。baseline 9/6/3/12/30;订单级 round(baseline*ratio)。SUBTOTAL = 30*ratio。</summary>
+    [SugarColumn(ColumnName = "count_value", ColumnDataType = "int", IsNullable = true)]
+    public int? CountValue { get; set; }
+
+    /// <summary>占比百分比(0~100)。baseline 30/20/10/40/100;订单级保持结构(复制 baseline 值)。decimal(5,2)。</summary>
+    [SugarColumn(ColumnName = "ratio_pct", DecimalDigits = 2, Length = 5, IsNullable = true)]
+    public decimal? RatioPct { get; set; }
+
+    /// <summary>损失工时(小时)。baseline 9.00/4.50/3.40/9.25/7.50;订单级 round(baseline*ratio,2)。decimal(8,2)。</summary>
+    [SugarColumn(ColumnName = "loss_hours", DecimalDigits = 2, Length = 8, IsNullable = true)]
+    public decimal? LossHours { get; set; }
+
+    /// <summary>排序号 1..5(材料/设备/质量/效率/小计)。</summary>
+    [SugarColumn(ColumnName = "sort_no", ColumnDataType = "int")]
+    public int SortNo { get; set; }
+
+    /// <summary>BASELINE_PPT / ORDER_LEVEL。</summary>
+    [SugarColumn(ColumnName = "scenario_code", Length = 16)]
+    public string ScenarioCode { get; set; } = "BASELINE_PPT";
+
+    /// <summary>SEED / IMPORT / AGG。</summary>
+    [SugarColumn(ColumnName = "data_source", Length = 16)]
+    public string DataSource { get; set; } = "SEED";
+
+    [SugarColumn(ColumnName = "tenant_id", ColumnDataType = "bigint")]
+    public long TenantId { get; set; }
+
+    [SugarColumn(ColumnName = "factory_id", ColumnDataType = "bigint")]
+    public long FactoryId { get; set; }
+
+    [SugarColumn(ColumnName = "created_at")]
+    public DateTime CreatedAt { get; set; } = DateTime.Now;
+
+    [SugarColumn(ColumnName = "updated_at", IsNullable = true)]
+    public DateTime? UpdatedAt { get; set; }
+
+    [SugarColumn(ColumnName = "is_deleted", ColumnDataType = "boolean")]
+    public bool IsDeleted { get; set; }
+}

+ 70 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowManufacturingOperator.cs

@@ -0,0 +1,70 @@
+namespace Admin.NET.Plugin.AiDOP.Entity.S8.OrderFlow;
+
+/// <summary>
+/// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:
+/// S8 订单执行链路本体生产「操作员表现」表(baseline + 订单级 SEED)。
+///
+/// operator_code 取值:OP_ZHANG / OP_LI / OP_WANG(演示固定 3 个操作员)。
+///   - avg_hours:baseline 20.00/10.00/8.00;订单级 round(baseline*ratio,2)。
+///   - status:baseline red/yellow/green(按 fixture 颜色固化);订单级保持每个操作员的 status(按用户规则结构保留)。
+/// </summary>
+[SugarTable("ado_s8_order_flow_manufacturing_operator", "S8 订单执行链路本体生产操作员表现")]
+[SugarIndex("idx_order_flow_mfg_operator_baseline", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(OperatorCode), OrderByType.Asc)]
+[SugarIndex("idx_order_flow_mfg_operator_order", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(OrderCode), OrderByType.Asc)]
+[SugarIndex("idx_order_flow_mfg_operator_scenario", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(ScenarioCode), OrderByType.Asc, nameof(IsDeleted), OrderByType.Asc)]
+public class AdoS8OrderFlowManufacturingOperator
+{
+    [SugarColumn(ColumnName = "id", IsPrimaryKey = true, ColumnDataType = "bigint")]
+    public long Id { get; set; }
+
+    /// <summary>NULL = baseline 行;非 NULL = 订单级行。</summary>
+    [SugarColumn(ColumnName = "order_id", ColumnDataType = "bigint", IsNullable = true)]
+    public long? OrderId { get; set; }
+
+    /// <summary>NULL = baseline 行;非 NULL = 订单业务键。</summary>
+    [SugarColumn(ColumnName = "order_code", Length = 64, IsNullable = true)]
+    public string? OrderCode { get; set; }
+
+    /// <summary>操作员编码:OP_ZHANG / OP_LI / OP_WANG。</summary>
+    [SugarColumn(ColumnName = "operator_code", Length = 32)]
+    public string OperatorCode { get; set; } = string.Empty;
+
+    /// <summary>操作员姓名:张师傅 / 李师傅 / 王师傅。</summary>
+    [SugarColumn(ColumnName = "operator_name", Length = 64)]
+    public string OperatorName { get; set; } = string.Empty;
+
+    /// <summary>平均工时(小时)。baseline 20.00/10.00/8.00;订单级 round(baseline*ratio,2)。decimal(6,2)。</summary>
+    [SugarColumn(ColumnName = "avg_hours", DecimalDigits = 2, Length = 6)]
+    public decimal AvgHours { get; set; }
+
+    /// <summary>状态:green / yellow / red(按操作员固化;订单级复用 baseline 同色)。</summary>
+    [SugarColumn(ColumnName = "status", Length = 16)]
+    public string Status { get; set; } = "green";
+
+    /// <summary>排序号 1..3。</summary>
+    [SugarColumn(ColumnName = "sort_no", ColumnDataType = "int")]
+    public int SortNo { get; set; }
+
+    /// <summary>BASELINE_PPT / ORDER_LEVEL。</summary>
+    [SugarColumn(ColumnName = "scenario_code", Length = 16)]
+    public string ScenarioCode { get; set; } = "BASELINE_PPT";
+
+    /// <summary>SEED / IMPORT / AGG。</summary>
+    [SugarColumn(ColumnName = "data_source", Length = 16)]
+    public string DataSource { get; set; } = "SEED";
+
+    [SugarColumn(ColumnName = "tenant_id", ColumnDataType = "bigint")]
+    public long TenantId { get; set; }
+
+    [SugarColumn(ColumnName = "factory_id", ColumnDataType = "bigint")]
+    public long FactoryId { get; set; }
+
+    [SugarColumn(ColumnName = "created_at")]
+    public DateTime CreatedAt { get; set; } = DateTime.Now;
+
+    [SugarColumn(ColumnName = "updated_at", IsNullable = true)]
+    public DateTime? UpdatedAt { get; set; }
+
+    [SugarColumn(ColumnName = "is_deleted", ColumnDataType = "boolean")]
+    public bool IsDeleted { get; set; }
+}

+ 91 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/OrderFlow/AdoS8OrderFlowManufacturingProcess.cs

@@ -0,0 +1,91 @@
+namespace Admin.NET.Plugin.AiDOP.Entity.S8.OrderFlow;
+
+/// <summary>
+/// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:
+/// S8 订单执行链路本体生产「工序明细」表(baseline + 订单级 SEED)。
+///
+/// order_id / order_code 允许为空:
+///   - NULL → baseline / PPT 级别基线行(scenario_code=BASELINE_PPT)
+///   - 非 NULL → 订单级行(scenario_code=ORDER_LEVEL)
+///
+/// process_code 取值:P10 / P20 / P30 / P40 / TOTAL(合计行 sort_no=5)。
+/// pi_days / actual_days 使用 decimal(6,3) 承载 1 工序 0.441 等尾差修正后的 3 位小数精度。
+/// achievement_rate 使用 decimal(5,4),取值范围 0.0000~1.0000;TOTAL 行 baseline 来自 fixture(0.90 黄)、订单级按 plan_qty 加权平均。
+/// achievement_status 来自 fixture 表格颜色(baseline)或 ≥0.95 green / ≥0.80 yellow / 否则 red(订单级派生)。
+/// </summary>
+[SugarTable("ado_s8_order_flow_manufacturing_process", "S8 订单执行链路本体生产工序明细")]
+[SugarIndex("idx_order_flow_mfg_process_baseline", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(ProcessCode), OrderByType.Asc)]
+[SugarIndex("idx_order_flow_mfg_process_order", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(OrderCode), OrderByType.Asc)]
+[SugarIndex("idx_order_flow_mfg_process_scenario", nameof(TenantId), OrderByType.Asc, nameof(FactoryId), OrderByType.Asc, nameof(ScenarioCode), OrderByType.Asc, nameof(IsDeleted), OrderByType.Asc)]
+public class AdoS8OrderFlowManufacturingProcess
+{
+    [SugarColumn(ColumnName = "id", IsPrimaryKey = true, ColumnDataType = "bigint")]
+    public long Id { get; set; }
+
+    /// <summary>NULL = baseline 行;非 NULL = 订单级行。</summary>
+    [SugarColumn(ColumnName = "order_id", ColumnDataType = "bigint", IsNullable = true)]
+    public long? OrderId { get; set; }
+
+    /// <summary>NULL = baseline 行;非 NULL = 订单业务键。</summary>
+    [SugarColumn(ColumnName = "order_code", Length = 64, IsNullable = true)]
+    public string? OrderCode { get; set; }
+
+    /// <summary>工序编码:P10 / P20 / P30 / P40 / TOTAL。</summary>
+    [SugarColumn(ColumnName = "process_code", Length = 16)]
+    public string ProcessCode { get; set; } = string.Empty;
+
+    /// <summary>工序名称:10工序 / 20工序 / 30工序 / 40工序 / 合计。</summary>
+    [SugarColumn(ColumnName = "process_name", Length = 32)]
+    public string ProcessName { get; set; } = string.Empty;
+
+    /// <summary>PI 标准工时(天)。常量:1.0 / 1.0 / 2.5 / 1.5;TOTAL=6。decimal(6,3)。</summary>
+    [SugarColumn(ColumnName = "pi_days", DecimalDigits = 3, Length = 6)]
+    public decimal PiDays { get; set; }
+
+    /// <summary>实际工时(天)。订单级按 stage.actual_days 守恒尾差修正;TOTAL = stage.actual_days。decimal(6,3)。</summary>
+    [SugarColumn(ColumnName = "actual_days", DecimalDigits = 3, Length = 6)]
+    public decimal ActualDays { get; set; }
+
+    /// <summary>周期状态:green / yellow / red。actual ≤ pi green / ≤ pi*1.2 yellow / 否则 red(seed 时固化,运行期不重判)。</summary>
+    [SugarColumn(ColumnName = "cycle_status", Length = 16)]
+    public string CycleStatus { get; set; } = "green";
+
+    /// <summary>计划台次。baseline fixture: 45/3/15/2/NULL;订单级 round(baseline*ratio);TOTAL 行 NULL。</summary>
+    [SugarColumn(ColumnName = "plan_qty", ColumnDataType = "int", IsNullable = true)]
+    public int? PlanQty { get; set; }
+
+    /// <summary>计划达成率。decimal(5,4),取值 0.0000~1.0000;TOTAL baseline=0.9000(fixture 锚),订单级 TOTAL 由 plan_qty 加权平均。</summary>
+    [SugarColumn(ColumnName = "achievement_rate", DecimalDigits = 4, Length = 5, IsNullable = true)]
+    public decimal? AchievementRate { get; set; }
+
+    /// <summary>达成状态:green / yellow / red;baseline 由 fixture 颜色固定,订单级由 rate 阈值派生(≥0.95 green / ≥0.80 yellow / 否则 red)。</summary>
+    [SugarColumn(ColumnName = "achievement_status", Length = 16)]
+    public string AchievementStatus { get; set; } = string.Empty;
+
+    /// <summary>排序号 1..5(10工序/20工序/30工序/40工序/合计)。</summary>
+    [SugarColumn(ColumnName = "sort_no", ColumnDataType = "int")]
+    public int SortNo { get; set; }
+
+    /// <summary>BASELINE_PPT / ORDER_LEVEL。</summary>
+    [SugarColumn(ColumnName = "scenario_code", Length = 16)]
+    public string ScenarioCode { get; set; } = "BASELINE_PPT";
+
+    /// <summary>SEED / IMPORT / AGG。同 (order_code, process_code) IMPORT/AGG 行存在时优先采用,SEED 仅兜底。</summary>
+    [SugarColumn(ColumnName = "data_source", Length = 16)]
+    public string DataSource { get; set; } = "SEED";
+
+    [SugarColumn(ColumnName = "tenant_id", ColumnDataType = "bigint")]
+    public long TenantId { get; set; }
+
+    [SugarColumn(ColumnName = "factory_id", ColumnDataType = "bigint")]
+    public long FactoryId { get; set; }
+
+    [SugarColumn(ColumnName = "created_at")]
+    public DateTime CreatedAt { get; set; } = DateTime.Now;
+
+    [SugarColumn(ColumnName = "updated_at", IsNullable = true)]
+    public DateTime? UpdatedAt { get; set; }
+
+    [SugarColumn(ColumnName = "is_deleted", ColumnDataType = "boolean")]
+    public bool IsDeleted { get; set; }
+}

+ 18 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Order/S1MdpSyncTransformService.cs

@@ -117,6 +117,24 @@ public class S1MdpSyncTransformService : ITransient
                 target_table_name=VALUES(target_table_name), sync_mode=VALUES(sync_mode), status=VALUES(status),
                 remark=VALUES(remark), update_time=CURRENT_TIMESTAMP;
             """);
+
+        await _db.Ado.ExecuteCommandAsync(
+            """
+            INSERT INTO mdp_entity
+            (tenant_id, source_id, entity_code, entity_name, entity_type, source_table_name, target_table_name, sync_mode, incr_column, batch_size, status, remark)
+            SELECT 0, s.id, v.entity_code, v.entity_name, 'TABLE', v.source_table_name, 'mdp_stg_so', 'INCR', 'UpdateTime', 5000, 1, v.remark
+            FROM mdp_source s
+            JOIN (
+                SELECT 'S1_PRODUCT_DESIGN' AS entity_code, 'S1产品设计主表' AS entity_name, 'ado_product_design' AS source_table_name, '产品设计主表,进入订单标准层' AS remark
+                UNION ALL SELECT 'S1_PRODUCT_DESIGN_BOM', 'S1产品设计BOM', 'ado_product_design_bom', '产品设计BOM,进入订单标准层'
+                UNION ALL SELECT 'S1_PRODUCT_DESIGN_ROUTING', 'S1产品设计工艺路线', 'ado_product_design_routing', '产品设计工艺路线,进入订单标准层'
+            ) v
+            WHERE s.tenant_id=0 AND s.source_code='AIDOPDEV_MYSQL'
+            ON DUPLICATE KEY UPDATE
+                source_id=VALUES(source_id), entity_name=VALUES(entity_name), source_table_name=VALUES(source_table_name),
+                target_table_name=VALUES(target_table_name), sync_mode=VALUES(sync_mode), incr_column=VALUES(incr_column),
+                status=VALUES(status), remark=VALUES(remark), update_time=CURRENT_TIMESTAMP;
+            """);
     }
 
     private async Task<int> SyncStagingAsync(string batchId, DateTime now, CancellationToken cancellationToken)

+ 423 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/S8OrderFlowManufacturingSeedData.cs

@@ -0,0 +1,423 @@
+using Admin.NET.Plugin.AiDOP.Entity.S8.OrderFlow;
+
+namespace Admin.NET.Plugin.AiDOP.SeedData;
+
+/// <summary>
+/// S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:本体生产「工序明细」/「损失因素」/「操作员表现」三表 seed。
+///
+/// ──────────────────────────────────────────────────────────────────────
+/// S8-...-FIX-1S(阶段 2 失败修正):本项目实际 SEED 数据落地路径是 UpdateScripts SQL
+///   的 DELETE+INSERT(与 procurement 1.0.148.sql 模式一致),不是 SqlSugar IncreSeed
+///   自动写入。阶段 2 实测启动后三表创建成功但 IncreSeed 0 行写入。
+/// 处理:移除 IncreSeed attribute,保留本算法 SOT 作为 SQL 生成依据与未来 IMPORT/AGG
+///   接入的算法 owner;本批次 221 行 SEED 数据由 WIP-S8-BODY-PRODUCTION-ORDER-LEVEL-SEED.sql
+///   的 INSERT 语句落地。
+/// ──────────────────────────────────────────────────────────────────────
+///
+/// baseline 行(order_id=NULL)来自 MANUFACTURING_DETAIL_FIXTURE 逐字段对齐:
+///   - process:(P10/P20/P30/P40/TOTAL) × (pi, actual, plan_qty, rate, status)
+///   - loss factor:(MATERIAL/EQUIPMENT/QUALITY/EFFICIENCY/SUBTOTAL) × (count, ratio_pct, loss_hours)
+///   - operator:(张/李/王) × (avg_hours, status)
+///
+/// 订单级行(order_id≠NULL,scenario=ORDER_LEVEL):
+///   对每个 BODY_PRODUCTION stage.status != "pending" 的订单(16 单),按 A=stage.actualDays 与 baseline 比例派生:
+///     ratio = A / 6.8
+///   process 行:
+///     baseline_actuals = [2.4, 0.8, 3.0, 0.6]
+///     actual[0..2] = round(baseline_actuals[i] * A / 6.8, 3)
+///     actual[3] = A - sum(actual[0..2])    // 守恒尾差修正
+///     plan_qty[i] = round(baseline_plan[i] * ratio)
+///     achievement_rate[i] = baseline_rate[i] (per-process 固定属性)
+///     achievement_status[i] = ≥0.95 green / ≥0.80 yellow / 否则 red (由 rate 派生)
+///     cycle_status[i] = ≤pi green / ≤pi*1.2 yellow / 否则 red (由 actual vs pi 派生)
+///     TOTAL 行:pi=6, actual=A, plan_qty=NULL,
+///               rate=0.9000 / status="yellow" 锚定 fixture (S8-...-FIX-1R),
+///               不再做 plan_qty 加权计算,与 baseline TOTAL 一致;
+///               cycle_status 仍由 actual vs 6 派生。SEED 过渡口径,IMPORT/AGG 接入后替换。
+///   loss factor 行:
+///     count[i] = round(baseline_count[i] * ratio)
+///     ratio_pct[i] = baseline_ratio_pct[i]    // 结构保留
+///     loss_hours[i] = round(baseline_loss_hours[i] * ratio, 2)
+///     SUBTOTAL: count=round(30*ratio), ratio_pct=100, loss_hours=round(7.5*ratio,2)  // fixture-pinned 比例缩放
+///   operator 行:
+///     avg_hours[i] = round(baseline_hours[i] * ratio, 2)
+///     status[i] = baseline_status[i]    // 每操作员固定 status
+///
+/// 真实数据源(IMPORT / AGG)接入后,service 优先采用 IMPORT/AGG,同 (order_code, process/factor/operator) SEED 行仅兜底。
+/// </summary>
+// S8-...-FIX-1S:[IncreSeed] 已移除(项目实际不通过 SqlSugar IncreSeed 自动写入)。
+// 数据落地见 UpdateScripts/WIP-S8-BODY-PRODUCTION-ORDER-LEVEL-SEED.sql 的 INSERT。
+public class S8OrderFlowManufacturingProcessSeedData : ISqlSugarEntitySeedData<AdoS8OrderFlowManufacturingProcess>
+{
+    public IEnumerable<AdoS8OrderFlowManufacturingProcess> HasData()
+        => S8OrderFlowManufacturingDataset.BuildProcessBaselineRows()
+            .Concat(S8OrderFlowManufacturingDataset.BuildProcessOrderLevelRows());
+}
+
+// S8-...-FIX-1S:[IncreSeed] 已移除(项目实际不通过 SqlSugar IncreSeed 自动写入)。
+// 数据落地见 UpdateScripts/WIP-S8-BODY-PRODUCTION-ORDER-LEVEL-SEED.sql 的 INSERT。
+public class S8OrderFlowManufacturingLossFactorSeedData : ISqlSugarEntitySeedData<AdoS8OrderFlowManufacturingLossFactor>
+{
+    public IEnumerable<AdoS8OrderFlowManufacturingLossFactor> HasData()
+        => S8OrderFlowManufacturingDataset.BuildLossFactorBaselineRows()
+            .Concat(S8OrderFlowManufacturingDataset.BuildLossFactorOrderLevelRows());
+}
+
+// S8-...-FIX-1S:[IncreSeed] 已移除(项目实际不通过 SqlSugar IncreSeed 自动写入)。
+// 数据落地见 UpdateScripts/WIP-S8-BODY-PRODUCTION-ORDER-LEVEL-SEED.sql 的 INSERT。
+public class S8OrderFlowManufacturingOperatorSeedData : ISqlSugarEntitySeedData<AdoS8OrderFlowManufacturingOperator>
+{
+    public IEnumerable<AdoS8OrderFlowManufacturingOperator> HasData()
+        => S8OrderFlowManufacturingDataset.BuildOperatorBaselineRows()
+            .Concat(S8OrderFlowManufacturingDataset.BuildOperatorOrderLevelRows());
+}
+
+internal static class S8OrderFlowManufacturingDataset
+{
+    // ─────────────── ID base ranges(与 procurement-pivot 同号段策略) ───────────────
+    internal const long ProcessBaselineIdBase            = 1329909160000L;
+    internal const long ProcessOrderLevelIdBase          = 1329909170000L;
+    internal const long LossFactorBaselineIdBase         = 1329909180000L;
+    internal const long LossFactorOrderLevelIdBase       = 1329909190000L;
+    internal const long OperatorBaselineIdBase           = 1329909200000L;
+    internal const long OperatorOrderLevelIdBase         = 1329909210000L;
+
+    internal const string ScenarioBaseline   = "BASELINE_PPT";
+    internal const string ScenarioOrderLevel = "ORDER_LEVEL";
+
+    // BODY_PRODUCTION 在 5 阶段流水中固定为索引 3(order_review→product_design→material_procurement→body_production→final_assembly_shipping)。
+    private const int BodyProductionStageIndex = 3;
+
+    // ─────────────── baseline 真值(与 MANUFACTURING_DETAIL_FIXTURE 逐字段对齐) ───────────────
+    private sealed record ProcessBaseline(
+        int SortNo, string Code, string Name,
+        decimal Pi, decimal Actual,
+        int? PlanQty, decimal? Rate, string AchStatus);
+
+    /// <summary>fixture 工序基线:(sort, code, name, pi, actual, plan, rate, ach_status)。</summary>
+    private static readonly ProcessBaseline[] ProcessBaselines =
+    {
+        new(1, "P10",   "10工序", 1.0m, 2.4m, 45,   0.5500m, "red"),
+        new(2, "P20",   "20工序", 1.0m, 0.8m, 3,    0.9700m, "yellow"),
+        new(3, "P30",   "30工序", 2.5m, 3.0m, 15,   0.8500m, "green"),
+        new(4, "P40",   "40工序", 1.5m, 0.6m, 2,    0.9800m, "red"),
+        // TOTAL:pi=6, actual=6.8, plan_qty=NULL, rate=0.90 (fixture-pinned), achievement_status=yellow(来自 fixture 表格颜色)。
+        new(5, "TOTAL", "合计",   6.0m, 6.8m, null, 0.9000m, "yellow"),
+    };
+
+    private sealed record LossFactorBaseline(
+        int SortNo, string Code, string Name,
+        int? Count, decimal? RatioPct, decimal? LossHours);
+
+    /// <summary>fixture 损失因素基线:(sort, code, name, count, ratio_pct, loss_hours)。</summary>
+    /// <remarks>SUBTOTAL loss_hours=7.50 来自 fixture,不等于 4 因素之和 26.15;保留 fixture 锚定。</remarks>
+    private static readonly LossFactorBaseline[] LossFactorBaselines =
+    {
+        new(1, "MATERIAL",   "材料影响",       9,  30.00m, 9.00m),
+        new(2, "EQUIPMENT",  "设备影响",       6,  20.00m, 4.50m),
+        new(3, "QUALITY",    "质量影响",       3,  10.00m, 3.40m),
+        new(4, "EFFICIENCY", "作业效率损失",   12, 40.00m, 9.25m),
+        new(5, "SUBTOTAL",   "损失小计",       30, 100.00m, 7.50m),
+    };
+
+    private sealed record OperatorBaseline(int SortNo, string Code, string Name, decimal Hours, string Status);
+
+    /// <summary>fixture 操作员基线:(sort, code, name, avg_hours, status)。</summary>
+    private static readonly OperatorBaseline[] OperatorBaselines =
+    {
+        new(1, "OP_ZHANG", "张师傅", 20.00m, "red"),
+        new(2, "OP_LI",    "李师傅", 10.00m, "yellow"),
+        new(3, "OP_WANG",  "王师傅", 8.00m,  "green"),
+    };
+
+    /// <summary>baseline TOTAL.actual_days(6.8)作为订单级 ratio = A/6.8 的归一化分母。</summary>
+    private const decimal BaselineTotalActualDays = 6.8m;
+    private const decimal BaselineTotalPiDays = 6.0m;
+
+    // ────────────────────────────────────────────────────────────
+    // Process 行
+    // ────────────────────────────────────────────────────────────
+    public static IEnumerable<AdoS8OrderFlowManufacturingProcess> BuildProcessBaselineRows()
+    {
+        long seq = 0;
+        foreach (var b in ProcessBaselines)
+        {
+            yield return new AdoS8OrderFlowManufacturingProcess
+            {
+                Id = ProcessBaselineIdBase + (++seq),
+                OrderId = null,
+                OrderCode = null,
+                ProcessCode = b.Code,
+                ProcessName = b.Name,
+                PiDays = b.Pi,
+                ActualDays = b.Actual,
+                CycleStatus = ClassifyCycleStatus(b.Actual, b.Pi),
+                PlanQty = b.PlanQty,
+                AchievementRate = b.Rate,
+                AchievementStatus = b.AchStatus,
+                SortNo = b.SortNo,
+                ScenarioCode = ScenarioBaseline,
+                DataSource = "SEED",
+                TenantId = 1,
+                FactoryId = 1,
+                CreatedAt = S8OrderFlowDataset.CreatedAt,
+                UpdatedAt = null,
+                IsDeleted = false,
+            };
+        }
+    }
+
+    public static IEnumerable<AdoS8OrderFlowManufacturingProcess> BuildProcessOrderLevelRows()
+    {
+        long seq = 0;
+        foreach (var spec in S8OrderFlowDataset.Specs)
+        {
+            var lifecycle = S8OrderFlowStageDataset.BuildLifecycleValues(spec);
+            var stage = lifecycle[BodyProductionStageIndex];
+            if (stage.status == "pending") continue;
+
+            var A = stage.actualDays;
+            var ratio = A / BaselineTotalActualDays;
+            var orderId = S8OrderFlowDataset.OrderIdBase + spec.Idx;
+
+            // 4 个工序 actual:前 3 个直接缩放,第 4 个尾差修正以满足 sum == A。
+            var actuals = new decimal[4];
+            decimal sumFirstThree = 0m;
+            for (var i = 0; i < 3; i++)
+            {
+                actuals[i] = decimal.Round(ProcessBaselines[i].Actual * ratio, 3);
+                sumFirstThree += actuals[i];
+            }
+            actuals[3] = decimal.Round(A - sumFirstThree, 3);
+
+            // 4 工序 plan_qty(TOTAL 行不计入;取 baseline.PlanQty 非 null 即可,TOTAL 是第 5 行)
+            var planQtys = new int[4];
+            for (var i = 0; i < 4; i++)
+            {
+                var basePlan = ProcessBaselines[i].PlanQty ?? 0;
+                planQtys[i] = (int)decimal.Round(basePlan * ratio, MidpointRounding.AwayFromZero);
+            }
+
+            // 4 工序行
+            for (var i = 0; i < 4; i++)
+            {
+                var baseRow = ProcessBaselines[i];
+                var rate = baseRow.Rate!.Value;
+                yield return new AdoS8OrderFlowManufacturingProcess
+                {
+                    Id = ProcessOrderLevelIdBase + (++seq),
+                    OrderId = orderId,
+                    OrderCode = spec.OrderCode,
+                    ProcessCode = baseRow.Code,
+                    ProcessName = baseRow.Name,
+                    PiDays = baseRow.Pi,
+                    ActualDays = actuals[i],
+                    CycleStatus = ClassifyCycleStatus(actuals[i], baseRow.Pi),
+                    PlanQty = planQtys[i],
+                    AchievementRate = rate,
+                    AchievementStatus = ClassifyAchievementStatus(rate),
+                    SortNo = baseRow.SortNo,
+                    ScenarioCode = ScenarioOrderLevel,
+                    DataSource = "SEED",
+                    TenantId = 1,
+                    FactoryId = 1,
+                    CreatedAt = S8OrderFlowDataset.CreatedAt,
+                    UpdatedAt = null,
+                    IsDeleted = false,
+                };
+            }
+
+            // TOTAL 行:plan_qty=NULL。
+            // S8-...-FIX-1R:achievement_rate / achievement_status 锚定 fixture(ProcessBaselines[4],
+            // 即 0.9000 / yellow),不再用 4 工序 plan_qty 加权计算,与 baseline TOTAL 保持一致。
+            // SEED 过渡口径;真实 IMPORT/AGG 接入后由真实生产达成数据替换。
+            var fixtureTotalRate = ProcessBaselines[4].Rate!.Value;       // 0.9000m
+            var fixtureTotalStatus = ProcessBaselines[4].AchStatus;       // "yellow"
+
+            yield return new AdoS8OrderFlowManufacturingProcess
+            {
+                Id = ProcessOrderLevelIdBase + (++seq),
+                OrderId = orderId,
+                OrderCode = spec.OrderCode,
+                ProcessCode = ProcessBaselines[4].Code,
+                ProcessName = ProcessBaselines[4].Name,
+                PiDays = BaselineTotalPiDays,
+                ActualDays = decimal.Round(A, 3),
+                CycleStatus = ClassifyCycleStatus(A, BaselineTotalPiDays),
+                PlanQty = null,
+                AchievementRate = fixtureTotalRate,
+                AchievementStatus = fixtureTotalStatus,
+                SortNo = ProcessBaselines[4].SortNo,
+                ScenarioCode = ScenarioOrderLevel,
+                DataSource = "SEED",
+                TenantId = 1,
+                FactoryId = 1,
+                CreatedAt = S8OrderFlowDataset.CreatedAt,
+                UpdatedAt = null,
+                IsDeleted = false,
+            };
+        }
+    }
+
+    // ────────────────────────────────────────────────────────────
+    // Loss factor 行
+    // ────────────────────────────────────────────────────────────
+    public static IEnumerable<AdoS8OrderFlowManufacturingLossFactor> BuildLossFactorBaselineRows()
+    {
+        long seq = 0;
+        foreach (var b in LossFactorBaselines)
+        {
+            yield return new AdoS8OrderFlowManufacturingLossFactor
+            {
+                Id = LossFactorBaselineIdBase + (++seq),
+                OrderId = null,
+                OrderCode = null,
+                FactorCode = b.Code,
+                FactorName = b.Name,
+                CountValue = b.Count,
+                RatioPct = b.RatioPct,
+                LossHours = b.LossHours,
+                SortNo = b.SortNo,
+                ScenarioCode = ScenarioBaseline,
+                DataSource = "SEED",
+                TenantId = 1,
+                FactoryId = 1,
+                CreatedAt = S8OrderFlowDataset.CreatedAt,
+                UpdatedAt = null,
+                IsDeleted = false,
+            };
+        }
+    }
+
+    public static IEnumerable<AdoS8OrderFlowManufacturingLossFactor> BuildLossFactorOrderLevelRows()
+    {
+        long seq = 0;
+        foreach (var spec in S8OrderFlowDataset.Specs)
+        {
+            var lifecycle = S8OrderFlowStageDataset.BuildLifecycleValues(spec);
+            var stage = lifecycle[BodyProductionStageIndex];
+            if (stage.status == "pending") continue;
+
+            var A = stage.actualDays;
+            var ratio = A / BaselineTotalActualDays;
+            var orderId = S8OrderFlowDataset.OrderIdBase + spec.Idx;
+
+            foreach (var b in LossFactorBaselines)
+            {
+                int? count = b.Count.HasValue
+                    ? (int)decimal.Round(b.Count.Value * ratio, MidpointRounding.AwayFromZero)
+                    : null;
+                decimal? hours = b.LossHours.HasValue
+                    ? decimal.Round(b.LossHours.Value * ratio, 2)
+                    : null;
+
+                yield return new AdoS8OrderFlowManufacturingLossFactor
+                {
+                    Id = LossFactorOrderLevelIdBase + (++seq),
+                    OrderId = orderId,
+                    OrderCode = spec.OrderCode,
+                    FactorCode = b.Code,
+                    FactorName = b.Name,
+                    CountValue = count,
+                    RatioPct = b.RatioPct, // 结构保留:baseline ratio_pct 原值复制
+                    LossHours = hours,
+                    SortNo = b.SortNo,
+                    ScenarioCode = ScenarioOrderLevel,
+                    DataSource = "SEED",
+                    TenantId = 1,
+                    FactoryId = 1,
+                    CreatedAt = S8OrderFlowDataset.CreatedAt,
+                    UpdatedAt = null,
+                    IsDeleted = false,
+                };
+            }
+        }
+    }
+
+    // ────────────────────────────────────────────────────────────
+    // Operator 行
+    // ────────────────────────────────────────────────────────────
+    public static IEnumerable<AdoS8OrderFlowManufacturingOperator> BuildOperatorBaselineRows()
+    {
+        long seq = 0;
+        foreach (var b in OperatorBaselines)
+        {
+            yield return new AdoS8OrderFlowManufacturingOperator
+            {
+                Id = OperatorBaselineIdBase + (++seq),
+                OrderId = null,
+                OrderCode = null,
+                OperatorCode = b.Code,
+                OperatorName = b.Name,
+                AvgHours = b.Hours,
+                Status = b.Status,
+                SortNo = b.SortNo,
+                ScenarioCode = ScenarioBaseline,
+                DataSource = "SEED",
+                TenantId = 1,
+                FactoryId = 1,
+                CreatedAt = S8OrderFlowDataset.CreatedAt,
+                UpdatedAt = null,
+                IsDeleted = false,
+            };
+        }
+    }
+
+    public static IEnumerable<AdoS8OrderFlowManufacturingOperator> BuildOperatorOrderLevelRows()
+    {
+        long seq = 0;
+        foreach (var spec in S8OrderFlowDataset.Specs)
+        {
+            var lifecycle = S8OrderFlowStageDataset.BuildLifecycleValues(spec);
+            var stage = lifecycle[BodyProductionStageIndex];
+            if (stage.status == "pending") continue;
+
+            var A = stage.actualDays;
+            var ratio = A / BaselineTotalActualDays;
+            var orderId = S8OrderFlowDataset.OrderIdBase + spec.Idx;
+
+            foreach (var b in OperatorBaselines)
+            {
+                var hours = decimal.Round(b.Hours * ratio, 2);
+                yield return new AdoS8OrderFlowManufacturingOperator
+                {
+                    Id = OperatorOrderLevelIdBase + (++seq),
+                    OrderId = orderId,
+                    OrderCode = spec.OrderCode,
+                    OperatorCode = b.Code,
+                    OperatorName = b.Name,
+                    AvgHours = hours,
+                    Status = b.Status, // 结构保留:每操作员固定 status
+                    SortNo = b.SortNo,
+                    ScenarioCode = ScenarioOrderLevel,
+                    DataSource = "SEED",
+                    TenantId = 1,
+                    FactoryId = 1,
+                    CreatedAt = S8OrderFlowDataset.CreatedAt,
+                    UpdatedAt = null,
+                    IsDeleted = false,
+                };
+            }
+        }
+    }
+
+    // ────────────────────────────────────────────────────────────
+    // status classifiers(seed-time 一次性,运行期不再重判)
+    // ────────────────────────────────────────────────────────────
+
+    /// <summary>cycle_status:actual ≤ pi → green;≤ pi*1.2 → yellow;否则 red。</summary>
+    private static string ClassifyCycleStatus(decimal actual, decimal pi)
+    {
+        if (actual <= pi) return "green";
+        if (actual <= pi * 1.2m) return "yellow";
+        return "red";
+    }
+
+    /// <summary>achievement_status:rate ≥ 0.95 green / ≥ 0.80 yellow / 否则 red。</summary>
+    private static string ClassifyAchievementStatus(decimal rate)
+    {
+        if (rate >= 0.95m) return "green";
+        if (rate >= 0.80m) return "yellow";
+        return "red";
+    }
+}

+ 6 - 6
server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/SysMenuSeedData.cs

@@ -548,7 +548,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
         {
             Id = subDirId + 1,
             Pid = subDirId,
-            Title = "客户管理",
+            Title = "客户信息维护",
             Path = "/aidop/s0/sales/customer",
             Name = "aidopS0SalesCustomer",
             Component = "/aidop/s0/sales/CustomerList",
@@ -556,14 +556,14 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
             Type = MenuTypeEnum.Menu,
             CreateTime = ct,
             OrderNo = 1,
-            Remark = "S0 客户管理"
+            Remark = "S0 客户信息维护"
         };
 
         yield return new SysMenu
         {
             Id = subDirId + 2,
             Pid = subDirId,
-            Title = "物料管理",
+            Title = "物料维护列表",
             Path = "/aidop/s0/sales/material",
             Name = "aidopS0SalesMaterial",
             Component = "/aidop/s0/sales/MaterialList",
@@ -571,14 +571,14 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
             Type = MenuTypeEnum.Menu,
             CreateTime = ct,
             OrderNo = 2,
-            Remark = "S0 物料管理"
+            Remark = "S0 物料维护列表"
         };
 
         yield return new SysMenu
         {
             Id = subDirId + 3,
             Pid = subDirId,
-            Title = "订单优先规则",
+            Title = "订单优先级配置",
             Path = "/aidop/s0/sales/order-priority-rule",
             Name = "aidopS0SalesOrderPriorityRule",
             Component = "/aidop/s0/sales/OrderPriorityRuleList",
@@ -586,7 +586,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
             Type = MenuTypeEnum.Menu,
             CreateTime = ct,
             OrderNo = 3,
-            Remark = "S0 订单优先规则"
+            Remark = "S0 订单优先级配置"
         };
 
         yield return new SysMenu

+ 341 - 1
server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/OrderFlow/S8OrderFlowService.cs

@@ -45,6 +45,10 @@ public class S8OrderFlowService : ITransient
     private readonly SqlSugarRepository<AdoS8OrderFlowProcurementPivot> _pivotRep;
     private readonly SqlSugarRepository<AdoS8Exception> _exceptionRep;
     private readonly SqlSugarRepository<AdoS8OrderFlowProductDesignDrawing> _pddRep;
+    // S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:本体生产 3 表 repository。
+    private readonly SqlSugarRepository<AdoS8OrderFlowManufacturingProcess> _mfgProcessRep;
+    private readonly SqlSugarRepository<AdoS8OrderFlowManufacturingLossFactor> _mfgLossRep;
+    private readonly SqlSugarRepository<AdoS8OrderFlowManufacturingOperator> _mfgOperatorRep;
 
     public S8OrderFlowService(
         SqlSugarRepository<AdoS8OrderFlowOrder> orderRep,
@@ -54,7 +58,10 @@ public class S8OrderFlowService : ITransient
         SqlSugarRepository<AdoS8OrderFlowSnapshot> snapshotRep,
         SqlSugarRepository<AdoS8OrderFlowProcurementPivot> pivotRep,
         SqlSugarRepository<AdoS8Exception> exceptionRep,
-        SqlSugarRepository<AdoS8OrderFlowProductDesignDrawing> pddRep)
+        SqlSugarRepository<AdoS8OrderFlowProductDesignDrawing> pddRep,
+        SqlSugarRepository<AdoS8OrderFlowManufacturingProcess> mfgProcessRep,
+        SqlSugarRepository<AdoS8OrderFlowManufacturingLossFactor> mfgLossRep,
+        SqlSugarRepository<AdoS8OrderFlowManufacturingOperator> mfgOperatorRep)
     {
         _orderRep = orderRep;
         _stageRep = stageRep;
@@ -64,6 +71,9 @@ public class S8OrderFlowService : ITransient
         _pivotRep = pivotRep;
         _exceptionRep = exceptionRep;
         _pddRep = pddRep;
+        _mfgProcessRep = mfgProcessRep;
+        _mfgLossRep = mfgLossRep;
+        _mfgOperatorRep = mfgOperatorRep;
     }
 
     /// <summary>订单档案列表(无分页)。当前 baseline 20 单。</summary>
@@ -968,4 +978,334 @@ public class S8OrderFlowService : ITransient
             Status = d.Status,
             ProductQuantity = d.ProductQuantity,
         };
+
+    // ──────────────────────────────────────────────────────────────────────
+    // S8-ORDER-CHAIN-BODY-PRODUCTION-ORDER-LEVEL-SEED-FIX-1:本体生产透视。
+    // 单一数据源 = ado_s8_order_flow_manufacturing_{process,loss_factor,operator} 三表。
+    // BASELINE_PPT 读 (order_id IS NULL) baseline 行;CURRENT_FILTERED 读订单级行(order_id IS NOT NULL),
+    //   按 IMPORT/AGG > SEED 优先级去重后,按业务口径聚合:
+    //     process actual_days:AVG(多订单按行平均)
+    //     process plan_qty:SUM(多订单累计计划台次)
+    //     process achievement_rate:AVG(多订单平均达成率),TOTAL 行特殊处理见 BuildManufacturingProcessAggregated。
+    //     process cycle_status / achievement_status:聚合后按阈值重判(与 baseline 同口径,运行期不修改 seed 行)。
+    //     loss factor count:SUM;ratio_pct / loss_hours:AVG。
+    //     operator avg_hours:AVG;status:取首单的 status(baseline 每操作员固定,AVG 后语义不变)。
+    //   orderCodes 为空时返回空骨架(不静默 fallback baseline,避免 baseline 泄漏到单订单态)。
+    // status 阈值与 seed 同步:cycle_status (≤pi green / ≤pi*1.2 yellow / 否则 red),
+    //   achievement_status (≥0.95 green / ≥0.80 yellow / 否则 red)。
+    // ──────────────────────────────────────────────────────────────────────
+
+    private const string ManufacturingProcessTotalCode = "TOTAL";
+
+    // S8-...-FIX-1R:order-level TOTAL.achievement_rate / achievement_status 锚定 fixture,
+    // 与 baseline TOTAL(0.90 / yellow)保持一致,不再用 plan_qty 加权计算(避免 65% red 与 90% yellow 冲突)。
+    // SEED 过渡口径;真实 IMPORT/AGG 接入后由真实生产达成数据替换。
+    private const decimal ManufacturingTotalAchievementRate = 0.9000m;
+    private const string ManufacturingTotalAchievementStatus = "yellow";
+
+    public async Task<AdoS8OrderFlowManufacturingPivotDto> GetManufacturingPivotAsync(
+        AdoS8OrderFlowManufacturingPivotQueryDto query)
+    {
+        var tenantId = query.TenantId ?? 1;
+        var factoryId = query.FactoryId ?? 1;
+        var scope = string.IsNullOrWhiteSpace(query.Scope) ? ScopeBaselinePpt : query.Scope;
+
+        if (string.Equals(scope, ScopeBaselinePpt, StringComparison.OrdinalIgnoreCase))
+        {
+            var processRows = await _mfgProcessRep.AsQueryable()
+                .Where(p => p.TenantId == tenantId && p.FactoryId == factoryId && !p.IsDeleted)
+                .Where(p => p.OrderId == null)
+                .ToListAsync();
+            var lossRows = await _mfgLossRep.AsQueryable()
+                .Where(p => p.TenantId == tenantId && p.FactoryId == factoryId && !p.IsDeleted)
+                .Where(p => p.OrderId == null)
+                .ToListAsync();
+            var operatorRows = await _mfgOperatorRep.AsQueryable()
+                .Where(p => p.TenantId == tenantId && p.FactoryId == factoryId && !p.IsDeleted)
+                .Where(p => p.OrderId == null)
+                .ToListAsync();
+
+            return BuildManufacturingPivotFromBaseline(scope, processRows, lossRows, operatorRows);
+        }
+
+        if (string.Equals(scope, ScopeCurrentFiltered, StringComparison.OrdinalIgnoreCase))
+        {
+            var orderCodes = ParseOrderCodesCsv(query.OrderCodes);
+            if (orderCodes.Count == 0)
+                return new AdoS8OrderFlowManufacturingPivotDto { Scope = scope };
+
+            var processRows = await _mfgProcessRep.AsQueryable()
+                .Where(p => p.TenantId == tenantId && p.FactoryId == factoryId && !p.IsDeleted)
+                .Where(p => p.OrderId != null && p.OrderCode != null)
+                .Where(p => orderCodes.Contains(p.OrderCode!))
+                .ToListAsync();
+            var lossRows = await _mfgLossRep.AsQueryable()
+                .Where(p => p.TenantId == tenantId && p.FactoryId == factoryId && !p.IsDeleted)
+                .Where(p => p.OrderId != null && p.OrderCode != null)
+                .Where(p => orderCodes.Contains(p.OrderCode!))
+                .ToListAsync();
+            var operatorRows = await _mfgOperatorRep.AsQueryable()
+                .Where(p => p.TenantId == tenantId && p.FactoryId == factoryId && !p.IsDeleted)
+                .Where(p => p.OrderId != null && p.OrderCode != null)
+                .Where(p => orderCodes.Contains(p.OrderCode!))
+                .ToListAsync();
+
+            if (processRows.Count == 0 && lossRows.Count == 0 && operatorRows.Count == 0)
+                return new AdoS8OrderFlowManufacturingPivotDto { Scope = scope };
+
+            // IMPORT/AGG > SEED 去重:同 (order_code, process_code/factor_code/operator_code) 上 IMPORT/AGG 优先。
+            var preferredProcess = SelectPreferredMfgProcess(processRows);
+            var preferredLoss = SelectPreferredMfgLossFactor(lossRows);
+            var preferredOperator = SelectPreferredMfgOperator(operatorRows);
+
+            return new AdoS8OrderFlowManufacturingPivotDto
+            {
+                Scope = scope,
+                Processes = BuildManufacturingProcessAggregated(preferredProcess),
+                LossFactors = BuildManufacturingLossFactorAggregated(preferredLoss),
+                Operators = BuildManufacturingOperatorAggregated(preferredOperator),
+            };
+        }
+
+        return new AdoS8OrderFlowManufacturingPivotDto { Scope = scope };
+    }
+
+    private static AdoS8OrderFlowManufacturingPivotDto BuildManufacturingPivotFromBaseline(
+        string scope,
+        List<AdoS8OrderFlowManufacturingProcess> processRows,
+        List<AdoS8OrderFlowManufacturingLossFactor> lossRows,
+        List<AdoS8OrderFlowManufacturingOperator> operatorRows)
+    {
+        var processes = processRows
+            .OrderBy(r => r.SortNo)
+            .Select(r => new AdoS8OrderFlowManufacturingProcessDto
+            {
+                ProcessCode = r.ProcessCode,
+                ProcessName = r.ProcessName,
+                PiDays = r.PiDays,
+                ActualDays = r.ActualDays,
+                CycleStatus = r.CycleStatus,
+                PlanQty = r.PlanQty,
+                AchievementRate = r.AchievementRate,
+                AchievementStatus = r.AchievementStatus,
+                SortNo = r.SortNo,
+            })
+            .ToList();
+
+        var losses = lossRows
+            .OrderBy(r => r.SortNo)
+            .Select(r => new AdoS8OrderFlowManufacturingLossFactorDto
+            {
+                FactorCode = r.FactorCode,
+                FactorName = r.FactorName,
+                CountValue = r.CountValue,
+                RatioPct = r.RatioPct,
+                LossHours = r.LossHours,
+                SortNo = r.SortNo,
+            })
+            .ToList();
+
+        var operators = operatorRows
+            .OrderBy(r => r.SortNo)
+            .Select(r => new AdoS8OrderFlowManufacturingOperatorDto
+            {
+                OperatorCode = r.OperatorCode,
+                OperatorName = r.OperatorName,
+                AvgHours = r.AvgHours,
+                Status = r.Status,
+                SortNo = r.SortNo,
+            })
+            .ToList();
+
+        return new AdoS8OrderFlowManufacturingPivotDto
+        {
+            Scope = scope,
+            Processes = processes,
+            LossFactors = losses,
+            Operators = operators,
+        };
+    }
+
+    private static List<AdoS8OrderFlowManufacturingProcess> SelectPreferredMfgProcess(
+        List<AdoS8OrderFlowManufacturingProcess> rows)
+    {
+        var grouped = rows.GroupBy(r => (r.OrderCode, r.ProcessCode));
+        var result = new List<AdoS8OrderFlowManufacturingProcess>(rows.Count);
+        foreach (var g in grouped)
+        {
+            var preferred = g.FirstOrDefault(r =>
+                string.Equals(r.DataSource, "IMPORT", StringComparison.OrdinalIgnoreCase) ||
+                string.Equals(r.DataSource, "AGG", StringComparison.OrdinalIgnoreCase));
+            result.Add(preferred ?? g.First());
+        }
+        return result;
+    }
+
+    private static List<AdoS8OrderFlowManufacturingLossFactor> SelectPreferredMfgLossFactor(
+        List<AdoS8OrderFlowManufacturingLossFactor> rows)
+    {
+        var grouped = rows.GroupBy(r => (r.OrderCode, r.FactorCode));
+        var result = new List<AdoS8OrderFlowManufacturingLossFactor>(rows.Count);
+        foreach (var g in grouped)
+        {
+            var preferred = g.FirstOrDefault(r =>
+                string.Equals(r.DataSource, "IMPORT", StringComparison.OrdinalIgnoreCase) ||
+                string.Equals(r.DataSource, "AGG", StringComparison.OrdinalIgnoreCase));
+            result.Add(preferred ?? g.First());
+        }
+        return result;
+    }
+
+    private static List<AdoS8OrderFlowManufacturingOperator> SelectPreferredMfgOperator(
+        List<AdoS8OrderFlowManufacturingOperator> rows)
+    {
+        var grouped = rows.GroupBy(r => (r.OrderCode, r.OperatorCode));
+        var result = new List<AdoS8OrderFlowManufacturingOperator>(rows.Count);
+        foreach (var g in grouped)
+        {
+            var preferred = g.FirstOrDefault(r =>
+                string.Equals(r.DataSource, "IMPORT", StringComparison.OrdinalIgnoreCase) ||
+                string.Equals(r.DataSource, "AGG", StringComparison.OrdinalIgnoreCase));
+            result.Add(preferred ?? g.First());
+        }
+        return result;
+    }
+
+    /// <summary>
+    /// 多订单工序聚合:
+    ///   非 TOTAL 行:actual_days = AVG;plan_qty = SUM;achievement_rate = AVG(保留 4 位小数);
+    ///                cycle_status 按聚合 actual vs pi 重判;achievement_status 按聚合 rate 重判。
+    ///   TOTAL 行:pi=6(取 baseline 常量);actual = AVG(与 4 工序 AVG 之和守恒,差异为 rounding 容差);
+    ///             plan_qty = NULL;
+    ///             S8-...-FIX-1R:achievement_rate / achievement_status 锚定 fixture(0.90 / yellow),
+    ///             不再做 plan_qty 加权计算(避免与 baseline TOTAL 视觉冲突);
+    ///             cycle_status 按聚合 actual vs pi 重判。
+    /// </summary>
+    private static List<AdoS8OrderFlowManufacturingProcessDto> BuildManufacturingProcessAggregated(
+        List<AdoS8OrderFlowManufacturingProcess> rows)
+    {
+        var grouped = rows
+            .GroupBy(r => r.ProcessCode)
+            .ToDictionary(g => g.Key, g => g.ToList());
+
+        // S8-...-FIX-1R:TOTAL 行 rate / status 锚定 fixture,不再做 4 工序 plan_qty 加权计算,
+        // 不需要维护中间 aggregatedRates 字典。
+        var processDtos = new List<AdoS8OrderFlowManufacturingProcessDto>();
+
+        foreach (var kv in grouped.OrderBy(g => g.Value.First().SortNo))
+        {
+            var code = kv.Key;
+            var list = kv.Value;
+            var sample = list[0];
+            var isTotal = string.Equals(code, ManufacturingProcessTotalCode, StringComparison.OrdinalIgnoreCase);
+
+            var actualAvg = decimal.Round(list.Average(r => r.ActualDays), 3);
+            var pi = sample.PiDays;
+
+            decimal? aggregatedRate;
+            int? planQtySum;
+            string achStatus;
+            if (isTotal)
+            {
+                // S8-...-FIX-1R:TOTAL 行 rate / status 锚定 fixture(0.90 / yellow),
+                // 不再做 plan_qty 加权计算;非 TOTAL 行的 plan_qty 仍保留供 UI 显示,但不参与 TOTAL.rate。
+                planQtySum = null;
+                aggregatedRate = ManufacturingTotalAchievementRate;
+                achStatus = ManufacturingTotalAchievementStatus;
+            }
+            else
+            {
+                planQtySum = list.Where(r => r.PlanQty.HasValue).Sum(r => r.PlanQty!.Value);
+                var rateRows = list.Where(r => r.AchievementRate.HasValue).ToList();
+                aggregatedRate = rateRows.Count == 0
+                    ? null
+                    : decimal.Round(rateRows.Average(r => r.AchievementRate!.Value), 4);
+                achStatus = aggregatedRate.HasValue
+                    ? ClassifyMfgAchievementStatus(aggregatedRate.Value)
+                    : string.Empty;
+            }
+
+            var cycleStatus = ClassifyMfgCycleStatus(actualAvg, pi);
+
+            processDtos.Add(new AdoS8OrderFlowManufacturingProcessDto
+            {
+                ProcessCode = sample.ProcessCode,
+                ProcessName = sample.ProcessName,
+                PiDays = pi,
+                ActualDays = actualAvg,
+                CycleStatus = cycleStatus,
+                PlanQty = planQtySum,
+                AchievementRate = aggregatedRate,
+                AchievementStatus = achStatus,
+                SortNo = sample.SortNo,
+            });
+        }
+
+        return processDtos;
+    }
+
+    private static List<AdoS8OrderFlowManufacturingLossFactorDto> BuildManufacturingLossFactorAggregated(
+        List<AdoS8OrderFlowManufacturingLossFactor> rows)
+    {
+        return rows
+            .GroupBy(r => r.FactorCode)
+            .OrderBy(g => g.First().SortNo)
+            .Select(g =>
+            {
+                var sample = g.First();
+                var countList = g.Where(r => r.CountValue.HasValue).ToList();
+                var ratioList = g.Where(r => r.RatioPct.HasValue).ToList();
+                var hoursList = g.Where(r => r.LossHours.HasValue).ToList();
+                return new AdoS8OrderFlowManufacturingLossFactorDto
+                {
+                    FactorCode = sample.FactorCode,
+                    FactorName = sample.FactorName,
+                    CountValue = countList.Count == 0 ? null : countList.Sum(r => r.CountValue!.Value),
+                    RatioPct = ratioList.Count == 0
+                        ? null
+                        : decimal.Round(ratioList.Average(r => r.RatioPct!.Value), 2),
+                    LossHours = hoursList.Count == 0
+                        ? null
+                        : decimal.Round(hoursList.Average(r => r.LossHours!.Value), 2),
+                    SortNo = sample.SortNo,
+                };
+            })
+            .ToList();
+    }
+
+    private static List<AdoS8OrderFlowManufacturingOperatorDto> BuildManufacturingOperatorAggregated(
+        List<AdoS8OrderFlowManufacturingOperator> rows)
+    {
+        return rows
+            .GroupBy(r => r.OperatorCode)
+            .OrderBy(g => g.First().SortNo)
+            .Select(g =>
+            {
+                var sample = g.First();
+                return new AdoS8OrderFlowManufacturingOperatorDto
+                {
+                    OperatorCode = sample.OperatorCode,
+                    OperatorName = sample.OperatorName,
+                    AvgHours = decimal.Round(g.Average(r => r.AvgHours), 2),
+                    // 每操作员 baseline status 固化,多订单聚合时各订单值一致;取首单不引入歧义。
+                    Status = sample.Status,
+                    SortNo = sample.SortNo,
+                };
+            })
+            .ToList();
+    }
+
+    private static string ClassifyMfgCycleStatus(decimal actual, decimal pi)
+    {
+        if (actual <= pi) return "green";
+        if (actual <= pi * 1.2m) return "yellow";
+        return "red";
+    }
+
+    private static string ClassifyMfgAchievementStatus(decimal rate)
+    {
+        if (rate >= 0.95m) return "green";
+        if (rate >= 0.80m) return "yellow";
+        return "red";
+    }
 }

+ 0 - 1
server/Plugins/Admin.NET.Plugin.AiDOP/Startup.cs

@@ -96,7 +96,6 @@ public class Startup : AppStartup
                 typeof(AdoS0ItemMaster),
                 typeof(AdoS0ItemSubstituteDetail),
                 typeof(AdoS0PriorityCode),
-                typeof(AdoS0ProductStructureMaster),
                 typeof(AdoS0ProductStructureOp),
                 typeof(AdoS0StdOpMaster),
                 typeof(AdoS0LineMaster),

+ 22 - 0
server/deploy/winsw/AiDOPBackendService.xml

@@ -0,0 +1,22 @@
+<service>
+  <id>AiDOPBackend</id>
+  <name>AiDOP Backend</name>
+  <description>AiDOP Admin.NET backend (WinSW)</description>
+
+  <executable>C:\Program Files\dotnet\dotnet.exe</executable>
+  <arguments>Admin.NET.Web.Entry.dll</arguments>
+  <workingdirectory>c:\Projects\AiDOP\SourceCode\server\.publish\web-entry</workingdirectory>
+
+  <env name="ASPNETCORE_ENVIRONMENT" value="Production" />
+  <env name="ASPNETCORE_URLS" value="http://0.0.0.0:5005" />
+
+  <logpath>c:\Projects\AiDOP\SourceCode\server\.publish\web-entry\logs</logpath>
+  <log mode="roll-by-size-time">
+    <sizeThreshold>10485760</sizeThreshold>
+    <pattern>yyyyMMdd</pattern>
+  </log>
+
+  <onfailure action="restart" delay="10 sec" />
+  <onfailure action="restart" delay="30 sec" />
+  <onfailure action="restart" delay="60 sec" />
+</service>