From dd3461812f84ac4f930d3c51e5b8eba92fea4dab Mon Sep 17 00:00:00 2001
From: kyy <3283105747@qq.com>
Date: 星期五, 12 九月 2025 15:47:29 +0800
Subject: [PATCH] 1、采购订单日期转换 2、收料通知修改

---
 MES.Service/service/BasicData/MesInvItemArnManager.cs |  547 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 321 insertions(+), 226 deletions(-)

diff --git a/MES.Service/service/BasicData/MesInvItemArnManager.cs b/MES.Service/service/BasicData/MesInvItemArnManager.cs
index 53e92ad..e958c16 100644
--- a/MES.Service/service/BasicData/MesInvItemArnManager.cs
+++ b/MES.Service/service/BasicData/MesInvItemArnManager.cs
@@ -7,257 +7,352 @@
 using System.Collections.Generic;
 using System.Linq;
 
-namespace MES.Service.service;
-
-/// <summary>
-/// 鏀舵枡鍗曟暟鎹鐞嗙被锛堝鐞咵RP鏀舵枡鍗曟暟鎹悓姝ュ埌MES鏀舵枡鍗曡〃锛�
-/// 鍏宠仈涓昏〃锛歁esInvItemArn锛屾槑缁嗚〃锛歁esInvItemArnDetail
-/// 鍏宠仈ERP DTO锛欵rpSltz锛堣仛鍚堢被锛夈�丒rpSltza锛圗RP涓昏〃锛夈�丒rpSltzBList锛圗RP鏄庣粏锛�
-/// </summary>
-public class MesInvItemArnManager : Repository<MesInvItemArn>
+namespace MES.Service.service
 {
     /// <summary>
-    /// 鎵归噺淇濆瓨鏀舵枡鍗曪紙涓昏〃+鏄庣粏锛�- 浜嬪姟淇濊瘉鎵归噺鎿嶄綔涓�鑷存��
+    /// 鏀舵枡鍗曟暟鎹鐞嗙被锛堝鐞咵RP鏀舵枡鍗曟暟鎹悓姝ュ埌MES鏀舵枡鍗曡〃锛�
+    /// 鍏宠仈涓昏〃锛歁esInvItemArn锛圡ES鏀舵枡鍗曚富琛級
+    /// 鍏宠仈鏄庣粏琛細MesInvItemArnDetail锛圡ES鏀舵枡鍗曟槑缁嗚〃锛�
+    /// 鍏宠仈ERP DTO锛欵rpSltz锛堣仛鍚堢被锛屽惈涓昏〃+鏄庣粏锛夈�丒rpSltza锛圗RP鏀舵枡鍗曚富琛級銆丒rpSltzBList锛圗RP鏀舵枡鍗曟槑缁嗭級
     /// </summary>
-    /// <param name="erpSltzList">ERP鏀舵枡鍗曞垪琛紙鍚富琛�+鏄庣粏锛�</param>
-    /// <returns>鍏ㄩ儴鎴愬姛杩斿洖true锛屽惁鍒檉alse</returns>
-    public bool SaveList(List<ErpSltz> erpSltzList)
+    public class MesInvItemArnManager : Repository<MesInvItemArn>
     {
-        if (erpSltzList == null || !erpSltzList.Any())
-            throw new ArgumentNullException(nameof(erpSltzList), "寰呬繚瀛樼殑鏀舵枡鍗曞垪琛ㄤ笉鑳戒负绌�");
-
-        // 淇锛氱敤浜嬪姟鍖呰9鎵归噺鎿嶄綔锛岀‘淇濇暟鎹竴鑷存��
-        return UseTransaction(db =>
+        /// <summary>
+        /// 鎵归噺淇濆瓨鏀舵枡鍗曪紙涓昏〃+鏄庣粏锛�- 浜嬪姟淇濊瘉鎵归噺鎿嶄綔涓�鑷存��
+        /// 鍗曟潯澶辫触鍒欐暣浣撳洖婊�
+        /// </summary>
+        public bool SaveList(List<ErpSltz> erpSltzList)
         {
-            foreach (var erpSltz in erpSltzList)
+            if (erpSltzList == null || !erpSltzList.Any())
+                throw new ArgumentNullException(nameof(erpSltzList), "寰呬繚瀛樼殑鏀舵枡鍗曞垪琛ㄤ笉鑳戒负绌�");
+
+            return UseTransaction(db =>
             {
-                // 淇锛氳皟鐢ㄤ簨鍔″唴鐨凷ave鏂规硶锛屼紶鍏b瀹炰緥
-                if (!Save(db, erpSltz))
+                foreach (var erpSltz in erpSltzList)
                 {
-                    return 0; // 鍗曟潯澶辫触锛屼簨鍔″洖婊�
+                    if (!SaveInTransaction(db, erpSltz))
+                        return 0; // 瑙﹀彂鍥炴粴
                 }
-            }
-            return 1; // 鍏ㄩ儴鎴愬姛
-        }) > 0;
-    }
 
-    /// <summary>
-    /// 鍗曟潯淇濆瓨鏀舵枡鍗曪紙涓昏〃+鏄庣粏锛�- 浜嬪姟鍐呰皟鐢紙淇璁块棶淇グ绗︼紝纭繚浜嬪姟鍐呭彲鐢級
-    /// </summary>
-    /// <param name="db">浜嬪姟鍐呯殑SqlSugar瀹炰緥</param>
-    /// <param name="erpSltz">ERP鏀舵枡鍗曪紙鍚富琛�+鏄庣粏锛�</param>
-    /// <returns>鍗曟潯澶勭悊鎴愬姛杩斿洖true</returns>
-    private bool Save(SqlSugarScope db, ErpSltz erpSltz)
-    {
-        // 1. 鍙傛暟鏍¢獙
-        if (erpSltz == null)
-            throw new ArgumentNullException(nameof(erpSltz), "鏀舵枡鍗曟暟鎹笉鑳戒负绌�");
-        if (erpSltz.ErpSltza == null)
-            throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "鏀舵枡鍗曚富琛ㄦ暟鎹笉鑳戒负绌�");
-
-        // 2. 鎻愬彇ERP涓昏〃鍜屾槑缁嗘暟鎹�
-        var erpMain = erpSltz.ErpSltza;
-        var erpDetails = erpSltz.ErpSltzBList ?? new List<ErpSltzBList>();
-
-        // 3. 淇锛氱敤浜嬪姟鍐呯殑db鏌ヨ锛岀‘淇濇暟鎹竴鑷存��
-        Guid mainId = GetOrCreateMainId(db, erpMain);
-
-        // 4. 鏄犲皠ERP鏁版嵁鍒癕ES瀹炰綋锛堜慨澶嶅瓧娈垫敞閲婏紝琛ュ厖鍏抽敭灞炴�э級
-        var mesMain = MapErpSltzaToMesInvItemArn(erpMain, mainId);
-        var mesDetails = MapErpSltzBListToMesInvItemArnDetail(erpDetails, mainId);
-
-        // 5. 鏍规嵁鎿嶄綔绫诲瀷澶勭悊鏁版嵁
-        switch (erpMain.TYPE?.Trim())
-        {
-            case "1": // 鏂板
-            case "2": // 鏇存柊
-                return HandleSaveOrUpdate(db, mesMain, mesDetails, mainId);
-            case "3": // 鍒犻櫎
-                return HandleDelete(db, mesMain, mesDetails, mainId);
-            default:
-                throw new NotImplementedException($"鏈疄鐜扮殑鏀舵枡鍗曟搷浣滅被鍨嬶細{erpMain.TYPE}锛堟敮鎸佺被鍨嬶細1-鏂板锛�2-鏇存柊锛�3-鍒犻櫎锛�");
+                return 1; // 鎻愪氦
+            }) > 0;
         }
