using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Estsh.Core.Base; using Estsh.Core.Wms.IRepositories; using Estsh.Core.Wms.IServices; using Estsh.Core.Model.Result; using Estsh.Core.Services; using Estsh.Core.Repositories; using Estsh.Core.Models; using Newtonsoft.Json.Linq; using static Estsh.Core.Model.EnumUtil.WmsEnumUtil; using Estsh.Core.Model.EnumUtil; namespace Estsh.Core.Wms.Services { public class MoveService : BaseService, IMoveService { private readonly IMoveRepository repository; public MoveService(IMoveRepository _repository) : base(_repository) { repository = _repository; } /// /// 执行移库 /// /// 用户名 /// public WmsResponseResult CheckMove(string loginId, string cartonNo, string locateName, string isPack) { //判断箱条码是否可用 SysStock cartonInfo = repository.CheckCartonNoStatus(cartonNo); WmsResponseResult result = new WmsResponseResult(); if (cartonInfo == null) { result.Success = false; result.Msg = "条码不存在:[" + cartonNo + "],请检查!"; return result; } if (cartonInfo.Enabled.Equals("N")) { result.Success = false; result.Msg = "[" + cartonNo + "]:箱条码已冻结,无法操作!"; return result; } if (cartonInfo.Status != (int)StockStatus.INSTOCKED) { result.Success = false; result.Msg = "[" + cartonNo + "]:该条码为" + cartonInfo.StockStatus + "状态,请检查!"; return result; } if (cartonInfo.CartonType == 1 && isPack == "True") { result.Success = false; result.Msg = "[" + cartonNo + "]:该条码为料架,无法使用组托!"; return result; } //获取库位表库位与绑定零件信息 List sysLocates = repository.CheckLocateStatus(locateName); if (sysLocates.Count == 0) { result.Success = false; result.Msg = "[" + locateName + "]:库位不存在,请检查!"; return result; } if (cartonInfo.ErpWarehouse != sysLocates[0].ErpWarehouse) { result.Success = false; result.Msg = "移库不允许跨库存地!"; return result; } if (sysLocates[0].LocateId == cartonInfo.LocateId) { result.Success = false; result.Msg = "[" + locateName + "]:来源库位与目标库位一致,请检查!"; return result; } List UseStocks = repository.CheckUseStockCapacity(locateName); //当前库位已经使用库存列表 decimal QtySum = UseStocks.Sum(a => a.Qty);//已经使用库存总量 if (isPack == "True") { if (cartonInfo.GroupNo == "" || cartonInfo.GroupNo == null) { result.Success = false; result.Msg = "[" + cartonNo + "]:组托号为空,无法使用组托!"; return result; } //组托入库 List stocksByPack = repository.CheckCartonNoStatusByPack(cartonNo); decimal QtySumByPack = stocksByPack.Sum(a => a.Qty);//组托入库所需库容 if (sysLocates[0].LocateCapacity > QtySum + QtySumByPack) { //有库容 //判断入库库位类型 是单零件 还是多零件 var getcount = stocksByPack.GroupBy(a => a.PartId).Select(b => (new SysStock { PartId = b.Key, Qty = b.Count() })); int PartCount = getcount.Count(); if (PartCount > 1) { if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.BASICS_LOCATE) { result.Success = false; result.Msg = "库位[" + locateName + "]类型无法满足操作,请更换为动态组合库!"; return result; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.MANEUVER_LOCATE) { result.Success = false; result.Msg = "库位[" + locateName + "]类型无法满足操作,请更换为动态组合库!"; return result; } //多种类,进动态组合库 (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE 30 if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE) { //动态组合库库位正确 ,有库容,正常入库 return repository.UpdateStockStatus(stocksByPack, sysLocates, (int)WmsEnumUtil.StockStatus.INSTOCKED, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } } else { //单种类,进基础库位 、 机动库位 (int)WmsEnumUtil.LocateType if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.BASICS_LOCATE) { if (sysLocates.Where(a => a.PartId == cartonInfo.PartId).Count() >= 0) { int Outstatus = (int)WmsEnumUtil.StockStatus.INSTOCKED; //基础库位正确 ,有库容,正常入库 return repository.UpdateStockStatus(stocksByPack, sysLocates, Outstatus, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } else { result.Success = false; result.Msg = "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; return result; } } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.LINE_LOCATE) { if (sysLocates.FirstOrDefault(a => a.PartId > 0) == null || sysLocates.Where(a => a.PartId == cartonInfo.PartId).Count() >= 0) { int Outstatus = (int)WmsEnumUtil.StockStatus.ONLINED; //线边库位,维护过零件则校验零件是否存在,未维护零件则不校验 return repository.UpdateStockStatus(stocksByPack, sysLocates, Outstatus, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } else { result.Success = false; result.Msg = "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; return result; } } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.MANEUVER_LOCATE) { //机动库位正确 ,有库容,正常入库 if (UseStocks.Where(a => a.PartId == cartonInfo.PartId).Count() >= 0) { //基础库位正确 ,有库容,正常入库 return repository.UpdateStockStatus(stocksByPack, sysLocates, (int)WmsEnumUtil.StockStatus.INSTOCKED, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } else { result.Success = false; result.Msg = "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; return result; } } //多种类,进动态组合库 (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE 30 if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE) { //动态组合库库位正确 ,有库容,正常入库 return repository.UpdateStockStatus(stocksByPack, sysLocates, (int)WmsEnumUtil.StockStatus.INSTOCKED, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } } result.Success = false; result.Msg = "[" + locateName + "]:库位类型不匹配,请检查!"; return result; } else { result.Success = false; result.Msg = "[" + locateName + "]:库位容量不足,请检查!"; return result; } } else { //单包装入库 SysStock sysStock = repository.CheckCartonNoStatus(cartonNo); if (sysLocates[0].LocateCapacity > QtySum + sysStock.Qty) { //有库容 if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.BASICS_LOCATE) { if (sysLocates.Where(a => a.PartId == cartonInfo.PartId).Count() > 0) { int Outstatus = (int)WmsEnumUtil.StockStatus.INSTOCKED; //基础库位正确 ,有库容,正常入库 List sysStocks = new List(); sysStocks.Add(sysStock); return repository.UpdateStockStatus(sysStocks, sysLocates, Outstatus, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } else { result.Success = false; result.Msg = "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; return result; } } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.LINE_LOCATE) { if (sysLocates.FirstOrDefault(a => a.PartId > 0) == null || sysLocates.Where(a => a.PartId == cartonInfo.PartId).Count() > 0) { int Outstatus = (int)WmsEnumUtil.StockStatus.ONLINED; //线边库位,维护过零件则校验零件是否存在,未维护零件则不校验 List sysStocks = new List(); sysStocks.Add(sysStock); return repository.UpdateStockStatus(sysStocks, sysLocates, Outstatus, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } else { result.Success = false; result.Msg = "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; return result; } } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.MANEUVER_LOCATE) { //机动库位正确 ,有库容,正常入库 if (UseStocks.Where(a => a.PartId == cartonInfo.PartId).Count() >= 0) { //基础库位正确 ,有库容,正常入库 List sysStocks = new List(); sysStocks.Add(sysStock); return repository.UpdateStockStatus(sysStocks, sysLocates, (int)WmsEnumUtil.StockStatus.INSTOCKED, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } else { result.Success = false; result.Msg = "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; return result; } } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE) { //动态组合库库位正确 ,有库容,正常入库 List sysStocks = new List(); sysStocks.Add(sysStock); return repository.UpdateStockStatus(sysStocks, sysLocates, (int)WmsEnumUtil.StockStatus.INSTOCKED, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.NC_LOCATE) { //动态组合库库位正确 ,有库容,正常入库 List sysStocks = new List(); sysStocks.Add(sysStock); return repository.UpdateStockStatus(sysStocks, sysLocates, (int)WmsEnumUtil.StockStatus.NC_INSTOCK, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId); } result.Success = false; result.Msg = "[" + locateName + "]:库位类型异常,请检查!"; return result; } else { result.Success = false; result.Msg = "[" + locateName + "]:库位容量不足,请检查!"; return result; } } } //判断库位 public string CheckLocateName(string loginId, string LocateName, string isPack) { List sysLocates = repository.CheckLocateStatus(LocateName); if (sysLocates.Count == 0) { return "[" + LocateName + "]:库位不存在,请检查!"; } List sysStocks = repository.CheckUseStockCapacity(LocateName); if (sysStocks.Count == 0) { return "OK"; } if (sysStocks[0].LocateNum > sysLocates[0].LocateCapacity) { return "[" + LocateName + "]:库位容量已满,请检查!"; } return "OK"; } //获取信息列表 public List GetMovePartInfo(string cartonNo, string isPack) { if (isPack == "True") { //组托移 return repository.GetCartonNoInfoByPack(cartonNo); } else { //单包装移 return repository.GetCartonNoInfo(cartonNo); } } /// /// 获取单据移动单列表 /// /// public List GetMoveOrderList() { return repository.GetMoveOrderList(); } /// /// 获取单据移动单列表 /// /// public List GetMoveOrderDetailList(string orderNo) { return repository.CheckMoveOrderLocate(orderNo); } /// /// 单据移动单 库位判断 /// /// /// /// /// public string CheckMoveOrderLocateName(string loginId, string LocateName, string orderNo) { List wmsMoveDetails = repository.CheckMoveOrderLocate(orderNo); if (wmsMoveDetails.Count == 0) { return "[" + orderNo + "]:订单明细不存在,请检查!"; } string dest_zone = wmsMoveDetails[0].DestZoneId.ToString(); List sysLocates = repository.CheckLocateStatus(LocateName); if (sysLocates.Count == 0) { return "[" + LocateName + "]:库位不存在,请检查!"; } ///大于1 ,说明移动单订单中设置了移动目的地库区,判断扫描的库位是否是指定库区 if (dest_zone.Length > 1) { if (sysLocates[0].ZoneId.ToString() == dest_zone) { //扫描库位在订单要求库区中 } else { return "[" + LocateName + "]:库位不在订单库区中,请检查!"; } } List sysStocks = repository.CheckUseStockCapacity(LocateName); if (sysStocks.Count == 0) { return "OK"; } if (sysStocks[0].LocateNum > sysLocates[0].LocateCapacity) { return "[" + LocateName + "]:库位容量已满,请检查!"; } return "OK"; } /// /// 单据移动单 箱条码判断 /// /// /// /// /// public string CheckCartonMoveOrder(string loginId, string cartonNo, string locateName, string orderNo) { //判断箱条码来源是否满足订单 List wmsMoveDetails = repository.CheckMoveOrderLocate(orderNo); if (wmsMoveDetails.Count == 0) { return "[" + orderNo + "]:订单明细不存在,请检查!"; } string scr_zone = wmsMoveDetails[0].SrcZoneId.ToString(); //判断箱条码是否可用 SysStock cartonInfo = repository.CheckCartonNoStatus(cartonNo); List ifnum = wmsMoveDetails.Where(a => a.PartId == cartonInfo.PartId).ToList(); decimal partno = 0; if (ifnum.Count > 0) { if (ifnum[0].Qty == ifnum[0].OutQty) { return "[" + cartonNo + "]:箱条码零件在订单中已完成操作,请检查!"; } } else { return "[" + cartonNo + "]:箱条码零件不在订单明细中,请检查!"; } if (scr_zone.Length > 1 && cartonInfo != null) { if (cartonInfo.ZoneId.ToString() != scr_zone) { return "[" + cartonNo + "]:箱条码不在订单要求来源的库区,请检查!"; } } if (cartonInfo == null) { return "[" + cartonNo + "]:条码不存在,请检查!"; } if (cartonInfo.Enabled.Equals("N")) { return "[" + cartonNo + "]:箱条码已冻结,无法操作!"; } //if (cartonInfo.Status != (int)StockStatus.INSTOCKED) //{ // return "[" + cartonNo + "]:该条码为" + cartonInfo.StockStatus + "状态,请检查!"; //} //获取库位表库位与绑定零件信息 List sysLocates = repository.CheckLocateStatus(locateName); if (sysLocates.Count == 0) { return "[" + locateName + "]:该库位不存在,请检查!"; } if (sysLocates[0].LocateId == cartonInfo.LocateId) { return "[" + locateName + "]:来源库位与目标库位一致,请检查!"; } int move_status = 50; if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.BASICS_LOCATE)//基础库 { move_status = (int)WmsEnumUtil.StockStatus.INSTOCKED; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.MANEUVER_LOCATE)//机动库位 { move_status = (int)WmsEnumUtil.StockStatus.INSTOCKED; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE)//动态组合库位 { move_status = (int)WmsEnumUtil.StockStatus.INSTOCKED; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.LINE_LOCATE)//线边库位 { move_status = (int)WmsEnumUtil.StockStatus.ONLINED; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.COLLECT_LOCATE)//收货库位 { move_status = (int)WmsEnumUtil.StockStatus.INSTOCKED; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.NC_LOCATE)//NC库位 { move_status = (int)WmsEnumUtil.StockStatus.NC_INSTOCK; } //if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.TRANSIT_LOCATE)//在途库位 //{ // move_status = 50; //} //if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.RETURN_LOCATE)//退货库位 //{ // move_status = 50; //} if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.OUTSOURCE_LOCATE)//委外库位 { move_status = (int)WmsEnumUtil.StockStatus.OUTSTOCKED; } if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.OFFLINEVIRTUAL_LOCATE)//成品下线虚拟库位 { move_status = (int)WmsEnumUtil.StockStatus.INSTOCKED; } List UseStocks = repository.CheckUseStockCapacity(locateName); //当前库位已经使用库存列表 decimal QtySum = UseStocks.Sum(a => a.Qty);//已经使用库存总量 SysStock sysStock = repository.CheckCartonNoStatus(cartonNo); if (sysLocates[0].LocateCapacity > QtySum + sysStock.Qty) { //有库容 //if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.BASICS_LOCATE) //{ // // TODO 此处需要重新写逻辑 // if (sysLocates.Where(a => a.PartId == cartonInfo.PartId).Count() > 0) // { // //基础库位正确 ,有库容,正常入库 // List sysStocks = new List(); // sysStocks.Add(sysStock); // return repository.UpdateStockStatusByMoveOrder(sysStocks, sysLocates, move_status, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId, orderNo); // } // { // return "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; // } //} //if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.MANEUVER_LOCATE) //{ // //机动库位正确 ,有库容,正常入库 // if (UseStocks.Where(a => a.PartId == cartonInfo.PartId).Count() >= 0) // { // //基础库位正确 ,有库容,正常入库 // List sysStocks = new List(); // sysStocks.Add(sysStock); // return repository.UpdateStockStatusByMoveOrder(sysStocks, sysLocates, move_status, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId, orderNo); // } // else // { // return "库位[" + locateName + "]与条码零件[" + cartonInfo.PartNo + "]不匹配!"; // } //} //if (sysLocates[0].LocateType == (int)WmsEnumUtil.LocateType.COMBINATION_LOCATE) //{ //动态组合库库位正确 ,有库容,正常入库 List sysStocks = new List(); sysStocks.Add(sysStock); return repository.UpdateStockStatusByMoveOrder(sysStocks, sysLocates, move_status, (int)WmsEnumUtil.TransType.MOVESTOCK, loginId, orderNo); //} } else { return "[" + locateName + "]:库位容量不足,请检查!"; } } public string ChangeMoveHeaderStatus(string loginId, string orderNo) { List wmsMoveDetails = repository.CheckMoveOrderLocate(orderNo); int statusSum = wmsMoveDetails.Sum(a => a.ItemStatus); if (wmsMoveDetails.Count * (int)WmsEnumUtil.MoveOrderStatus.COMPLETED == statusSum) { repository.ChangeMoveHeaderStatus(loginId, orderNo); } return "OK"; } } }