using HH.WMS.BLL; using HH.WMS.BLL.Algorithm; using HH.WMS.BLL.Basic; using HH.WMS.BLL.OutStock; using HH.WMS.BLL.SysMgr; 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.Entitys; 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; using HH.WMS.WebApi.Extension; using System.Data; using HH.WMS.Entitys.Algorithm; using HH.WMS.BLL.CoreServer; using HH.Redis.ReisModel; namespace HH.WMS.WebApi.Areas.OutStock.Controllers { public class OutController : BaseController { #region 出库单查询 /// /// 出库单查询 /// /// /// [HttpPost] public string GetOutList(SearchModel searchModel) { try { return ValidateToken(searchModel.TokenId, t => { IsoDateTimeConverter timeFormat = new IsoDateTimeConverter(); timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss"; List states = new List(); //状态初始化多个 逗号隔开 string state = Util.ToString(searchModel.SearchCondition.CN_S_STATE); if (!string.IsNullOrEmpty(state)) states = state.Split(',').ToList(); string waveNo = Util.ToString(searchModel.SearchCondition.CN_S_WAVE_CODE); OperateResult result = new OperateResult(); long total = 0; DataTable dt = new DataTable(); if (!string.IsNullOrEmpty(waveNo)) { if (searchModel.IsExport) dt = BLLCreator.Create>().GetDataTable(new { CN_S_WAVE_CODE = waveNo, }, " ORDER BY CN_T_MODIFY DESC, CN_T_CREATE DESC "); else dt = BLLCreator.Create>().GetPagingData(searchModel.PageIndex, searchModel.PageSize, out total, new { CN_S_WAVE_CODE = waveNo, }, " ORDER BY CN_T_MODIFY DESC, CN_T_CREATE DESC "); } else { if (searchModel.IsExport) dt = BLLCreator.Create>().GetData(new List() { new SearchWhere(){ key="CN_S_STOCK_CODE", sign = WhereSign.Eq, value=Util.ToString(searchModel.SearchCondition.CN_S_STOCK_CODE)}, new SearchWhere(){ key="CN_S_OP_NO", sign = WhereSign.Like,value=Util.ToString(searchModel.SearchCondition.CN_S_OP_NO)}, new SearchWhere(){ key="CN_S_STATE", sign = WhereSign.Include,value=states}, new SearchWhere(){ key="CN_S_CUSTOMER_NAME", sign = WhereSign.Like,value=Util.ToString(searchModel.SearchCondition.CN_S_CUSTOMER_NAME)}, new SearchWhere(){ key="CN_S_OP_TYPE", sign = WhereSign.Eq,value=Util.ToString(searchModel.SearchCondition.CN_S_OP_TYPE)}, new SearchWhere(){ key="CN_S_LOGISTICS_NAME", sign = WhereSign.Like,value=Util.ToString(searchModel.SearchCondition.CN_S_LOGISTICS_NAME)}, new SearchWhere(){ key="CN_T_CREATE", sign = WhereSign.TRange,value= new string[]{Util.ToString(searchModel.SearchCondition.CN_T_START),Util.ToString(searchModel.SearchCondition.CN_T_END)}} //new SearchWhere(){ key="CN_T_CREATE", sign = WhereSign.Lt,value=Util.ToString(searchModel.SearchCondition.CN_T_END)} }, true, new { CN_S_STOCK_CODE = Util.ToString(searchModel.SearchCondition.CN_S_STOCK_CODE), CN_S_OP_TYPE = Util.ToString(searchModel.SearchCondition.CN_S_OP_TYPE), CN_S_OP_NO = "%" + Util.ToString(searchModel.SearchCondition.CN_S_OP_NO) + "%", CN_S_STATE = states, CN_S_CUSTOMER_NAME = "%" + Util.ToString(searchModel.SearchCondition.CN_S_CUSTOMER_NAME) + "%", CN_S_LOGISTICS_NAME = "%" + Util.ToString(searchModel.SearchCondition.CN_S_LOGISTICS_NAME) + "%", START = Util.ToString(searchModel.SearchCondition.CN_T_START), END = Util.ToString(searchModel.SearchCondition.CN_T_END) }, " ORDER BY CN_T_MODIFY DESC, CN_T_CREATE DESC "); else dt = BLLCreator.Create>().GetPagingData(new List() { new SearchWhere(){ key="CN_S_STOCK_CODE", sign = WhereSign.Eq, value=Util.ToString(searchModel.SearchCondition.CN_S_STOCK_CODE)}, new SearchWhere(){ key="CN_S_OP_NO", sign = WhereSign.Like,value=Util.ToString(searchModel.SearchCondition.CN_S_OP_NO)}, new SearchWhere(){ key="CN_S_STATE", sign = WhereSign.Include,value=states}, new SearchWhere(){ key="CN_S_CUSTOMER_NAME", sign = WhereSign.Like,value=Util.ToString(searchModel.SearchCondition.CN_S_CUSTOMER_NAME)}, new SearchWhere(){ key="CN_S_OP_TYPE", sign = WhereSign.Eq,value=Util.ToString(searchModel.SearchCondition.CN_S_OP_TYPE)}, new SearchWhere(){ key="CN_S_LOGISTICS_NAME", sign = WhereSign.Like,value=Util.ToString(searchModel.SearchCondition.CN_S_LOGISTICS_NAME)}, new SearchWhere(){ key="CN_T_CREATE", sign = WhereSign.TRange,value= new string[]{Util.ToString(searchModel.SearchCondition.CN_T_START),Util.ToString(searchModel.SearchCondition.CN_T_END)}} //new SearchWhere(){ key="CN_T_CREATE", sign = WhereSign.Lt,value=Util.ToString(searchModel.SearchCondition.CN_T_END)} }, searchModel.PageIndex, searchModel.PageSize, out total, true, new { CN_S_STOCK_CODE = Util.ToString(searchModel.SearchCondition.CN_S_STOCK_CODE), CN_S_OP_TYPE = Util.ToString(searchModel.SearchCondition.CN_S_OP_TYPE), CN_S_OP_NO = "%" + Util.ToString(searchModel.SearchCondition.CN_S_OP_NO) + "%", CN_S_STATE = states, CN_S_CUSTOMER_NAME = "%" + Util.ToString(searchModel.SearchCondition.CN_S_CUSTOMER_NAME) + "%", CN_S_LOGISTICS_NAME = "%" + Util.ToString(searchModel.SearchCondition.CN_S_LOGISTICS_NAME) + "%", START = Util.ToString(searchModel.SearchCondition.CN_T_START), END = Util.ToString(searchModel.SearchCondition.CN_T_END) }, " ORDER BY CN_T_MODIFY DESC, CN_T_CREATE DESC "); } dt.Columns.Add("CN_S_STOCK_NAME"); //dt.Columns["CN_S_STOCK_CODE"].ReadOnly = false; foreach (DataRow dr in dt.Rows) { dr["CN_S_STOCK_NAME"] = (GetStock().Find(x => x.CN_S_STOCK_CODE.Equals(dr["CN_S_STOCK_CODE"].ToString().Trim())) ?? new TN_AB_STOCKEntity()).CN_S_STOCK_NAME; } return JsonConvert.SerializeObject(OperateResult.Succeed("", new { rows = dt, total = total }), timeFormat); }); } catch (Exception ex) { return JsonConvert.SerializeObject(OperateResult.Error(ex.Message)); } } #endregion #region 出库单新增修改 /// /// 出库单新增修改 /// /// /// [HttpPost] public OperateResult OutEdit(PostEntity postEntity) { return ValidateToken(postEntity.TokenId, t => { var outMst = postEntity.GetPostData(); var customer = BLLCreator.Create().GetSingleCustom(outMst.CN_S_CUSTOMER) ?? new TN_AB_CUSTOMEREntity(); OperateResult result = new OperateResult(); //新增 if (outMst.OperateType == OperateType.Add) { outMst.CN_GUID = Guid.NewGuid().ToString(); //货主不能为空,暂时赋值 outMst.CN_S_OWNER = string.IsNullOrEmpty(outMst.CN_S_OWNER) ? Constants.DefaultOwner : outMst.CN_S_OWNER; outMst.CN_T_CREATE = DateTime.Now; outMst.CN_T_MODIFY = DateTime.Now; //outMst.CN_S_RECEIVER_NAME = customer.CN_S_LEGAL_PERSON; //outMst.CN_S_PHONE = customer.CN_S_PHONE; //outMst.CN_S_PROVINCE = customer.CN_S_PROVINCE; //outMst.CN_S_CITY = customer.CN_S_CITY; //outMst.CN_S_AREA = customer.CN_S_AREA; //outMst.CN_S_TOWN = customer.CN_S_TOWN; //outMst.CN_S_DETAIL_ADDRESS = customer.CN_S_DELIVERY_DESTINATION; 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_S_ITEM_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().AddOut(outMst); } else { //修改 var existsOutMst = BLLCreator.Create>().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 + "的状态已被修改,请刷新页面"); 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_S_RECEIVER_NAME = customer.CN_S_LEGAL_PERSON; //outMst.CN_S_PHONE = customer.CN_S_PHONE; //outMst.CN_S_PROVINCE = customer.CN_S_PROVINCE; //outMst.CN_S_CITY = customer.CN_S_CITY; //outMst.CN_S_AREA = customer.CN_S_AREA; //outMst.CN_S_TOWN = customer.CN_S_TOWN; //outMst.CN_S_DETAIL_ADDRESS = customer.CN_S_DELIVERY_DESTINATION; //货主不能为空,暂时赋值 outMst.CN_S_OWNER = string.IsNullOrEmpty(outMst.CN_S_OWNER) ? Constants.DefaultOwner : outMst.CN_S_OWNER; 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_S_ITEM_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().UpdateOut(outMst); } if (outMst.OperateMessage == Constants.Operate_EditAndSubmit) return SubmitOut(outMst.CN_S_OP_NO, postEntity.TokenId); return result; }); } #endregion #region 获取出库单主子表 /// /// 获取出库单主子表 /// /// /// public OperateResult GetOutMstAndDtl(string opNo) { return ValidateToken(t => { var entity = BLLCreator.Create().GetOutMstAndDtl(opNo); return OperateResult.Succeed(null, entity); }); } #endregion #region 获取多个出库单主表 /// /// 获取多个出库单主表 /// /// /// public OperateResult GetOutMstRange(string opNos) { return ValidateToken(t => { List opNoList = opNos.Split(',').ToList(); var outMstList = BLLCreator.Create>().GetList(new { CN_S_OP_NO = opNoList }); return OperateResult.Succeed(null, outMstList); }); } #endregion #region 删除出库订单 /// /// 删除出库订单 /// /// /// [HttpGet] public OperateResult DeleteOut(string opNo, string tokenId) { return ValidateToken(tokenId, t => { return BLLCreator.Create().DeleteOut(opNo); }); } #endregion #region 带出出库订单,批分,仓库实体 /// /// 带出出库订单实体 /// /// /// /// public OperateResult ChangeOutOperate(string opNo, Func, List, List, OperateResult> funcOut) { try { if (string.IsNullOrEmpty(opNo)) return OperateResult.Error("出库订单号不可为空"); var outMst = BLLCreator.Create>().GetSingleEntity(new { CN_S_OP_NO = opNo }); if (outMst == null) return OperateResult.Error("未找到出库订单号:" + opNo); var outDtl = BLLCreator.Create>().GetList(new { CN_S_OP_NO = outMst.CN_S_OP_NO, CN_C_AUTO_INOUT = false }).ToList(); outMst.OutDtlList = outDtl; var batchesList = outDtl.Select(p => new BatchesEntity() { ItemCode = p.CN_S_ITEM_CODE, ItemState = p.CN_S_ITEM_STATE, ItemArrivalLot = p.CN_S_LOT_CODE, ItemProductionLot = p.CN_S_PRODUCTION_BATCH, Owner = outMst.CN_S_OWNER, Qty = p.CN_F_QUANTITY, StockCode = outMst.CN_S_STOCK_CODE, AreaCode = outMst.CN_S_AREA, OpNo = outMst.CN_S_OP_NO, OutMst = outMst, IsFilter = p.CN_C_AUTO_INOUT }).ToList(); //当前子表物料库存 var stockList = BLLCreator.Create>().GetList(new { CN_S_ITEM_CODE = batchesList.Select(p => p.ItemCode).ToList() }); //算法策略 List lstStrate = BLLCreator.Create().GetStrateListByAreaOrStock("", "", Constants.Out) .OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList(); return funcOut(outMst, batchesList, stockList, lstStrate); } catch (Exception ex) { return OperateResult.Error(ex.Message); } } #endregion #region 获取出库订单所有客户 /// /// 获取出库订单所有客户 /// /// [HttpGet] public OperateResult GetDistinctCustom() { return ValidateToken(t => { var list = BLLCreator.Create().GetDistinctCustom(); return OperateResult.Succeed(null, list); }); } #endregion #region 出库订单子表数据 /// /// 出库订单子表数据 /// /// /// [HttpGet] public OperateResult GetOutDtl(string opNo) { return ValidateToken(t => { var outDtl = BLLCreator.Create>().GetList(new { CN_S_OP_NO = opNo, CN_C_AUTO_INOUT = false }); return OperateResult.Succeed(null, outDtl); }); } #endregion #region 提交 /// /// 提交 /// /// /// [HttpGet] public OperateResult SubmitOut(string opNo, string tId = "") { string tokenId = !string.IsNullOrEmpty(tId) ? tId : Requests.QueryString["tokenId"]; return ValidateToken(tokenId, t => { return ChangeOutOperate(opNo, (outMst, batchesList, stockList, lstStrate) => { if (outMst.CN_S_STATE != Constants.State_New && outMst.CN_S_STATE != Constants.State_Reject) { return OperateResult.Error("该单据状态已被修改,请刷新页面"); } var notCheckStock = GetStrategy(outMst.CN_S_STOCK_CODE, StrategyKey.NotCheckStock); if (notCheckStock != Constants.Y) { //正批分编辑量 var batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ForwardBatch, StockBatchesField.EditingQty, lstStrate); if (!batchResult.Success) return batchResult; } else { stockList = new List(); } return BLLCreator.Create().SubmitOut(opNo, stockList, t); }); }); } #endregion #region 驳回 /// /// 驳回 /// /// /// [HttpPost] public OperateResult Reject(PostEntity postEntity) { return ValidateToken(postEntity.TokenId, t => { TN_WM_B_REJECTEntity rejectEntity = postEntity.GetPostData(); if (rejectEntity == null) return OperateResult.Error("参数不正确"); return ChangeOutOperate(rejectEntity.CN_S_FROM_NO, (outMst, batchesList, stockList, lstStrate) => { if (string.IsNullOrEmpty(rejectEntity.CN_S_OPINION)) return OperateResult.Error("驳回意见不可为空"); //驳回时状态必须为 已提交、已反审 if (outMst.CN_S_STATE != Constants.State_Submit && outMst.CN_S_STATE != Constants.State_ReAudit) { return OperateResult.Error("该单据状态已被修改,请刷新页面"); } //驳回实体 rejectEntity.CN_GUID = Guid.NewGuid().ToString(); rejectEntity.CN_S_OP_FROM = Constants.Rule_OutOrder; rejectEntity.CN_T_CREATE = DateTime.Now; rejectEntity.CN_T_MODIFY = DateTime.Now; var notCheckStock = GetStrategy(outMst.CN_S_STOCK_CODE, StrategyKey.NotCheckStock); if (notCheckStock != Constants.Y) { //反批分编辑量 var batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ReverseBatch, StockBatchesField.EditingQty, lstStrate); if (!batchResult.Success) return batchResult; } else { stockList = new List(); } return BLLCreator.Create().OutReject(rejectEntity, stockList, t); }); }); } #endregion #region 反审 /// /// 反审 /// /// /// [HttpGet] public OperateResult ReAuditOut(string opNo) { return ValidateToken(t => { return ChangeOutOperate(opNo, (outMst, batchesList, stockList, lstStrate) => { //反审时状态必须为 已审核 if (outMst.CN_S_STATE != Constants.State_Audit) { return OperateResult.Error("该单据状态已被修改,请刷新页面"); } var notCheckStock = GetStrategy(outMst.CN_S_STOCK_CODE, StrategyKey.NotCheckStock); if (notCheckStock != Constants.Y) { //反批分分配量 var batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ReverseBatch, StockBatchesField.AllocationQty, lstStrate); if (!batchResult.Success) return batchResult; //正批分编辑量 batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ForwardBatch, StockBatchesField.EditingQty, lstStrate); if (!batchResult.Success) return batchResult; } else { stockList = new List(); } return BLLCreator.Create().ReAuditOut(opNo, stockList, t); }); }); } #endregion #region 审核 /// /// 审核 /// /// /// [HttpGet] public OperateResult AuditOut(string opNo) { return ValidateToken(t => { return ChangeOutOperate(opNo, (outMst, batchesList, stockList, lstStrate) => { if (outMst.CN_S_STATE != Constants.State_Submit && outMst.CN_S_STATE != Constants.State_ReAudit) { return OperateResult.Error("该单据状态已被修改,请刷新页面"); } var notCheckStock = GetStrategy(outMst.CN_S_STOCK_CODE, StrategyKey.NotCheckStock); if (notCheckStock != Constants.Y) { //反批分编辑量 var batchEditResult = stockList.BatchesStockQty(batchesList, BatchesType.ReverseBatch, StockBatchesField.EditingQty, lstStrate); if (!batchEditResult.Success) return batchEditResult; if (outMst.CN_S_OP_TYPE.Equals(Constants.OutOpType_WxXs) || outMst.CN_S_OP_TYPE.Equals(Constants.OutOpType_WxXh)) { //初始化调用算法数据 List itemQuerys = outMst.OutDtlList.GroupBy(p => new { p.CN_S_ITEM_CODE, p.CN_S_ITEM_STATE, p.CN_S_LOT_CODE, p.CN_S_PRODUCTION_BATCH }) .Select(x => new itemQueryClass() { itemCode = x.Key.CN_S_ITEM_CODE, batchCode = x.Key.CN_S_LOT_CODE, itemState = x.Key.CN_S_ITEM_STATE, ownerName = outMst.CN_S_OWNER, 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("消耗出库调用出库算法参数 itemQuerys", JsonConvert.SerializeObject(itemQuerys)); Log.Info("消耗出库调用出库算法参数 lstAreaPrior", JsonConvert.SerializeObject(lstAreaPrior)); //调用出库算法 var algorResultEntity = BLLCreator.Create().OutArea(itemQuerys, lstAreaPrior); Log.Info("消耗出库调用出库算法结果 algorResultEntity", JsonConvert.SerializeObject(algorResultEntity)); if (!algorResultEntity.Success) return OperateResult.Error("算法异常:" + algorResultEntity.Msg); //算法结果 var algorResult = algorResultEntity.itemOutAreaResult; Log.Info("消耗出库调用出库算法结果 algorResult", JsonConvert.SerializeObject(algorResult)); if (algorResult == null) return OperateResult.Error("库存不足,请先完成来料区的上架"); var stockAreaList = BLLCreator.Create>().GetList(new { CN_S_STOCK_AREA = algorResult.Select(x => x.areaCode).ToList() }); #region 垃圾代码,后续优化 //初始化调用算法数据(暂缺少生产批次) List algorItems = new List(); foreach (var a in algorResult) { foreach (var m in a.lstItem) { algorItems.Add(new itemQueryClass() { stockCode = a.stockCode, areaCode = a.areaCode, itemCode = m.itemCode, batchCode = a.batchCode, itemState = a.itemState, itemQty = m.itemQty }); } } var lstAreaLocationPrior = algorItems.Select(x => new areaPriorClass() { areaCode = x.areaCode, Prior = 1 }).ToList(); Log.Info("消耗出库调用出库算法OutNew algorItems", JsonConvert.SerializeObject(algorItems)); Log.Info("消耗出库调用出库算法OutNew lstAreaPrior", JsonConvert.SerializeObject(lstAreaPrior)); 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()) { return OperateResult.Warning("物料:" + string.Join(";", outResult.lstItemNotEnough.Select(x => x.itemCode)) + "库存不足,请先完成来料区的上架"); } if (!outResult.Success) return OperateResult.Error("算法异常:" + outResult.Msg); //if(outResult.itemLocations.Sum(x=>x.itemQty)!=) List batchesTrayItemList = new List(); batchesTrayItemList = outResult.itemLocations.Select(m => new BatchesEntity() { TrayCode = m.trayCode, ItemCode = m.itemCode, ItemState = m.itemState, ItemArrivalLot = m.batchCode, ItemProductionLot = m.prodBatchCode, Qty = m.itemQty, Owner = m.ownerName }).ToList(); var trayItemMstList = batchesTrayItemList.BatchesDropTrayItemQty(false); #endregion var trayLocations = BLLCreator.Create>().GetList(new { CN_S_TRAY_CODE = trayItemMstList.Select(x => x.CN_S_TRAY_CODE).ToList() }); //正批分分配量(直接降库存) var batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ForwardBatch, StockBatchesField.AllocationQty, lstStrate, true, true); if (!batchResult.Success) return batchResult; var batchesResultData = batchResult.GetData(); if (batchesResultData == null) return OperateResult.Error("生成出库数据异常"); //批分库区 (直接降库存) var batchesAreaResult = stockAreaList.BatchesAreaQty(algorResult, lstStrate); if (!batchesAreaResult.Success) return batchesAreaResult; //batchResult return BLLCreator.Create().AuditOut(opNo, stockList, stockAreaList, t, outMst, trayItemMstList, trayLocations, batchesResultData.ReduceInventoryMstList); } else { //正批分分配量 var batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ForwardBatch, StockBatchesField.AllocationQty, lstStrate); if (!batchResult.Success) return batchResult; return BLLCreator.Create().AuditOut(opNo, stockList, null, t, outMst); } } else { //不校验库存时,判断单据中是否存在大件,有大件 大件拆单 stockList = new List(); if (outMst.CN_S_OUT_TYPE != Constants.OutType_BigOut) { outMst.OutDtlList.ForEach(a => { //物料详细 AutoBomItemEntity item = BLLCreator.Create().GetItemEntity(a.CN_S_ITEM_CODE); if (item == null) throw new Exception("autobom中未找到物料:" + a.CN_S_ITEM_CODE); if (item.CN_S_STORE_TYPE == Constants.BigArea) a.CN_C_BIG = true; }); //当前单据所有大件 var bigDtlList = outMst.OutDtlList.FindAll(f => f.CN_C_BIG); //非大件 var otherDtlList = outMst.OutDtlList.FindAll(f => !f.CN_C_BIG); if (bigDtlList.Any()) { outMst.BigOutMst = GenerateNewOut(outMst, bigDtlList, t, Constants.OutType_BigOut); if (otherDtlList.Any()) outMst.OtherOutMst = GenerateNewOut(outMst, otherDtlList, t, ""); } } return BLLCreator.Create().AuditOut(opNo, stockList, null, t, outMst); } }); }); } #endregion #region 拆单审核时生成新的单据 /// /// 拆单生成新的单据 /// /// /// /// /// /// private TN_WM_OUT_MSTEntity GenerateNewOut(TN_WM_OUT_MSTEntity oldOutEntity, List dtlList, RedisUserEntity user, string outType) { TN_WM_OUT_MSTEntity newOutMst = oldOutEntity.Clone() as TN_WM_OUT_MSTEntity; newOutMst.CN_GUID = Guid.NewGuid().ToString(); string postData = "{\"appCode\":\"" + Constants.appCode + "\",\"ruleName\":\"" + Constants.Rule_OutOrder + "\",\"orgId\":\"0\",\"orgFlag\":\"\"}"; string orderNo = WebApiManager.HttpAutoBom_Post("api/BillRule/GenBillNo", postData); newOutMst.CN_S_OP_NO = orderNo; newOutMst.CN_S_STATE = Constants.State_Audit; dtlList.ForEach(e => { e.CN_GUID = Guid.NewGuid().ToString(); e.CN_S_OP_NO = orderNo; e.CN_S_ITEM_STATE = newOutMst.CN_S_STATE; e.CN_S_MSTGUID = newOutMst.CN_GUID; }); newOutMst.CN_S_SPLIT_FROM = oldOutEntity.CN_S_OP_NO; newOutMst.CN_S_OUT_TYPE = outType; newOutMst.CN_S_AUDITOR = user.CN_S_NAME; newOutMst.CN_T_AUDIT_TIME = DateTime.Now; newOutMst.CN_S_MODIFY = user.CN_S_NAME; newOutMst.CN_S_MODIFY_BY = user.CN_S_LOGIN; newOutMst.CN_T_MODIFY = DateTime.Now; newOutMst.OutDtlList = dtlList; return newOutMst; } #endregion #region 合单 /// /// 合单 /// /// /// public OperateResult MergeOrder(PostEntity postEntity) { return ValidateToken(postEntity.TokenId, t => { List outList = postEntity.GetPostData>(); if (outList == null || !outList.Any()) return OperateResult.Error("参数不正确"); var groupOutList = outList.GroupBy(p => new { p.CN_S_OP_TYPE, p.CN_S_CUSTOMER, p.CN_S_STOCK_CODE, p.CN_S_FORWARDING_WAY, p.CN_S_STATE, p.CN_S_OWNER }); if (groupOutList.Count() != 1) return OperateResult.Warning("所选单据不允许合单"); string state = outList[0].CN_S_STATE; if (state != Constants.State_Submit) { return OperateResult.Error("只允许合并已提交单据!"); } //合单单据的子表数据 var outDtlList = BLLCreator.Create>().GetList(new { CN_S_OP_NO = outList.Select(p => p.CN_S_OP_NO).ToList() }); TN_WM_OUT_MSTEntity newOutMst = new TN_WM_OUT_MSTEntity(); newOutMst.CN_S_OP_TYPE = outList[0].CN_S_OP_TYPE; newOutMst.CN_S_CUSTOMER = outList[0].CN_S_CUSTOMER; newOutMst.CN_S_CUSTOMER_NAME = outList[0].CN_S_CUSTOMER_NAME; newOutMst.CN_S_STOCK_CODE = outList[0].CN_S_STOCK_CODE; newOutMst.CN_T_OP_DATE = DateTime.Now; newOutMst.CN_S_SALES_STYLE = outList[0].CN_S_SALES_STYLE; newOutMst.CN_S_FORWARDING_WAY = outList[0].CN_S_FORWARDING_WAY; newOutMst.CN_S_STATE = outList[0].CN_S_STATE; newOutMst.CN_S_OWNER = string.IsNullOrEmpty(outList[0].CN_S_OWNER) ? Constants.DefaultOwner : outList[0].CN_S_OWNER; //string.IsNullOrEmpty(outMst.CN_S_OWNER) ? Constants.DefaultOwner : outMst.CN_S_OWNER; newOutMst.CN_S_RECEIVER_NAME = outList[0].CN_S_RECEIVER_NAME; newOutMst.CN_S_PHONE = outList[0].CN_S_PHONE; newOutMst.CN_S_DETAIL_ADDRESS = outList[0].CN_S_DETAIL_ADDRESS; newOutMst.CN_S_NOTE = string.Join(";", outList.Where(w => !string.IsNullOrEmpty(w.CN_S_NOTE)).Select(x => x.CN_S_NOTE)); //生成一个新的单据 UserRuleEntity user = new UserRuleEntity() { OrgCode = "0", RuleCode = Constants.Rule_OutOrder }; string orderNo = user.GenerateNo(); newOutMst.CN_GUID = Guid.NewGuid().ToString(); newOutMst.CN_S_OP_NO = orderNo; newOutMst.CN_T_OP_DATE = DateTime.Now; newOutMst.CN_T_CREATE = DateTime.Now; newOutMst.CN_S_CREATOR = t.CN_S_LOGIN; newOutMst.CN_S_CREATOR_BY = t.CN_S_NAME; newOutMst.CN_T_MODIFY = DateTime.Now; newOutMst.CN_S_MODIFY = t.CN_S_LOGIN; newOutMst.CN_S_MODIFY_BY = t.CN_S_NAME; newOutMst.CN_S_OPERATOR = t.CN_S_NAME; newOutMst.CN_S_MERGE_SPLIT = Constants.MergeSplit_Merge; outList.ForEach(p => { p.CN_S_STATE = Constants.State_Cancel; p.CN_S_PARENT_NO = newOutMst.CN_S_OP_NO; }); int index = 1; //根据【物料编码、物料名称、物料状态、规格型号、图号、计量单位】分组 生成合单新单据的子表数据 var newOutDtlList = outDtlList.GroupBy(p => new { p.CN_S_ITEM_CODE, p.CN_S_ITEM_NAME, p.CN_S_ITEM_STATE, p.CN_S_MODEL, p.CN_S_FIGURE_NO, p.CN_S_MEASURE_UNIT, p.CN_C_AUTO_INOUT }) .Select(x => new TN_WM_OUT_DTLEntity() { CN_GUID = Guid.NewGuid().ToString(), CN_N_ROW_NO = index++, CN_S_MSTGUID = newOutMst.CN_GUID, CN_S_OP_NO = newOutMst.CN_S_OP_NO, CN_S_ITEM_CODE = x.Key.CN_S_ITEM_CODE, CN_S_ITEM_NAME = x.Key.CN_S_ITEM_NAME, CN_S_ITEM_STATE = x.Key.CN_S_ITEM_STATE, CN_S_MODEL = x.Key.CN_S_MODEL, CN_S_FIGURE_NO = x.Key.CN_S_FIGURE_NO, CN_S_MEASURE_UNIT = x.Key.CN_S_MEASURE_UNIT, CN_C_AUTO_INOUT = x.Key.CN_C_AUTO_INOUT, CN_T_CREATE = DateTime.Now, CN_S_CREATOR = newOutMst.CN_S_CREATOR, CN_S_CREATOR_BY = newOutMst.CN_S_CREATOR_BY, CN_T_MODIFY = DateTime.Now, CN_S_MODIFY = newOutMst.CN_S_MODIFY, CN_S_MODIFY_BY = newOutMst.CN_S_MODIFY_BY, CN_F_QUANTITY = x.Sum(y => y.CN_F_QUANTITY), CN_S_NOTE = string.Join(";", x.Select(y => y.CN_S_NOTE)) }).ToList(); newOutMst.OutDtlList = newOutDtlList; //合单 return BLLCreator.Create().MergeOrder(newOutMst, outList, t); }); } #endregion #region U8服务调用-新增出库单主子表 /// /// U8服务调用-新增出库单主子表 /// /// 出库单主子表集合 /// [HttpPost] public string AddU8OutData(List mstList) { OperateResult or = BLLCreator.Create().AddU8OutData(mstList); return JsonConvert.SerializeObject(or); } /// /// 发货确认时,提取数据反写U8系统 /// /// /// [HttpGet] public string GetOutU8Data(string opNo) { var outMst = BLLCreator.Create>().GetSingleEntity(new { CN_S_FROM_NO = opNo }); var outDtl = BLLCreator.Create>().GetList(new { CN_S_OP_NO = outMst.CN_S_OP_NO }); outMst.OutDtlList = outDtl; return JsonConvert.SerializeObject(OperateResult.Succeed("", outMst)); } #endregion #region 查询出库订单 /// /// 查询出库订单 /// /// 出库订单号 /// public OperateResult GetEntity(string opNo) { return ValidateToken(t => { TN_WM_OUT_MSTEntity entity = BLLCreator.Create>().GetSingleEntity(new { CN_S_OP_NO = opNo }); if (entity != null) return OperateResult.Succeed("", entity); else return OperateResult.Error("无当前单号的出库订单!"); }); } #endregion #region 获取物料可用量 /// /// 获取物料可用量 /// /// /// public OperateResult GetItemStockQty(string owner, string itemCode, string itemState) { return ValidateToken(t => { var currentItemStock = BLLCreator.Create>().GetList(new { CN_S_ITEM_CODE = itemCode, CN_S_ITEM_STATE = itemState, CN_S_OWNER = owner }); 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 根据包装箱编码查询数据 /// /// 根据包装箱编码查询数据 /// /// /// [HanHe(LT)] CREATED 2019/1/8 [HttpGet] public OperateResult GetOutPack(string pack) { return ValidateToken(t => { var list = BLLCreator.Create().GetOutPack(" where CN_S_PACKING_CODE='" + pack + "'"); return OperateResult.Succeed(null, list); }); } /// /// 根据包装箱编码查询数据 /// /// /// [HanHe(LT)] CREATED 2019/1/8 [HttpGet] public OperateResult GetBoxdtl(string pack) { return ValidateToken(t => { var list = BLLCreator.Create().GetBoxdtl(" AND CN_S_PACKING_CODE='" + pack + "'"); return OperateResult.Succeed(null, list); }); } #endregion #region 取消 /// /// 取消 /// /// /// [HttpGet] public OperateResult CancelOut(string opNo) { return ValidateToken(t => { return ChangeOutOperate(opNo, (outMst, batchesList, stockList, lstStrate) => { if (outMst.CN_S_STATE == Constants.State_Completed) return OperateResult.Error("该单据已完成,不允许取消"); var notCheckStock = GetStrategy(outMst.CN_S_STOCK_CODE, StrategyKey.NotCheckStock); //需要根据状态降库存 if (notCheckStock != Constants.Y) { if (outMst.CN_S_STATE == Constants.State_Submit) { //反批分编辑量 var batchEditResult = stockList.BatchesStockQty(batchesList, BatchesType.ReverseBatch, StockBatchesField.EditingQty, lstStrate); if (!batchEditResult.Success) return batchEditResult; } else if (outMst.CN_S_STATE == Constants.State_Audit) { //反批分分配量 var batchResult = stockList.BatchesStockQty(batchesList, BatchesType.ReverseBatch, StockBatchesField.AllocationQty, lstStrate); if (!batchResult.Success) return batchResult; } else { stockList = new List(); } } else { stockList = new List(); } return BLLCreator.Create().CancelOut(outMst, stockList, t); }); }); } #endregion } }