-    }
 
-    /// <summary>
-    /// 鍗曟潯淇濆瓨鏀舵枡鍗曪紙涓昏〃+鏄庣粏锛�- 瀵瑰鍏紑鎺ュ彛锛堜緵鎺у埗鍣ㄨ皟鐢級
-    /// </summary>
-    /// <param name="erpSltz">ERP鏀舵枡鍗曟暟鎹紙鍚富琛�+鏄庣粏锛�</param>
-    /// <returns>淇濆瓨鎴愬姛杩斿洖true</returns>
-    public bool Save(ErpSltz erpSltz)
-    {
-        if (erpSltz == null)
-            throw new ArgumentNullException(nameof(erpSltz), "鏀舵枡鍗曟暟鎹笉鑳戒负绌�");
-        if (erpSltz.ErpSltza == null)
-            throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "鏀舵枡鍗曚富琛ㄦ暟鎹笉鑳戒负绌�");
-
-        // 浜嬪姟鍐呭鐞嗕富浠庤〃淇濆瓨
-        return UseTransaction(db =>
+        /// <summary>
+        /// 瀵瑰鍗曟潯淇濆瓨锛堝唴閮ㄨ嚜鍔ㄤ簨鍔★級
+        /// </summary>
+        public bool Save(ErpSltz erpSltz)
         {
-            return Save(db, erpSltz) ? 1 : 0;
-        }) > 0;
-    }
+            if (erpSltz == null) throw new ArgumentNullException(nameof(erpSltz), "鏀舵枡鍗曟暟鎹笉鑳戒负绌�");
+            if (erpSltz.ErpSltza == null) throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "鏀舵枡鍗曚富琛ㄦ暟鎹笉鑳戒负绌�");
 
