WebAPI/Controllers/MateOutController.cs
@@ -1074,10 +1074,390 @@
        {
            try
            {
                SQLHelper.ClsCN oCN = new SQLHelper.ClsCN();
                List<object> columnNameList = new List<object>();
                string Ret = "";
                if (oSystemParameter.ShowBill(ref Ret))
                {
                    if (oSystemParameter.omodel.WMS_CloudMode == "Y")
                    {
                        DataSet ds = oCN.RunProcReturn("exec h_p_KF_ICInventoryByMaterIDList1 '" + HBarCode + "'," + sHWHID + "," + sHSPID + "," + HOWNERID + ",'" + sWhere + "'", "h_p_KF_ICInventoryByMaterIDList");
                        //添加列名
                        foreach (DataColumn col in ds.Tables[0].Columns)
                        {
                            Type dataType = col.DataType;
                            string ColmString = "{\"ColmCols\":\"" + col.ColumnName + "\",\"ColmType\":\"" + dataType.Name + "\"}";
                            columnNameList.Add(JsonConvert.DeserializeObject(ColmString));//获取到DataColumn列对象的列名
                        }
                        if (ds == null || ds.Tables[0].Rows.Count <= 0)
                        {
                            objJsonResult.code = "0";
                            objJsonResult.count = 0;
                            objJsonResult.Message = "没有返回任何记录!";
                            objJsonResult.data = null;
                            return objJsonResult;
                        }
                        else
                        {
                            objJsonResult.code = "1";
                            objJsonResult.count = 1;
                            objJsonResult.Message = "获取信息成功!";
                            objJsonResult.data = ds.Tables[0];
                            objJsonResult.list = columnNameList;
                            return objJsonResult;
                        }
                    }
                    else
                    {
                        //从配置文件获取 CLOUD网址、账套信息、登录用户、登录密码
                        if (!Pub_Class.ClsPub.GetCLOUDLoginInfo(ref Pub_Class.ClsPub.sExeReturnInfo))
                        {
                            objJsonResult.code = "0";
                            objJsonResult.count = 0;
                            objJsonResult.Message = "ERP库存查询,同步获取登录账号密码失败!";
                            objJsonResult.data = null;
                            return objJsonResult;
                        }
                        var loginRet = InvokeHelper.Login();
                        var isSuccess = JObject.Parse(loginRet)["LoginResultType"].Value<int>();
                        if (isSuccess == 0)
                        {
                            objJsonResult.code = "0";
                            objJsonResult.count = 0;
                            objJsonResult.Message = "登录金蝶失败!";
                            objJsonResult.data = null;
                            return objJsonResult;
                        }
                        else
                        {
                            string queryJson = BuildDynamicQueryJson(HBarCode, sHWHID, HOWNERID);
                            string result = InvokeHelper.ExecuteBillQuery("STK_Inventory", queryJson);//查询
                            var dataArray = JArray.Parse(result);
                            if (dataArray == null || dataArray.Count == 0)
                            {
                                objJsonResult.code = "1";
                                objJsonResult.count = 0;
                                objJsonResult.Message = "查询成功,无数据!";
                                objJsonResult.data = null;
                                return objJsonResult;
                            }
                            // 第一步:收集所有需要查询的ID
                            var ids = CollectIdsFromDataArray(dataArray);
                            // 第二步:批量查询数据库中的基础信息(同步方式)
                            var stockDict = BatchQuery(oCN, "Gy_Warehouse", "HName", ids.StockIds);
                            var locationDict = BatchQuery(oCN, "Gy_StockPlace", "HName", ids.LocationIds);
                            var materialDict = BatchQuery(oCN, "Gy_Material", "HNumber", ids.MaterialIds);
                            var orgDict = BatchQuery(oCN, "Xt_ORGANIZATIONS", "HName", ids.OwnerIds);
                            var propDict = BatchQuery(oCN, "Gy_Property", "HName", ids.PropIds);
                            // 第三步:批量查询批次信息(调用金蝶接口)
                            var batchDict = BatchQueryBatchInfo(ids.BatchIds);
                            var finalResults = new List<Dictionary<string, object>>();
                            // 第四步:处理数据
                            foreach (JArray item in dataArray)
                            {
                                if (item.Count >= 11)
                                {
                                    int HMaterID = item[0]?.Value<int>() ?? 0;
                                    int HStockId = item[3]?.Value<int>() ?? 0;
                                    int HLocationId = item[5]?.Value<int>() ?? 0;
                                    int FAuxPropId = item[8]?.Value<int>() ?? 0;
                                    int ownerId = item[11]?.Value<int>() ?? 0;
                                    int FLot = item[6]?.Value<int>() ?? 0; // 批次ID
                                    // 创建结果字典,使用中文字段名
                                    var resultDict = new Dictionary<string, object>
                                    {
                                        ["物料名称"] = item[1].Value<string>(),
                                        ["规格型号"] = item[2].Value<string>(),
                                        ["数量"] = item[4].Value<decimal>(),
                                        ["生产日期"] = DBUtility.ClsPub.isDate(item[8]?.Value<string>()),
                                        ["有效期至"] = DBUtility.ClsPub.isDate(item[9]?.Value<string>())
                                    };
                                    // 从字典获取仓库名称
                                    if (HStockId > 0 && stockDict.TryGetValue(HStockId, out string stockName))
                                        resultDict["仓库"] = stockName;
                                    else
                                        resultDict["仓库"] = "";
                                    // 从字典获取仓位名称
                                    if (HLocationId > 0 && locationDict.TryGetValue(HLocationId, out string locationName))
                                        resultDict["仓位"] = locationName;
                                    else
                                        resultDict["仓位"] = "";
                                    // 从字典获取物料代码
                                    if (HMaterID > 0 && materialDict.TryGetValue(HMaterID, out string materialCode))
                                        resultDict["物料代码"] = materialCode;
                                    else
                                        resultDict["物料代码"] = "";
                                    // 从字典获取组织名称
                                    if (ownerId > 0 && orgDict.TryGetValue(ownerId, out string orgName))
                                        resultDict["组织"] = orgName;
                                    else
                                        resultDict["组织"] = "";
                                    // 从字典获取辅助属性名称
                                    if (FAuxPropId > 0 && propDict.TryGetValue(FAuxPropId, out string propName))
                                        resultDict["辅助属性"] = propName;
                                    else
                                        resultDict["辅助属性"] = "";
                                    // 从字典获取批次名称
                                    if (FLot > 0 && batchDict.TryGetValue(FLot, out string batchName))
                                        resultDict["批次"] = batchName;
                                    else
                                        resultDict["批次"] = "";
                                    finalResults.Add(resultDict);
                                }
                            }
                            objJsonResult.code = "1";
                            objJsonResult.count = finalResults.Count;
                            objJsonResult.Message = "查询成功!";
                            objJsonResult.data = finalResults;
                            return objJsonResult;
                        }
                    }
                }
                objJsonResult.code = "1";
                objJsonResult.count = 1;
                objJsonResult.Message = "没有返回任何记录!";
                objJsonResult.data = null;
                return objJsonResult;
            }
            catch (Exception e)
            {
                objJsonResult.code = "0";
                objJsonResult.count = 0;
                objJsonResult.Message = "没有返回任何记录!" + e.ToString();
                objJsonResult.data = null;
                return objJsonResult;
            }
        }
        #region 金蝶及时库存查询 使用方法
        // 辅助类:用于收集所有需要查询的ID
        private class CollectedIds
        {
            public HashSet<int> StockIds { get; set; } = new HashSet<int>();
            public HashSet<int> LocationIds { get; set; } = new HashSet<int>();
            public HashSet<int> MaterialIds { get; set; } = new HashSet<int>();
            public HashSet<int> OwnerIds { get; set; } = new HashSet<int>();
            public HashSet<int> PropIds { get; set; } = new HashSet<int>();
            public HashSet<int> BatchIds { get; set; } = new HashSet<int>(); // 批次ID
        }
        // 收集所有需要查询的ID
        private CollectedIds CollectIdsFromDataArray(JArray dataArray)
        {
            var ids = new CollectedIds();
            foreach (JArray item in dataArray)
            {
                if (item.Count >= 11)
                {
                    int HMaterID = item[0]?.Value<int>() ?? 0;
                    int HStockId = item[3]?.Value<int>() ?? 0;
                    int HLocationId = item[5]?.Value<int>() ?? 0;
                    int FAuxPropId = item[8]?.Value<int>() ?? 0;
                    int ownerId = item[11]?.Value<int>() ?? 0;
                    int FLot = item[6]?.Value<int>() ?? 0; // 批次ID
                    if (HStockId > 0) ids.StockIds.Add(HStockId);
                    if (HLocationId > 0) ids.LocationIds.Add(HLocationId);
                    if (HMaterID > 0) ids.MaterialIds.Add(HMaterID);
                    if (ownerId > 0) ids.OwnerIds.Add(ownerId);
                    if (FAuxPropId > 0) ids.PropIds.Add(FAuxPropId);
                    if (FLot > 0) ids.BatchIds.Add(FLot); // 收集批次ID
                }
            }
            return ids;
        }
        // 批量查询方法(同步版本)
        private Dictionary<int, string> BatchQuery(SQLHelper.ClsCN oCN, string tableName, string nameColumn, HashSet<int> ids)
        {
            if (ids == null || ids.Count == 0)
                return new Dictionary<int, string>();
            string idList = string.Join(",", ids);
            string query = $"select Hitemid, {nameColumn} from {tableName} with (nolock) where Hitemid in ({idList})";
            DataSet ds = oCN.RunProcReturn(query, tableName);
            var dict = new Dictionary<int, string>();
            if (ds != null && ds.Tables.Count > 0)
            {
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    int id = Convert.ToInt32(row["Hitemid"]);
                    string name = row[nameColumn].ToString();
                    dict[id] = name;
                }
            }
            return dict;
        }
        // 批量查询批次信息(调用金蝶接口)
        private Dictionary<int, string> BatchQueryBatchInfo(HashSet<int> batchIds)
        {
            var batchDict = new Dictionary<int, string>();
            if (batchIds == null || batchIds.Count == 0)
                return batchDict;
            // 如果需要并行查询,可以使用 Parallel.ForEach
            // 但注意:如果接口不支持高并发,可以改为顺序查询
            foreach (int batchId in batchIds)
            {
                try
                {
                    // 构建查询参数
                    var queryJson = $"{{\"Id\": {batchId}, \"IsSortBySeq\": \"false\"}}";
                    // 调用批次查询接口
                    string result = InvokeHelper.View("BD_BatchMainFile", queryJson);
                    // 解析返回的JSON
                    var jsonObj = JObject.Parse(result);
                    // 获取批次名称(从Name数组的第一个元素的Value)
                    var nameArray = jsonObj["Result"]?["Result"]?["Name"] as JArray;
                    if (nameArray != null && nameArray.Count > 0)
                    {
                        string batchName = nameArray[0]["Value"]?.ToString();
                        if (!string.IsNullOrEmpty(batchName))
                        {
                            batchDict[batchId] = batchName;
                        }
                        else
                        {
                            // 如果Name数组中没有值,尝试从Number字段获取
                            string number = jsonObj["Result"]?["Result"]?["Number"]?.ToString();
                            if (!string.IsNullOrEmpty(number))
                            {
                                batchDict[batchId] = number;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // 记录错误日志,但继续处理其他批次
                    Console.WriteLine($"查询批次信息失败,批次ID: {batchId}, 错误: {ex.Message}");
                    // 如果查询失败,可以将批次ID作为默认值
                    batchDict[batchId] = batchId.ToString();
                }
            }
            return batchDict;
        }
        //JSON字符串参数
        public static string BuildDynamicQueryJson(string materialNumber = null, long FHStockId=0, long HOWNERID = 0)
        {
            // 创建动态过滤条件列表
            var filterList = new List<object>();
            if (HOWNERID!= 100038)
            {
                // 如果有物料编码,添加物料条件
                if (!string.IsNullOrWhiteSpace(materialNumber))
                {
                    filterList.Add(new
                    {
                        Left = "",
                        FieldName = "FHMaterID.FNumber",
                        Compare = "67",  // 等于
                        Value = materialNumber,
                        Right = "",
                        Logic = filterList.Count > 0 ? 1 : 0  // 如果有多个条件,Logic=1表示OR
                    });
                }
                // 如果有仓库名称,添加仓库条件
                if (FHStockId != 0)
                {
                    filterList.Add(new
                    {
                        Left = "",
                        FieldName = "FHStockId",
                        Compare = "67",  // 包含
                        Value = FHStockId,
                        Right = "",
                        Logic = filterList.Count > 0 ? 1 : 0  // 如果有多个条件,Logic=1表示OR
                    });
                }
                // 如果有组织ID,添加组织条件
                if (HOWNERID != 0)
                {
                    filterList.Add(new
                    {
                        Left = "",
                        FieldName = "FStockOrgId",
                        Compare = "67",  // 包含
                        Value = HOWNERID,  // 保持之前的类型转换修复
                        Right = "",
                        Logic = filterList.Count > 0 ? 1 : 0  // 如果有多个条件,Logic=1表示OR
                    });
                }
                // 构建完整的查询参数
                var queryParams = new
                {
                    FormId = "STK_Inventory",
                    FieldKeys = "FMaterialId,FMaterialName,FModel,FStockUnitId,FBaseQty,FStockId,FStockLocId,FLot,FAuxPropId,FProduceDate,FExpiryDate,FStockOrgId",
                    FilterString = filterList
                };
                return JsonConvert.SerializeObject(queryParams);
            }
            else
            {
                //47 不支持上面的动态过滤条件 构建完整的查询参数
                var queryParams1 = new
                {
                    FormId = "STK_Inventory",
                    FieldKeys = "FMaterialId,FMaterialName,FModel,FStockUnitId,FBaseQty,FStockId,FStockLocId,FLot,FAuxPropId,FProduceDate,FExpiryDate,FStockOrgId",
                    FilterString = ""
                };
                return JsonConvert.SerializeObject(queryParams1);
            }
        }
        #endregion
        //刷新表体 车间定位  返回车间即时库存库存信息网页PDA版
        [Route("KF_ICInventory_WorkShopByMaterID/GetWorkShopICInventory")]
        [HttpGet]
        public object GetWorkShopICInventory(string HBarCode, long sHWHID, long sHSPID, long HOWNERID, string sWhere)
        {
            try
            {
                SQLHelper.ClsCN oCN = new SQLHelper.ClsCN();
                List<object> columnNameList = new List<object>();
                DataSet ds = oCN.RunProcReturn("exec h_p_KF_ICInventoryByMaterIDList1 '" + HBarCode + "'," + sHWHID + "," + sHSPID+","+ HOWNERID+",'"+ sWhere+"'", "h_p_KF_ICInventoryByMaterIDList");
                DataSet ds = oCN.RunProcReturn("exec h_p_KF_ICInventory_WorkShopByMaterIDList '" + HBarCode + "'," + sHWHID + "," + sHSPID + "," + HOWNERID + ",'" + sWhere + "'", "h_p_KF_ICInventory_WorkShopByMaterIDList");
                //添加列名
                foreach (DataColumn col in ds.Tables[0].Columns)
                {
@@ -1116,6 +1496,196 @@
            }
        }
        //车间定位  车间下架库存信息查询
        [Route("KF_ICInventory_WorkShop/GetWorkShopXJICInventory")]
        [HttpGet]
        public object GetWorkShopXJICInventory(string HCarBarCode, string HEquipBarCode, string HProcExBillNo,string HMaterNumber, long HWHID, long HSPID,string sWhere)
        {
            try
            {
                SQLHelper.ClsCN oCN = new SQLHelper.ClsCN();
                List<object> columnNameList = new List<object>();
                DataSet ds = oCN.RunProcReturn("exec h_p_KF_ICInventory_WorkShopByXJList '" + HCarBarCode + "','" + HEquipBarCode + "','" + HProcExBillNo + "','" + HMaterNumber + "'," + HWHID + "," + HSPID + ",'" + sWhere + "'", "h_p_KF_ICInventory_WorkShopByXJList");
                //添加列名
                foreach (DataColumn col in ds.Tables[0].Columns)
                {
                    Type dataType = col.DataType;
                    string ColmString = "{\"ColmCols\":\"" + col.ColumnName + "\",\"ColmType\":\"" + dataType.Name + "\"}";
                    columnNameList.Add(JsonConvert.DeserializeObject(ColmString));//获取到DataColumn列对象的列名
                }
                if (ds == null || ds.Tables[0].Rows.Count <= 0)
                {
                    objJsonResult.code = "0";
                    objJsonResult.count = 0;
                    objJsonResult.Message = "没有返回任何记录!";
                    objJsonResult.data = null;
                    return objJsonResult;
                }
                else
                {
                    objJsonResult.code = "1";
                    objJsonResult.count = 1;
                    objJsonResult.Message = "获取信息成功!";
                    objJsonResult.data = ds.Tables[0];
                    objJsonResult.list = columnNameList;
                    return objJsonResult;
                }
            }
            catch (Exception e)
            {
                objJsonResult.code = "0";
                objJsonResult.count = 0;
                objJsonResult.Message = "没有返回任何记录!" + e.ToString();
                objJsonResult.data = null;
                return objJsonResult;
            }
        }
        #region  车间定位 车间查询条码是否存在
        [Route("KF_ICInventory_WorkShop/SearchHBarCode")]
        [HttpGet]
        public object checkHBarCode_Batch(string HBarCode, string user, int HOrgID)
        {
            try
            {
                ds = oCN.RunProcReturn(@"select * from h_v_Gy_BarCodeBill WITH(NOLOCK) where HBarCode='" + HBarCode + "'", "h_v_Gy_BarCodeBill");
                //判断条码是否存在条码档案
                if (ds.Tables[0].Rows.Count > 0)
                {
                    objJsonResult.code = "1";
                    objJsonResult.count = 1;
                    objJsonResult.Message = "[0000-1-037]校验成功";
                    objJsonResult.data = ds.Tables[0];
                    return objJsonResult;
                }
                else
                {
                    objJsonResult.code = "0";
                    objJsonResult.count = 0;
                    objJsonResult.Message = "[0000-1-010]没有返回任何记录!当前批次码无入库信息请检查是否扫错";
                    objJsonResult.data = null;
                    return objJsonResult;
                }
            }
            catch (Exception e)
            {
                objJsonResult.code = "0";
                objJsonResult.count = 0;
                objJsonResult.Message = "[0000-1-010]没有返回任何记录!" + e.ToString();
                objJsonResult.data = null;
                return objJsonResult;
            }
        }
        #endregion
        #region  车间定位 删除条码库存记录
        [Route("KF_ICInventory_WorkShop/ClearHBarCode")]
        [HttpGet]
        public object ClearHBarCode(string HBarCode, long HWHID, long HSPID, string user, int HOrgID)
        {
            try
            {
                //保存后控制=========================================
                ds = oCN.RunProcReturn($"exec h_p_KF_MaterialUpper_Clear '{HBarCode}','{HWHID}',{HSPID},'{user}',{HOrgID}", "h_p_KF_ICInventory_Clear");
                //写入日志
                ClsPub.Add_Log("", "删除项目,物料代码:" + HBarCode + ",仓位id:" + HSPID, user);
                if (ds == null || ds.Tables[0].Rows.Count == 0)
                {
                    objJsonResult.code = "0";
                    objJsonResult.count = 0;
                    objJsonResult.Message = "删除失败!";
                    objJsonResult.data = null;
                    return objJsonResult;
                }
                if (DBUtility.ClsPub.isStrNull(ds.Tables[0].Rows[0]["HBack"]) != "0")
                {
                    objJsonResult.code = "0";
                    objJsonResult.count = 0;
                    objJsonResult.Message = "删除失败!" + DBUtility.ClsPub.isStrNull(ds.Tables[0].Rows[0]["HBackRemark"]);
                    objJsonResult.data = null;
                    return objJsonResult;
                }
                objJsonResult.code = "0";
                objJsonResult.count = 0;
                objJsonResult.Message = "删除成功!";
                objJsonResult.data = null;
                return objJsonResult;
            }
            catch (Exception e)
            {
                objJsonResult.code = "0";
                objJsonResult.count = 0;
                objJsonResult.Message = "[0000-1-010]没有返回任何记录!" + e.ToString();
                objJsonResult.data = null;
                return objJsonResult;
            }
        }
        #endregion
        //车间定位  车间上下架时间查询
        [Route("Kf_WorkShopICStockBill/List")]
        [HttpGet]
        public object Kf_WorkShopICStockBillList(string HBillType, string HCarBarCode, string HProcExBillNo, string HMaterNumber, long HWHID, long HSPID, string sWhere)
        {
            try
            {
                SQLHelper.ClsCN oCN = new SQLHelper.ClsCN();
                List<object> columnNameList = new List<object>();
                if(sWhere!=null)
                {
                    sWhere = sWhere.Replace("'", "''");
                }
                DataSet ds = oCN.RunProcReturn("exec h_p_KF_WorkShopICStockBillList '" + HBillType + "','" + HCarBarCode + "','" + HProcExBillNo + "','" + HMaterNumber + "'," + HWHID + "," + HSPID + ",'" + sWhere + "'", "h_p_KF_WorkShopICStockBillList");
                //添加列名
                foreach (DataColumn col in ds.Tables[0].Columns)
                {
                    Type dataType = col.DataType;
                    string ColmString = "{\"ColmCols\":\"" + col.ColumnName + "\",\"ColmType\":\"" + dataType.Name + "\"}";
                    columnNameList.Add(JsonConvert.DeserializeObject(ColmString));//获取到DataColumn列对象的列名
                }
                if (ds == null || ds.Tables[0].Rows.Count <= 0)
                {
                    objJsonResult.code = "0";
                    objJsonResult.count = 0;
                    objJsonResult.Message = "没有返回任何记录!";
                    objJsonResult.data = ds.Tables[0];
                    return objJsonResult;
                }
                else
                {
                    objJsonResult.code = "1";
                    objJsonResult.count = 1;
                    objJsonResult.Message = "获取信息成功!";
                    objJsonResult.data = ds.Tables[0];
                    objJsonResult.list = columnNameList;
                    return objJsonResult;
                }
            }
            catch (Exception e)
            {
                objJsonResult.code = "0";
                objJsonResult.count = 0;
                objJsonResult.Message = "没有返回任何记录!" + e.ToString();
                objJsonResult.data = null;
                return objJsonResult;
            }
        }
        [Route("MateOutBill/Delete_Json")]
        [HttpGet]
        public object Delete_Json(long HInterID, long HMaterID, long HAuxPropID, string HMTONo, long HSourceInterID, long HSourceEntryID, string sHBillType)