diff --git a/SGGL/BLL/CLGL/TwInOutplanmasterService.cs b/SGGL/BLL/CLGL/TwInOutplanmasterService.cs index c7a4032d..052dd234 100644 --- a/SGGL/BLL/CLGL/TwInOutplanmasterService.cs +++ b/SGGL/BLL/CLGL/TwInOutplanmasterService.cs @@ -6,6 +6,7 @@ using Model; using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.Linq; @@ -388,6 +389,272 @@ namespace BLL } + /// + /// 导入历史出库数据,直接生成出库申请单和出库单并扣减库存 + /// + public static ResponeData ImportOutHistoryData(string oriFileName, string path, string projectId, string createUserId, string unitWorkId) + { + var responeData = new ResponeData(); + if (string.IsNullOrEmpty(unitWorkId)) + { + responeData.code = 0; + responeData.message = "请选择单位工程!"; + return responeData; + } + + List importRows; + try + { + importRows = MiniExcel.Query(path, startCell: "A1").ToList(); + } + catch (Exception ex) + { + responeData.code = 0; + responeData.message = "模板错误:" + ex.Message; + return responeData; + } + + if (importRows == null || importRows.Count == 0) + { + responeData.code = 0; + responeData.message = "导入数据为空!"; + return responeData; + } + + var warehouseList = Base_WarehouseService.GetWarehouseList(projectId); + var allStock = TwMaterialstockService.GetTw_MaterialStockByModle(new Tw_MaterialStockOutput + { + ProjectId = projectId + }); + var errors = new List(); + var detailRows = new List(); + for (int i = 0; i < importRows.Count; i++) + { + var row = importRows[i]; + string rowWarehouseCode = CleanImportText(row.WarehouseCode); + string materialCode = CleanImportText(row.MaterialCode); + string heatNo = CleanImportText(row.HeatNo); + string batchNo = CleanImportText(row.BatchNo); + string numText = CleanImportText(row.Num); + string outputDateText = CleanImportDateText(row.OutputDate); + string reqUnitName = CleanImportText(row.ReqUnitName); + int rowIndex = i + 2; + + if (string.IsNullOrEmpty(rowWarehouseCode) && string.IsNullOrEmpty(materialCode) && string.IsNullOrEmpty(heatNo) && string.IsNullOrEmpty(batchNo) + && string.IsNullOrEmpty(numText) && string.IsNullOrEmpty(outputDateText) && string.IsNullOrEmpty(reqUnitName)) + { + continue; + } + + if (string.IsNullOrEmpty(rowWarehouseCode)) + { + errors.Add("第" + rowIndex + "行,仓库,此项为必填项!"); + continue; + } + if (!warehouseList.Any(x => x.WarehouseName == rowWarehouseCode)) + { + errors.Add("第" + rowIndex + "行,仓库[" + rowWarehouseCode + "]不存在!"); + continue; + } + if (string.IsNullOrEmpty(materialCode)) + { + errors.Add("第" + rowIndex + "行,材料编码,此项为必填项!"); + continue; + } + if (string.IsNullOrEmpty(heatNo)) + { + errors.Add("第" + rowIndex + "行,炉号,此项为必填项!"); + continue; + } + if (string.IsNullOrEmpty(batchNo)) + { + errors.Add("第" + rowIndex + "行,批号,此项为必填项!"); + continue; + } + + decimal num; + if (!decimal.TryParse(numText, out num) || num <= 0) + { + errors.Add("第" + rowIndex + "行,数量,请输入大于0的数字!"); + continue; + } + + DateTime outputDate; + if (!TryParseImportDate(outputDateText, out outputDate)) + { + errors.Add("第" + rowIndex + "行,出库时间,格式错误!"); + continue; + } + + var reqUnit = UnitService.getUnitByUnitName(reqUnitName); + if (reqUnit == null) + { + errors.Add("第" + rowIndex + "行,领用单位[" + reqUnitName + "]不存在!"); + continue; + } + + var stock = allStock.FirstOrDefault(x => x.WarehouseCode == rowWarehouseCode && x.Code == materialCode && x.HeatNo == heatNo && x.BatchNo == batchNo); + if (stock == null) + { + errors.Add("第" + rowIndex + "行,仓库[" + rowWarehouseCode + "]库存中不存在此材料编码/炉号/批号-" + materialCode + "/" + heatNo + "/" + batchNo); + continue; + } + + detailRows.Add(new Tw_OutHistoryImportRow + { + WarehouseCode = stock.WarehouseCode, + MaterialCode = stock.PipeLineMatCode, + Code = stock.Code, + HeatNo = stock.HeatNo, + BatchNo = stock.BatchNo, + MaterialUnit = stock.MaterialUnit, + Num = num, + OutputDate = outputDate, + ReqUnitId = reqUnit.UnitId + }); + } + + if (errors.Count > 0) + { + responeData.code = 0; + responeData.message = string.Join("|", errors.Distinct()); + return responeData; + } + if (detailRows.Count == 0) + { + responeData.code = 0; + responeData.message = "导入数据为空!"; + return responeData; + } + + var stockErrors = detailRows.GroupBy(x => new { x.WarehouseCode, x.MaterialCode }) + .Select(x => new + { + x.Key.WarehouseCode, + x.Key.MaterialCode, + Num = x.Sum(y => y.Num), + Stock = allStock.FirstOrDefault(y => y.WarehouseCode == x.Key.WarehouseCode && y.PipeLineMatCode == x.Key.MaterialCode) + }) + .Where(x => x.Stock == null || (x.Stock.StockNum ?? 0) < x.Num) + .Select(x => "仓库[" + x.WarehouseCode + "]" + (x.Stock == null ? x.MaterialCode : x.Stock.Code + "/" + x.Stock.HeatNo + "/" + x.Stock.BatchNo) + + "库存不足,库存:" + (x.Stock?.StockNum ?? 0) + ",导入数量:" + x.Num) + .ToList(); + if (stockErrors.Count > 0) + { + responeData.code = 0; + responeData.message = string.Join("|", stockErrors); + return responeData; + } + + int planCount = 0; + foreach (var group in detailRows.GroupBy(x => new + { + x.WarehouseCode, + x.ReqUnitId, + OutputDate = x.OutputDate.Date, + Category = IsPipeSectionUnit(x.MaterialUnit) ? (int)TwConst.Category.管段 : (int)TwConst.Category.管件 + })) + { + var planId = SQLHelper.GetNewID(); + string cusBillCode = GetDataInCusBillCode(projectId, UnitService.GetUnitCodeByUnitId(group.Key.ReqUnitId), TwConst.TypeInt.其他出库.ToString()); + var planMaster = new Tw_InOutPlanMaster + { + Id = planId, + ProjectId = projectId, + CusBillCode = cusBillCode, + WarehouseCode = group.Key.WarehouseCode, + WeldTaskId = unitWorkId, + Source = 2, + InOutType = (int)TwConst.InOutType.出库, + TypeInt = (int)TwConst.TypeInt.其他出库, + State = (int)TwConst.State.已审核, + Category = group.Key.Category, + CreateMan = createUserId, + CreateDate = group.Key.OutputDate, + ReqUnitId = group.Key.ReqUnitId, + AuditMan = createUserId, + AuditDate = group.Key.OutputDate, + AuditMan2 = createUserId, + AuditDate2 = group.Key.OutputDate, + WarehouseMan = createUserId, + WarehouseDate = group.Key.OutputDate, + Remark = oriFileName + }; + Add(planMaster); + + var outputDetails = new List(); + int sortIndex = 1; + foreach (var detailGroup in group.GroupBy(x => x.MaterialCode)) + { + decimal num = detailGroup.Sum(x => x.Num); + TwInOutplandetailService.Add(new Tw_InOutPlanDetail + { + Id = SQLHelper.GetNewID(), + InOutPlanMasterId = planId, + MaterialCode = detailGroup.Key, + PlanNum = num, + ActNum = num, + SortIndex = sortIndex + }); + outputDetails.Add(new Tw_OutputDetail + { + MaterialCode = detailGroup.Key, + PlanNum = num, + ActNum = num + }); + sortIndex++; + } + + TwOutputmasterService.GenOutMasterByPlanId(planId, outputDetails); + planCount++; + } + + responeData.code = 1; + responeData.message = "导入成功,生成出库申请单/出库单" + planCount + "张。"; + return responeData; + } + + private static bool IsPipeSectionUnit(string materialUnit) + { + return CleanImportText(materialUnit) == "米"; + } + + private static string CleanImportText(string value) + { + return Convert.ToString(value).Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", "").Trim(); + } + + private static string CleanImportDateText(string value) + { + return Convert.ToString(value).Replace("\n", "").Replace("\t", " ").Replace("\r", "").Trim(); + } + + private static bool TryParseImportDate(string value, out DateTime date) + { + date = default(DateTime); + if (string.IsNullOrEmpty(value)) + { + return false; + } + + double oaDate; + if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out oaDate) && oaDate > 0) + { + try + { + date = DateTime.FromOADate(oaDate); + return true; + } + catch + { + return false; + } + } + + return DateTime.TryParse(value, CultureInfo.GetCultureInfo("zh-CN"), DateTimeStyles.None, out date) + || DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out date); + } + public static Model.Tw_InOutPlanMaster GetById(string Id) { return Funs.DB.Tw_InOutPlanMaster.FirstOrDefault(x => x.Id == Id); diff --git a/SGGL/FineUIPro.Web/CLGL/OutPlanMaster.aspx b/SGGL/FineUIPro.Web/CLGL/OutPlanMaster.aspx index 6e34cb4e..2bebeded 100644 --- a/SGGL/FineUIPro.Web/CLGL/OutPlanMaster.aspx +++ b/SGGL/FineUIPro.Web/CLGL/OutPlanMaster.aspx @@ -86,6 +86,8 @@ +