-    /// <summary>
-    /// 鎻愬墠鑾峰彇鎴栫敓鎴怣ES涓昏〃ID锛堜慨澶嶏細鐢ㄤ簨鍔″唴db鏌ヨ锛�
-    /// </summary>
-    private Guid GetOrCreateMainId(SqlSugarScope db, ErpSltza erpMain)
-    {
-        if (string.IsNullOrEmpty(erpMain.billNo))
-            throw new ArgumentException("ERP鏀舵枡鍗曞崟鎹彿涓嶈兘涓虹┖锛屾棤娉曠‘瀹氫富琛ㄥ敮涓�鎬�", nameof(erpMain.billNo));
+            return UseTransaction(db => SaveInTransaction(db, erpSltz) ? 1 : 0) > 0;
+        }
 
-        // 淇锛氱敤浜嬪姟鍐呯殑db鏌ヨ锛岃�岄潪Context
-        var existingMain = db.Queryable<MesInvItemArn>()
-            .Where(m => m.BillNo == erpMain.billNo)
-            .First();
-
-        return existingMain != null 
-            ? existingMain.Id 
-            : Guid.NewGuid();
-    }
-
-    /// <summary>
-    /// 澶勭悊鏀舵枡鍗曟柊澧�/鏇存柊锛堜富琛�+鏄庣粏锛�
-    /// </summary>
-    private bool HandleSaveOrUpdate(SqlSugarScope db, MesInvItemArn mesMain, List<MesInvItemArnDetail> mesDetails, Guid mainId)
-    {
-        mesMain.Id = mainId;
-        bool isMainExist = db.Queryable<MesInvItemArn>().Where(m => m.Id == mainId).Any();
-        int mainOperateResult;
-
-        if (isMainExist)
+        /// <summary>
+        /// 浜嬪姟鍐呭崟鏉′繚瀛�
+        /// </summary>
+        private bool SaveInTransaction(SqlSugarScope db, ErpSltz erpSltz)
         {
-            mainOperateResult = db.Updateable(mesMain)
-                .IgnoreColumns(m => new { m.CreateDate })
+            if (erpSltz == null) throw new ArgumentNullException(nameof(erpSltz), "鏀舵枡鍗曟暟鎹笉鑳戒负绌�");
+            if (erpSltz.ErpSltza == null) throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "鏀舵枡鍗曚富琛ㄦ暟鎹笉鑳戒负绌�");
+
+            var erpMain = erpSltz.ErpSltza;
+            var erpDetails = erpSltz.ErpSltzBList ?? new List<ErpSltzBList>();
+
+            // 閫氳繃 ERP 鍗曞彿纭畾/鐢熸垚涓昏〃ID
+            Guid mainId = GetOrCreateMainId(db, erpMain);
+
+            // 鏄犲皠
+            var mesMain = MapErpMainToMesMain(erpMain, mainId,db);
+            var mesDetails = MapErpDetailsToMesDetails(db, erpDetails, mainId);
+
+            // 绫诲瀷锛�1 鏂板锛�2 鏇存柊锛�3 鍒犻櫎
+            var type = TrimOrNull(erpMain.TYPE);
+            return type switch
+            {
+                "1" or "2" => HandleSaveOrUpdate(db, mesMain, mesDetails, mainId),
+                "3" => HandleDelete(db, mainId),
+                _ => throw new NotImplementedException($"鏈疄鐜扮殑鏀舵枡鍗曟搷浣滅被鍨嬶細{erpMain.TYPE}锛堟敮鎸侊細1-鏂板锛�2-鏇存柊锛�3-鍒犻櫎锛�")
+            };
+        }
+
+        /// <summary>
+        /// 鑾峰彇鎴栫敓鎴愪富琛↖D锛堟寜 ERP DeliveryNo 鍞竴锛�
+        /// </summary>
+        private Guid GetOrCreateMainId(SqlSugarScope db, ErpSltza erpMain)
+        {
+            var billNo = TrimOrNull(erpMain.DeliveryNo)
+                         ?? throw new ArgumentException("ERP鏀舵枡鍗曞崟鎹彿锛圖eliveryNo锛変笉鑳戒负绌猴紝鏃犳硶纭畾涓昏〃鍞竴鎬�",
+                             nameof(erpMain.DeliveryNo));
+
+            // SqlSugar: 鐢� First()锛屾棤鏁版嵁杩斿洖 null
+            var existingMain = db.Queryable<MesInvItemArn>()
+                .Where(m => m.BillNo == billNo)
+                .First();
+
+            return existingMain?.Id ?? Guid.NewGuid();
+        }
+
+        /// <summary>
+        /// 鏂板/鏇存柊锛堜富琛�+鏄庣粏锛氬厛鍒犳棫鏄庣粏鍐嶆彃鏂帮級
+        /// </summary>
+        private bool HandleSaveOrUpdate(SqlSugarScope db, MesInvItemArn mesMain, List<MesInvItemArnDetail> mesDetails,
+            Guid mainId)
+        {
+            mesMain.Id = mainId;
+
+            bool isMainExist = db.Queryable<MesInvItemArn>()
+                .Where(m => m.Id == mainId)
+                .Any();
+
+            int mainOperateResult;
+            if (isMainExist)
+            {
+                mainOperateResult = db.Updateable(mesMain)
+                    .IgnoreColumns(m => new { m.CreateDate })
+                    .Where(m => m.Id == mainId)
+                    .ExecuteCommand();
+            }
+            else
+            {
+                mesMain.CreateDate = DateTime.Now;
+                mainOperateResult = db.Insertable(mesMain).ExecuteCommand();
+            }
+
+            // 鏄庣粏鍚屾锛氬垹鏃� + 鎻掓柊
+            int deleteOldDetailsResult = db.Deleteable<MesInvItemArnDetail>()
+                .Where(d => d.Mid == mainId)
+                .ExecuteCommand();
+
+            int insertNewDetailsResult = mesDetails.Count > 0
+                ? db.Insertable(mesDetails).ExecuteCommand()
+                : 1;
+
+            return mainOperateResult > 0 && deleteOldDetailsResult >= 0 && insertNewDetailsResult > 0;
+        }
+
+        /// <summary>
+        /// 鍒犻櫎锛堝厛鍒犳槑缁嗗啀鍒犱富琛級
+        /// </summary>
+        private bool HandleDelete(SqlSugarScope db, Guid mainId)
+        {
+            db.Deleteable<MesInvItemArnDetail>()
+                .Where(d => d.Mid == mainId)
+                .ExecuteCommand();
+
+            int deleteMainResult = db.Deleteable<MesInvItemArn>()
                 .Where(m => m.Id == mainId)
                 .ExecuteCommand();
-        }
-        else
-        {
-            mesMain.CreateDate = DateTime.Now;
-            mainOperateResult = db.Insertable(mesMain).ExecuteCommand();
+
+            return deleteMainResult >= 0;
         }
 
