using HH.Redis.ReisModel; using HH.WMS.BLL; using HH.WMS.BLL.Algorithm; using HH.WMS.BLL.Basic; using HH.WMS.BLL.OutStock; using HH.WMS.Common; using HH.WMS.Common.Algorithm; using HH.WMS.Common.Algorithm.Out; using HH.WMS.Entitys; using HH.WMS.Entitys.Basic; using HH.WMS.Entitys.Common; using HH.WMS.Entitys.Dto; using HH.WMS.WebApi.Areas.Common.Controllers; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace HH.WMS.WebApi.Areas.OutStock.Controllers { public class HKOutController : BaseController { #region 发货通知单主表-分页 /// /// 发货通知单主表-分页 /// /// /// [HttpPost] public string GetOutList(OutSearchDto param) { return ValidateToken(t => { long total; var data = BLLCreator.Create(t).GetOutList(param, out total); IsoDateTimeConverter timeFormat = new IsoDateTimeConverter(); timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss"; var or = OperateResult.Succeed(null, new { rows = data, total = total }); return JsonConvert.SerializeObject(or, timeFormat); }); } #endregion #region 新增编辑页面实体 /// /// 新增编辑页面实体 /// /// /// /// [HttpGet] public OperateResult GetOutEditEntity(string opNo, bool read = false) { return ValidateToken(t => { TN_WM_OUT_MSTEntity outMst = new TN_WM_OUT_MSTEntity(); if (string.IsNullOrEmpty(opNo)) { string postData = "{\"appCode\":\"AutoWMS\",\"ruleName\":\"" + Constants.Rule_Out + "\",\"orgId\":\"0\",\"orgFlag\":\"\"}"; string orderNo = WebApiManager.HttpAutoBom_Post("api/BillRule/GenBillNo", postData); outMst.CN_S_OP_NO = orderNo; outMst.CN_T_OP_DATE = DateTime.Now; outMst.CN_S_OPERATOR = t.CN_S_NAME; outMst.CN_S_CREATOR = t.CN_S_NAME; outMst.CN_S_CREATOR_BY = t.CN_S_LOGIN; outMst.CN_S_STATE = Constants.State_New; //新增 outMst.OperateType = OperateType.Add; } else { outMst = BLLCreator.Create(t).GetOutMstAndDtl(opNo); if (outMst == null) return OperateResult.Error("出库订单:" + opNo + "已被删除!"); //编辑 outMst.OperateType = OperateType.Edit; //查看 if (read) outMst.OperateType = OperateType.Read; outMst.CN_S_MODIFY = t.CN_S_NAME; outMst.CN_S_MODIFY_BY = t.CN_S_LOGIN; } return OperateResult.Succeed(null, outMst); }); } #endregion #region 出库单新增修改 /// /// 出库单新增修改 /// /// /// [HttpPost] public OperateResult OutEdit(PostEntity postEntity) { return ValidateToken(postEntity.TokenId, t => { var outMst = postEntity.GetPostData(); OperateResult result = new OperateResult(); //新增 if (outMst.OperateType == OperateType.Add) { outMst.CN_GUID = Guid.NewGuid().ToString(); outMst.CN_T_CREATE = DateTime.Now; outMst.CN_T_MODIFY = DateTime.Now; outMst.CN_C_INVOICE_PRINT = Constants.N; outMst.OutDtlList = outMst.OutDtlList.FindAll(f => !string.IsNullOrEmpty(f.CN_S_ITEM_NAME)); if (!outMst.OutDtlList.Any()) return OperateResult.Error("物料行不可为空"); int rowNo = 1; foreach (var outDtl in outMst.OutDtlList) { outDtl.CN_GUID = Guid.NewGuid().ToString(); outDtl.CN_N_ROW_NO = rowNo++; outDtl.CN_S_MSTGUID = outMst.CN_GUID; outDtl.CN_S_OP_NO = outMst.CN_S_OP_NO; outDtl.CN_S_STATE = outMst.CN_S_STATE; outDtl.CN_T_CREATE = DateTime.Now; outDtl.CN_S_CREATOR = outMst.CN_S_CREATOR; outDtl.CN_S_CREATOR_BY = outMst.CN_S_CREATOR_BY; } result = BLLCreator.Create(t).AddOut(outMst); } else { //修改 var existsOutMst = BLLCreator.Create>(t).GetSingleEntity(new { CN_S_OP_NO = outMst.CN_S_OP_NO }); if (existsOutMst == null) return OperateResult.Error("出库订单:" + outMst.CN_S_OP_NO + "已被删除,请刷新页面"); if (existsOutMst.CN_S_STATE != Constants.State_New && existsOutMst.CN_S_STATE != Constants.State_Reject) return OperateResult.Error("出库订单:" + outMst.CN_S_OP_NO + "的状态已被修改,请刷新页面"); existsOutMst.OutDtlList = BLLCreator.CreateDapper(t).GetList(new { CN_S_OP_NO = outMst.CN_S_OP_NO }); outMst.CN_GUID = existsOutMst.CN_GUID; outMst.CN_T_CREATE = existsOutMst.CN_T_CREATE; outMst.CN_S_CREATOR = existsOutMst.CN_S_CREATOR; outMst.CN_S_CREATOR_BY = existsOutMst.CN_S_CREATOR_BY; outMst.CN_T_MODIFY = DateTime.Now; outMst.CN_C_INVOICE_PRINT = existsOutMst.CN_C_INVOICE_PRINT; outMst.OutDtlList = outMst.OutDtlList.FindAll(f => !string.IsNullOrEmpty(f.CN_S_ITEM_NAME)); if (!outMst.OutDtlList.Any()) return OperateResult.Error("物料行不可为空"); int rowNo = 1; foreach (var outDtl in outMst.OutDtlList) { outDtl.CN_GUID = Guid.NewGuid().ToString(); outDtl.CN_N_ROW_NO = rowNo++; outDtl.CN_S_MSTGUID = outMst.CN_GUID; outDtl.CN_S_OP_NO = outMst.CN_S_OP_NO; outDtl.CN_S_STATE = outMst.CN_S_STATE; outDtl.CN_T_CREATE = DateTime.Now; outDtl.CN_S_CREATOR = outMst.CN_S_CREATOR; outDtl.CN_S_CREATOR_BY = outMst.CN_S_CREATOR_BY; outDtl.CN_T_MODIFY = DateTime.Now; outDtl.CN_S_MODIFY = outMst.CN_S_MODIFY; outDtl.CN_S_MODIFY_BY = outMst.CN_S_MODIFY_BY; } result = BLLCreator.Create(t).UpdateOut(outMst); } if (!result.Success) return result; if (outMst.OperateMessage == Constants.Operate_EditAndSubmit) { var or = SubmitOut(outMst.CN_S_OP_NO); if (!or.Success) { return OperateResult.Error("保存成功,提交失败:" + or.Msg); } } return result; }); } #endregion #region 获取物料可用量 /// /// 获取物料可用量 /// /// /// public OperateResult GetItemStockQty(string itemCode) { return ValidateToken(t => { var currentItemStock = BLLCreator.Create>().GetList(new { CN_S_ITEM_CODE = itemCode, }); string itemQtyTagFormat = "物料编码:{0}  可用量:{1}"; if (currentItemStock.Any()) { var _currentItem = currentItemStock.GroupBy(x => x.CN_S_ITEM_CODE) .Select(y => new { ItemCode = y.Key, Qty = y.Sum(z => z.CN_F_QUANTITY), AllocQty = y.Sum(z => z.CN_F_ALLOC_QTY), EditQty = y.Sum(z => z.CN_F_EDITING_QTY) }).ToList(); var _qty = _currentItem[0].Qty - _currentItem[0].AllocQty - _currentItem[0].EditQty; string itemQtyTagType = _qty <= 0 ? "danger" : "success"; return OperateResult.Succeed(null, new { ItemQtyTagType = itemQtyTagType, ItemQtyTag = string.Format(itemQtyTagFormat, itemCode, _qty) }); } return OperateResult.Succeed(null, new { ItemQtyTagType = "danger", ItemQtyTag = string.Format(itemQtyTagFormat, itemCode, 0) }); }); } #endregion #region 提交出库单 /// /// 提交出库单 /// /// /// [HttpGet] public OperateResult SubmitOut(string opNo) { return ValidateToken(t => { UserRuleEntity user = new UserRuleEntity() { LoginCode = Util.ToString(t.CN_S_LOGIN).Trim(), LoginName = Util.ToString(t.CN_S_NAME).Trim(), OrgCode = Util.ToString(t.CN_S_ORGCODE).Trim(), OrgFlag = Util.ToString(t.CN_S_ORGFLAG).Trim(), RuleCode = Constants.Rule_SortingNo }; var outMst = BLLCreator.Create(t).GetOutMstAndDtl(opNo); if (outMst == null) return OperateResult.Error("出库订单:" + opNo + "已被删除!"); if (outMst.CN_S_STATE != "新建") return OperateResult.Error("请选择新建状态的单据提交"); #region 调用OutArea算出库区 //初始化调用算法数据 List itemQuerys = outMst.OutDtlList.GroupBy(p => new { p.CN_S_ITEM_CODE, }) .Select(x => new itemQueryClass() { itemCode = x.Key.CN_S_ITEM_CODE, stockCode = outMst.CN_S_STOCK_CODE, itemQty = x.Sum(y => y.CN_F_QUANTITY) }).ToList(); var allArea = BLLCreator.Create().GetArea(4, outMst.CN_S_STOCK_CODE); List lstAreaPrior = allArea.Select(p => new areaPriorClass() { areaCode = p.CN_S_AREA_CODE, Prior = p.CN_N_PRIORITY }).ToList(); Log.Info("调用OutArea参数 itemQuerys", JsonConvert.SerializeObject(itemQuerys)); Log.Info("调用OutArea参数 lstAreaPrior", JsonConvert.SerializeObject(lstAreaPrior)); //调用出库算法 var algorResultEntity = BLLCreator.Create().OutArea(itemQuerys, lstAreaPrior); if (!algorResultEntity.Success) return OperateResult.Error("算法消息:" + algorResultEntity.Msg); Log.Info("调用OutArea返回值 algorResultEntity", JsonConvert.SerializeObject(algorResultEntity)); //算法结果 var algorResult = algorResultEntity.itemOutAreaResult; Log.Info("调用OutArea返回值 algorResult", JsonConvert.SerializeObject(algorResult)); if (algorResult == null || !algorResult.Any()) return OperateResult.Error("库存不足,请先完成来料区的上架"); #endregion #region 根据OutArea返回值创建分拣单主子表 //List sortingList = new List(); IEnumerable> igOutAreaResult = algorResult.GroupBy(x => new { x.stockCode, x.areaCode }); string sortingNo = user.GenerateNo(); if (string.IsNullOrEmpty(sortingNo)) return OperateResult.Error("生成分拣单失败"); TN_WM_SORTING_LISTEntity sortingEntity = new TN_WM_SORTING_LISTEntity() { CN_GUID = Guid.NewGuid().ToString(), CN_S_SORTING_NO = sortingNo, CN_S_OP_FROM = Constants.Rule_Out, CN_S_FROM_NO = outMst.CN_S_OP_NO, CN_T_OPERATE = DateTime.Now.ToString(), CN_S_STOCK_CODE = algorResult[0].stockCode, //CN_S_STOCK_AREA = _igOutAreaResult.Key.areaCode, CN_S_STATE = Constants.Sorting_Stay, CN_S_SEEDING_MODE = "", CN_S_GROUP = "", CN_S_CREATOR = user.LoginCode, CN_S_CREATOR_BY = user.LoginName, CN_T_CREATE = DateTime.Now, CN_S_MODIFY = user.LoginCode, CN_S_MODIFY_BY = user.LoginName, CN_T_MODIFY = DateTime.Now }; //分拣单子表 sortingEntity.SortingDtlList = new List(); //分拣明细 sortingEntity.SortingLocationList = new List(); //分拣单子表行索引 int sortingDtlindex = 1; foreach (var _igOutAreaResult in igOutAreaResult) { foreach (var outArea in _igOutAreaResult.AsEnumerable()) { foreach (var d in outArea.lstItem) { //物料详细 AutoBomItemEntity item = BLLCreator.Create().GetItem(d.itemCode) ?? new AutoBomItemEntity(); //分拣单子行 TN_WM_SORTING_DTLEntity sortingDtlEntity = new TN_WM_SORTING_DTLEntity() { CN_GUID = Guid.NewGuid().ToString(), CN_S_SORTING_NO = sortingEntity.CN_S_SORTING_NO, CN_N_ROW_NO = sortingDtlindex++, CN_F_QUANTITY = d.itemQty, CN_S_ITEM_CODE = d.itemCode, CN_S_ITEM_NAME = item.CN_S_ITEM_NAME, CN_S_STATE = Constants.Sorting_Stay, CN_S_LOT_NO = outArea.batchCode, CN_S_PRODUCTION_BATCH = outArea.prodBatchCode, CN_S_ITEM_STATE = outArea.itemState, CN_S_OWNER = outArea.ownerName, CN_S_MODEL = item.CN_S_MODEL, CN_S_FIGURE_NO = item.CN_S_FIGURE_NO, CN_S_MEASURE_UNIT = item.CN_S_MEASURE_UNIT, CN_S_AREA_CODE = outArea.areaCode }; sortingEntity.SortingDtlList.Add(sortingDtlEntity); } } } #endregion #region 根据生成的分拣单 调用OutNew 生成分拣明细 //初始化调用算法数据 List algorItems = sortingEntity.SortingDtlList.GroupBy(x => new { x.CN_S_ITEM_CODE, x.CN_S_AREA_CODE, }).Select(y => new itemQueryClass() { stockCode = sortingEntity.CN_S_STOCK_CODE, areaCode = y.Key.CN_S_AREA_CODE, itemCode = y.Key.CN_S_ITEM_CODE, itemQty = y.Sum(z => z.CN_F_QUANTITY) }).ToList(); lstAreaPrior = algorItems.Select(x => new areaPriorClass() { areaCode = x.areaCode, Prior = 1 }).ToList(); Log.Info("调用OutNew参数 algorItems", JsonConvert.SerializeObject(algorItems)); var outResult = BLLCreator.Create().OutNew(new OutAlgorEnitty() { lstDevice = new List(), lstAreaPrior = lstAreaPrior, lstQueryItem = algorItems, lockLocation = false }); Log.Info("调用OutNew返回值 outResult", JsonConvert.SerializeObject(outResult)); if (outResult.lstItemNotEnough.Any()) { outResult.lstItemNotEnough.ForEach(x => { var currentNotEnough = sortingEntity.SortingDtlList.Find(s => s.CN_S_ITEM_CODE.Equals(x.itemCode)); if (currentNotEnough != null) x.itemName = currentNotEnough.CN_S_ITEM_NAME; }); return OperateResult.Warning("物料:" + string.Join(";", outResult.lstItemNotEnough.Select(x => x.itemCode)) + "库存不足,请先完成来料区的上架", outResult.lstItemNotEnough); } if (!outResult.Success) return OperateResult.Error("OutNew算法消息:" + outResult.Msg); if (sortingEntity.SortingDtlList.Sum(x => x.CN_F_QUANTITY) != Convert.ToDecimal(outResult.itemLocations.Sum(x => x.itemQty))) { return OperateResult.Error("OutNew算法消息:返回的物料信息不完整!"); } var locations = outResult.itemLocations.Select(m => { AutoBomItemEntity mm = BLLCreator.Create().GetItem(m.itemCode) ?? new AutoBomItemEntity(); return new TN_WM_SORTING_LOCATIONEntity() { CN_GUID = Guid.NewGuid().ToString(), CN_S_LOT_NO = m.batchCode, CN_S_ITEM_STATE = m.itemState, CN_S_OWNER = m.ownerName, CN_F_QUANTITY = m.itemQty, CN_F_PICKED_QTY = 0, CN_S_ITEM_CODE = m.itemCode, CN_S_LOCATION_CODE = m.locationCode, CN_S_TRAY_CODE = m.trayCode, CN_S_TRAY_GRID = m.trayGrid, CN_S_SORTING_NO = sortingEntity.CN_S_SORTING_NO, CN_S_STATE = sortingEntity.CN_S_STATE, CN_S_ORDER_NO = "", CN_S_CREATOR = user.LoginCode, CN_S_CREATOR_BY = user.LoginName, CN_S_ITEM_NAME = mm.CN_S_ITEM_NAME, CN_S_MODEL = mm.CN_S_MODEL, CN_S_FIGURE_NO = mm.CN_S_FIGURE_NO, CN_S_MEASURE_UNIT = mm.CN_S_MEASURE_UNIT, CN_S_PACKING_UNIT = m.packUnit, CN_F_PACKING_QTY = m.packQty, CN_S_PRODUCTION_BATCH = m.prodBatchCode, CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_S_NEED_SORT = m.needSort, CN_S_AREA_CODE = m.areaCode }; }).ToList(); sortingEntity.SortingLocationList.AddRange(locations); #endregion return BLLCreator.Create(t).SubmitOut(outMst, sortingEntity); }); } #endregion #region 删除出库订单 /// /// 删除出库订单 /// /// /// [HttpGet] public OperateResult DeleteOut(string opNo) { return ValidateToken(t => { return BLLCreator.Create().DeleteOut(opNo); }); } #endregion #region 出库单子表 /// /// 出库单子表 /// /// /// public OperateResult GetOutDtl(string opNo) { return ValidateToken(t => { if (string.IsNullOrEmpty(opNo)) return OperateResult.Error("单据号不可为空"); var data = BLLCreator.CreateDapper().GetList(new { CN_S_OP_NO = opNo }); return OperateResult.Succeed(null, data); }); } #endregion } }