|
@@ -612,6 +612,71 @@ public static class S0DimCatalog
|
|
|
new("source_updated_at", S0DimValueKind.DateTimeSec, "FMODIFYTIME")
|
|
new("source_updated_at", S0DimValueKind.DateTimeSec, "FMODIFYTIME")
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 供应商。源 <c>SuppMaster</c> —— **S0 的 Supplier 权威**。
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para><c>mdp_std_supplier</c> 属 Supply/S3 的多源标准层,**不是** S0 主数据权威,
|
|
|
|
|
+ /// 与本维度语义域不同(同 <see cref="Item"/> 对 <c>mdp_std_item</c> 的关系)。</para>
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para><b>身份 = tenant_id + Supp</b>。实测租户内重复 <b>0 组</b>;
|
|
|
|
|
+ /// <c>Supp</c> 跨租户碰撞 <b>13 码 / 27 行</b> ⇒ 租户必须入身份。
|
|
|
|
|
+ /// 旧唯一键 <c>uk_SuppMaster_factory_supp</c> 含 <c>factory_ref_id</c>,**不予继承** ——
|
|
|
|
|
+ /// <c>Domain</c> / <c>company_ref_id</c> / <c>factory_ref_id</c> **每租户各只有 1 个取值**
|
|
|
|
|
+ /// (严格 f(tenant),零判别力),且 <c>factory_ref_id=1000</c> 被两个租户共用。</para>
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para>CRUD 的查重守卫 <c>TenantId && FactoryRefId && Supp</c> **不构成 factory 应入身份的证据**:
|
|
|
|
|
+ /// 其 <c>factoryId</c> 来自 <c>AdoS0OrgScope.ResolveAsync(db, tenantId)</c> —— 仅凭 tenantId 解析、
|
|
|
|
|
+ /// 强制盖章、忽略 payload,故该守卫语义上等价于 <c>tenant + Supp</c>(D-025)。
|
|
|
|
|
+ /// 页面虽有「公司/工厂」下拉且 DTO 带 <c>[Range]</c> 必填,但 <c>CreateAsync</c>/<c>UpdateAsync</c>
|
|
|
|
|
+ /// **从不读取**这两个入参 —— UI 收集 ≠ 参与身份。</para>
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para>真实消费方按 <b>tenant + 编码</b> 关联:<c>SrmPurchase.SupplierNumber == Supp</c> 命中
|
|
|
|
|
+ /// <b>4447/4449</b>;而 <c>srm_purchase.supplier_id → SuppMaster.RecID</c> 命中 <b>0/4449</b>
|
|
|
|
|
+ /// (存量是 19 位雪花值,而 <c>RecID</c> 最大 3585)⇒ <c>RecID</c> 无任何读取消费方,
|
|
|
|
|
+ /// **不物化 <c>legacy_source_id</c>**。</para>
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para>🔴 <c>supplier_name</c> **绝不能设 Required**:<c>SortName</c> 有 <b>21 行 NULL</b>(全在租户 797)。
|
|
|
|
|
+ /// 误设会让 <c>RowGuards</c> 生成 <c>IS NOT NULL</c> 过滤 → <c>dim_count 3164 < stg_count 3185</c>
|
|
|
|
|
+ /// → 阻断级对账 FAIL,且报错指向对账而非字段声明,极难定位。
|
|
|
|
|
+ /// 同理 <c>source_updated_at</c> 可空(<c>UpdateTime</c> 有 12 行 NULL,全在租户 838257186181189)。</para>
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para>字段取舍(28 列 → 物化 9 列):本表 <b>11 列近乎全空</b> ——
|
|
|
|
|
+ /// <c>CrTerms</c>/<c>Curr</c>/<c>Type</c>/<c>TaxClass</c>/<c>address</c>/<c>contact</c>/
|
|
|
|
|
+ /// <c>position</c>/<c>contact_info</c>/<c>certification_level</c> 非空白值 <b>0/3575</b>;
|
|
|
|
|
+ /// <c>PurContact</c> 2 行、<c>Remark</c> 1 行。它们有真实 CRUD 写入路径、**不是影子列**,只是无人填;
|
|
|
|
|
+ /// 其中联系人/联系方式/职务另属 PII,即便将来填充也须重新评审。
|
|
|
|
|
+ /// <c>APStartDay1</c> 等 4 列虽 99.97% 非 NULL,但应用自身
|
|
|
|
|
+ /// (<c>FormatApDay</c> 的 <c>value == 0 → ""</c>)把 0 判为无值,有效填充率仅 2.01%/0.196%。</para>
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// <para><c>IsActive</c> / <c>TaxIn</c> 都是 <c>tinyint(1) NOT NULL</c>(非 <c>bit(1)</c>、非可空),
|
|
|
|
|
+ /// <see cref="S0DimValueKind.BoolTrue"/> 的可辨识性守卫安全。
|
|
|
|
|
+ /// 单租户最大 3185 行,<c>batch_size</c> 取 <b>20000</b> —— 默认 5000 只有 1.57× 头寸,
|
|
|
|
|
+ /// 而 <c>AssertNoSourceDuplicateAsync</c> 是 <c>sourceCount >= batchSize</c> 硬失败。</para>
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ public static readonly S0DimDefinition Supplier = new(
|
|
|
|
|
+ Key: "SUPPLIER",
|
|
|
|
|
+ EntityCode: "S0_SUPPLIER",
|
|
|
|
|
+ SourceTable: "SuppMaster",
|
|
|
|
|
+ SourceSystem: LocalSourceSystem,
|
|
|
|
|
+ StagingTable: "mdp_stg_s0_supplier",
|
|
|
|
|
+ DimTable: "dim_supplier",
|
|
|
|
|
+ BusinessKeyColumns: ["tenant_id", "supplier_code"],
|
|
|
|
|
+ SourceBizKeyColumns: ["Supp"],
|
|
|
|
|
+ Columns:
|
|
|
|
|
+ [
|
|
|
|
|
+ new("tenant_id", S0DimValueKind.TenantIdColumn),
|
|
|
|
|
+ new("supplier_code", S0DimValueKind.Str, "Supp", Required: true),
|
|
|
|
|
+ // 🔴 21 行 NULL,绝不能 Required(本表没有全称列,SortName 的 DDL 注释即「简称」,不发明第二个名称列)
|
|
|
|
|
+ new("supplier_name", S0DimValueKind.Str, "SortName"),
|
|
|
|
|
+ new("is_active", S0DimValueKind.BoolTrue, "IsActive"),
|
|
|
|
|
+ new("tax_included", S0DimValueKind.BoolTrue, "TaxIn"),
|
|
|
|
|
+ // ── LEGACY_SCOPE(属性透传,绝不入唯一键;三者均为 f(tenant))
|
|
|
|
|
+ new("domain_code", S0DimValueKind.Str, "Domain"),
|
|
|
|
|
+ new("company_id", S0DimValueKind.Int, "company_ref_id", Required: true),
|
|
|
|
|
+ new("factory_id", S0DimValueKind.Int, "factory_ref_id", Required: true),
|
|
|
|
|
+ new("source_updated_at", S0DimValueKind.DateTimeSec, "UpdateTime")
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 物料。源 <c>ItemMaster</c> —— **S0 的 Item 权威**(2026-09-07 拍板)。
|
|
/// 物料。源 <c>ItemMaster</c> —— **S0 的 Item 权威**(2026-09-07 拍板)。
|
|
|
///
|
|
///
|
|
@@ -1237,8 +1302,9 @@ public static class S0DimCatalog
|
|
|
LabelType, SopFileType, QualityBaseType,
|
|
LabelType, SopFileType, QualityBaseType,
|
|
|
// C2-2 qms 字典族(共用 mdp_stg_s0_qms_dict)
|
|
// C2-2 qms 字典族(共用 mdp_stg_s0_qms_dict)
|
|
|
SamplingScheme, InspectionItem, InspectionMethod, InspectionFrequency, InspectionInstrument,
|
|
SamplingScheme, InspectionItem, InspectionMethod, InspectionFrequency, InspectionInstrument,
|
|
|
- // C1 扩展:物料(S0 Item 权威;后续 6 张 C3 都要挂它作父,故必须排在 C3 之前)
|
|
|
|
|
- Item,
|
|
|
|
|
|
|
+ // C1 扩展:供应商(S0 Supplier 权威)与物料(S0 Item 权威;
|
|
|
|
|
+ // 后续 6 张 C3 都要挂 Item 作父,故 Item 必须排在 C3 之前)
|
|
|
|
|
+ Supplier, Item,
|
|
|
// C3 关系桥(EmpWorkDuty 的父 dim_employee 在前;LinePostSkill 的父 LinePost 紧邻其前)
|
|
// C3 关系桥(EmpWorkDuty 的父 dim_employee 在前;LinePostSkill 的父 LinePost 紧邻其前)
|
|
|
EmpWorkDuty, LinePost, LinePostSkill,
|
|
EmpWorkDuty, LinePost, LinePostSkill,
|
|
|
// C3-A 物料桥(父 dim_item,必须排在 Item 之后)
|
|
// C3-A 物料桥(父 dim_item,必须排在 Item 之后)
|