-        // 澶勭悊鏄庣粏
-        int deleteOldDetailResult = db.Deleteable<MesInvItemArnDetail>()
-            .Where(d => d.Mid == mainId)
-            .ExecuteCommand();
-
-        int insertNewDetailResult = mesDetails.Count > 0
-            ? db.Insertable(mesDetails).ExecuteCommand()
-            : 1;
-
-        return mainOperateResult > 0 && (deleteOldDetailResult >= 0 && insertNewDetailResult > 0);
-    }
-
-    /// <summary>
-    /// 澶勭悊鏀舵枡鍗曞垹闄わ紙涓昏〃+鏄庣粏锛�
-    /// </summary>
-    private bool HandleDelete(SqlSugarScope db, MesInvItemArn mesMain, List<MesInvItemArnDetail> mesDetails, Guid mainId)
-    {
-        db.Deleteable<MesInvItemArnDetail>().Where(d => d.Mid == mainId).ExecuteCommand();
-        int mainDeleteResult = db.Deleteable<MesInvItemArn>().Where(m => m.Id == mainId).ExecuteCommand();
-        return mainDeleteResult >= 0;
-    }
-
-    /// <summary>
-    /// ERP涓昏〃鏄犲皠鍒癕ES涓昏〃锛堜慨澶嶏細鍙栨秷鍏抽敭瀛楁娉ㄩ噴锛屼慨姝Type閫昏緫锛�
-    /// </summary>
-    private MesInvItemArn MapErpSltzaToMesInvItemArn(ErpSltza erpMain, Guid mainId)
-    {
-        // 鍗曟嵁鏃ユ湡杞崲
-        DateTime.TryParse(erpMain.FDate, out DateTime parsedDate);
-        // 鏄惁SRM杞崲锛�0-鍚︼紝1-鏄級
-        int.TryParse(erpMain.F_ZJXF_sfgx, out int isSrm);
-        // 渚涘簲鍟咺D杞崲锛堝瓧绗︿覆鐩存帴璧嬪�硷紝鍖归厤MES瀛楁绫诲瀷锛�
-        string suppId = string.IsNullOrEmpty(erpMain.SupplierId) ? null : erpMain.SupplierId.Trim();
-        // 淇锛氣�滄槸鍚﹀澶栤�濋�昏緫锛堝亣璁綞RP鐨刦Type鏄��1鈥�=鏄紝鈥�0鈥�=鍚︼紝鎴朾ool瀛楃涓诧級
-        bool isOutsourcing = false;
-        if (!string.IsNullOrEmpty(erpMain.fType))
+        /// <summary>
+        /// ERP 涓昏〃 -> MES 涓昏〃
+        /// </summary>
+        private MesInvItemArn MapErpMainToMesMain(ErpSltza erpMain, Guid mainId, SqlSugarScope db)
         {
-            isOutsourcing = erpMain.fType.Trim() == "1" || erpMain.fType.Trim().Equals("true", StringComparison.OrdinalIgnoreCase);
-        }
-
-        return new MesInvItemArn
-        {
-            // 淇锛氬彇娑堝叧閿瓧娈垫敞閲婏紝琛ュ厖璧嬪��
-            Id = mainId,
-            BillNo = erpMain.billNo?.Trim() ?? throw new ArgumentException("鏀舵枡鍗曞崟鎹彿涓嶈兘涓虹┖"),
-            SuppId = suppId,
-            CreateDate = parsedDate == DateTime.MinValue ? null : (DateTime?)parsedDate,
-            Remark = erpMain.Remark?.Trim(),
-            IsSrm = isSrm,
-            EbelnK3id = erpMain.erpId?.Trim(), // ERP涓昏〃ID锛堝搴攅beln_k3id锛�
-            CreateBy = erpMain.createBy?.Trim() ?? "SYSTEM", // 榛樿涓虹郴缁�
-            FType = isOutsourcing, // 淇锛氭纭殑鏄惁濮斿閫昏緫
-            ReceiveOrgId = erpMain.ReceiveOrgId?.Trim(),
-            // LastUpdateUser = erpMain.FCreatorId?.Trim() ?? "SYSTEM",
-            // LastUpdateTime = DateTime.Now,
-            // IsOut = false, // 鍒濆鏈嚭搴�
-            // Status = false // 鍒濆鏈鏍�
-        };
-    }
-
-    /// <summary>
-    /// ERP鏄庣粏鏄犲皠鍒癕ES鏄庣粏锛堜慨澶嶏細鍙栨秷鍏抽敭瀛楁娉ㄩ噴锛屼慨姝belnK3id杞崲锛�
-    /// </summary>
-    private List<MesInvItemArnDetail> MapErpSltzBListToMesInvItemArnDetail(List<ErpSltzBList> erpDetails, Guid mainId)
-    {
-        return erpDetails.Select(erpDetail =>
-        {
-            // 鏁板�肩被鍨嬪畨鍏ㄨ浆鎹�
-            int.TryParse(erpDetail.LineNo, out int lineNo); // 鏄庣粏涓婚敭
-            int.TryParse(erpDetail.ProductCode, out int itemId); // 鐗╂枡缂栫爜
-            decimal.TryParse(erpDetail.PurchaseQty, out decimal purchaseQty); // 閲囪喘璁㈠崟鏁伴噺
-            decimal.TryParse(erpDetail.DeliveryQty, out decimal deliveryQty); // 鏈搴旀敹鏁伴噺
-            decimal.TryParse(erpDetail.IncludeQty, out decimal includeQty); // 鏈瀹炴敹鏁伴噺
-            // 淇锛氱敤閲囪喘鍗旾D瀛楁锛坋beln_k3id锛夎浆int锛岃�岄潪婧愬崟鍗曞彿
-            int.TryParse(erpDetail.FSrcBillNo, out int ebelnK3id); 
-            int.TryParse(erpDetail.FSrcBillLine, out int lineK3id); // 閲囪喘鍗曡ID
-            bool.TryParse(erpDetail.urgentFlag, out bool urgentFlag); // 鎬ユ枡鏍囪瘑
-
-            return new MesInvItemArnDetail
+            var billNo = TrimOrNull(erpMain.DeliveryNo)
+                         ?? throw new ArgumentException("鏀舵枡鍗曞崟鎹彿涓嶈兘涓虹┖");
+            // 鑾峰彇渚涘簲鍟嗙紪鍙峰苟鏌ヨ瀵瑰簲鐨処D
+            string suppNo = TrimOrNull(erpMain.SupplierId);
+            decimal ? suppId = null;
+            if (!string.IsNullOrEmpty(suppNo))
             {
-                // 淇锛氬彇娑堝叧閿瓧娈垫敞閲婏紝琛ュ厖璧嬪��
-            //    LineNo = lineNo, // 鏄庣粏涓婚敭锛堝繀椤昏祴鍊硷級
-                Mid = mainId, // 澶栭敭锛堝叧鑱斾富琛↖D锛屽繀椤昏祴鍊硷級
-                Ebeln = erpDetail.FBillNo?.Trim(), // 閲囪喘鍗曞彿
-                ItemId = itemId,
-                EbelnQty = purchaseQty,
-                SubQty = deliveryQty,
-                Quantity = includeQty,
-              //  PurchaseUnit = erpDetail.PurchaseUnit?.Trim(), // 閲囪喘鍗曚綅锛堣ˉ鍏呰祴鍊硷級
-              //  InventoryUnit = erpDetail.InventoryUnit?.Trim(), // 搴撳瓨鍗曚綅锛堣ˉ鍏呰祴鍊硷級
-                Memo = erpDetail.Remark?.Trim(),
-                EbelnK3id = ebelnK3id, // 淇锛氭纭殑閲囪喘鍗旾D杞崲
-                LineK3id = lineK3id,
-             //   SalesOrderId = erpDetail.SalesOrderId?.Trim(), // 閿�鍞鍗曞彿锛堣ˉ鍏呰祴鍊硷級
-              //  FMtoNo = erpDetail.FMtoNo?.Trim(), // 璁″垝璺熻釜鍙凤紙琛ュ厖璧嬪�硷級
-             //   FLot = erpDetail.FLot?.Trim(), // 鎵瑰彿锛堣ˉ鍏呰祴鍊硷級
-                UrgentFlag = urgentFlag
-                //FStockId = erpDetail.DepotId?.Trim() // 鏀惰揣浠撳簱缂栧彿
+                // 浠庢暟鎹簱鏌ヨ渚涘簲鍟咺D锛圫uppNo鍞竴锛�
+                suppId = db.Queryable<MesSupplier>()
+                    .Where(s => s.SuppNo == suppNo)
+                    .Select(s => s.Id)
+                    .First();
+
+                // 鍙�夛細濡傛灉闇�瑕佷弗鏍奸獙璇佷緵搴斿晢瀛樺湪鎬э紝鍙栨秷涓嬮潰娉ㄩ噴
+                 if (suppId == null)
+                 {
+                     throw new KeyNotFoundException($"鏈壘鍒扮紪鍙蜂负銆恵suppNo}銆戠殑渚涘簲鍟嗕俊鎭�");
+                 }
+            }
+            // 鏄惁 SRM
+            var isSrm = ToInt(erpMain.F_ZJXF_sfgx, 0);
+
+            // 鏄惁濮斿锛欵RP鐨� fType 涓� "1"/"true" 瑙嗕负濮斿
+            var fTypeStr = TrimOrNull(erpMain.fType);
+            bool isOutsourcing = fTypeStr is not null &&
+                                 (fTypeStr == "1" || fTypeStr.Equals("true", StringComparison.OrdinalIgnoreCase));
+
+            return new MesInvItemArn
+            {
+                Id = mainId,
+                BillNo = billNo,
+                SuppId = suppId.ToString(),
+                CreateDate = ToDate(erpMain.FDate), // null 琛ㄧず鏈煡
+                Remark = TrimOrNull(erpMain.Remark),
+                IsSrm = isSrm,
+                EbelnK3id = TrimOrNull(erpMain.erpId),
+                CreateBy = TrimOrNull(erpMain.createBy) ?? "SYSTEM",
+                FType = isOutsourcing,
+                ReceiveOrgId = TrimOrNull(erpMain.ReceiveOrgId)
             };
-        }).ToList();
-    }
+        }
 
-    /// <summary>
-    /// 鎸夊崟鎹彿鏌ヨMES鏀舵枡鍗曪紙涓昏〃+鏄庣粏锛�
-    /// </summary>
-    public (MesInvItemArn main, List<MesInvItemArnDetail> details) GetByBillNo(string billNo)
-    {
-        if (string.IsNullOrEmpty(billNo))
-            throw new ArgumentNullException(nameof(billNo), "鏌ヨ鏉′欢鍗曟嵁鍙蜂笉鑳戒负绌�");
+        /// <summary>
+        /// ERP 鏄庣粏 -> MES 鏄庣粏
+        /// 鏍稿績锛氶�氳繃 ERP ProductCode 鍖归厤 mes_items.item_no 鑾峰彇 item_id
+        /// </summary>
+        private List<MesInvItemArnDetail> MapErpDetailsToMesDetails(SqlSugarScope db, List<ErpSltzBList> erpDetails,
+            Guid mainId)
+        {
+            var productCodes = erpDetails
+                .Where(d => !string.IsNullOrWhiteSpace(d.ProductCode))
+                .Select(d => d.ProductCode.Trim())
+                .Distinct()
+                .ToList();
 
-        var main = Context.Queryable<MesInvItemArn>()
-            .Where(m => m.BillNo == billNo)
-            .First();
+            // 鍏� ToList 鍐� ToDictionary锛岄伩鍏嶇洿鎺ュ ISugarQueryable 璋冪敤鎷撳睍鏂规硶澶辫触
+            var itemPairs = db.Queryable<MesItems>()
+                .Where(item => productCodes.Contains(item.ItemNo))
+                .Select(item => new { item.ItemNo, item.Id })
+                .ToList();
 
-        var details = main != null
-            ? Context.Queryable<MesInvItemArnDetail>()
-                .Where(d => d.Mid == main.Id)
-                .ToList()
-            : new List<MesInvItemArnDetail>();
+            var itemMap = itemPairs.ToDictionary(k => k.ItemNo, v => v.Id);
 
-        return (main, details);
+            var list = new List<MesInvItemArnDetail>(erpDetails.Count);
+
+            foreach (var erpDetail in erpDetails)
+            {
+                var lineNo = ToInt(erpDetail.LineNo);
+                var productCode = TrimOrNull(erpDetail.ProductCode);
+
+                if (productCode == null)
+                    throw new ArgumentNullException(nameof(erpDetail.ProductCode),
+                        $"ERP鏀舵枡鍗曟槑缁嗐�愯锛歿lineNo}銆戠殑鐗╂枡缂栫爜锛圥roductCode锛変笉鑳戒负绌猴紝鏃犳硶鐢熸垚鏄庣粏");
+
+                if (!itemMap.TryGetValue(productCode, out var itemId))
+                    throw new KeyNotFoundException(
+                        $"ERP鏀舵枡鍗曟槑缁嗐�愯锛歿lineNo}銆戠殑鐗╂枡缂栫爜銆恵productCode}銆戝湪 MES.mes_items 涓湭鎵惧埌鍖归厤鐨� item_no");
+
+                var detail = new MesInvItemArnDetail
+                {
+                    DeliveryLineID = lineNo,
+                    Eid = ToInt(erpDetail.ErpId),
+                    Mid = mainId,
+                    Ebeln = TrimOrNull(erpDetail.FBillNo),
+                    ItemId = ToInt(itemId),
+                    EbelnQty = ToDecimal(erpDetail.PurchaseQty),
+                    SubQty = ToDecimal(erpDetail.DeliveryQty),
+                    Quantity = ToDecimal(erpDetail.IncludeQty),
+                    PurchaseUnit = TrimOrNull(erpDetail.PurchaseUnit),
+                    InventoryUnit = TrimOrNull(erpDetail.InventoryUnit),
+                    Memo = TrimOrNull(erpDetail.Remark),
+                    EbelnK3id = ToInt(erpDetail.FSrcBillNo),
+                    LineK3id = ToInt(erpDetail.FSrcBillLine),
+                    SalesOrderId = TrimOrNull(erpDetail.SalesOrderId),
+                    MtoNo = TrimOrNull(erpDetail.FMtoNo),
+                    Lot = TrimOrNull(erpDetail.FLot),
+                    UrgentFlag = ToBool(erpDetail.urgentFlag),
+                    DepotId = ToInt(erpDetail.DepotId)
+                };
+
+                list.Add(detail);
+            }
+
+            return list;
+        }
+
+        /// <summary>
+        /// 鎸夊崟鎹彿鏌ヨ锛堜富+鏄庣粏锛�
+        /// </summary>
+        public (MesInvItemArn main, List<MesInvItemArnDetail> details) GetByBillNo(string billNo)
+        {
+            if (string.IsNullOrWhiteSpace(billNo))
+                throw new ArgumentNullException(nameof(billNo), "鏌ヨ鏉′欢鍗曟嵁鍙蜂笉鑳戒负绌�");
+
+            var no = billNo.Trim();
+
+            // SqlSugar: First()
+            var main = Context.Queryable<MesInvItemArn>()
+                .Where(m => m.BillNo == no)
+                .First();
+
+            var details = main != null
+                ? Context.Queryable<MesInvItemArnDetail>().Where(d => d.Mid == main.Id).ToList()
+                : new List<MesInvItemArnDetail>();
+
+            return (main, details);
+        }
+
+        #region 瀹夊叏杞崲/宸ュ叿鏂规硶
+
+        private static string TrimOrNull(string s) =>
+            string.IsNullOrWhiteSpace(s) ? null : s.Trim();
+
+        private static int ToInt(object value, int @default = 0)
+        {
+            switch (value)
+            {
+                case null: return @default;
+                case int i: return i;
+                case long l: return unchecked((int)l);
+                case short sh: return sh;
+                case byte b: return b;
+                case decimal dm: return (int)dm;
+                case double db: return (int)db;
+                case float f: return (int)f;
+                case string s when int.TryParse(s, out var n): return n;
+                default: return @default;
+            }
+        }
+
+        private static decimal ToDecimal(object value, decimal @default = 0m)
+        {
+            switch (value)
+            {
+                case null: return @default;
+                case decimal dm: return dm;
+                case double db: return (decimal)db;
+                case float f: return (decimal)f;
+                case int i: return i;
+                case long l: return l;
+                case string s when decimal.TryParse(s, out var n): return n;
+                default: return @default;
+            }
+        }
+
+        private static bool ToBool(object value, bool @default = false)
+        {
+            switch (value)
+            {
+                case null: return @default;
+                case bool b: return b;
+                case int i: return i != 0;
+                case long l: return l != 0;
+                case string s:
+                    var t = s.Trim().ToLowerInvariant();
+                    return t switch
+                    {
+                        "1" => true,
+                        "0" => false,
+                        "y" => true,
+                        "n" => false,
+                        "true" => true,
+                        "false" => false,
+                        _ => @default
+                    };
+                default: return @default;
+            }
+        }
+
+        private static DateTime? ToDate(object value)
+        {
+            switch (value)
+            {
+                case null: return null;
+                case DateTime dt: return dt;
+                case string s when DateTime.TryParse(s, out var d): return d;
+                default: return null;
+            }
+        }
+
+        #endregion
     }
 }
\ No newline at end of file

--
Gitblit v1.9.3