using HH.WMS.BLL;
using HH.WMS.BLL.Algorithm;
using HH.WMS.BLL.Basic;
using HH.WMS.BLL.Common;
using HH.WMS.BLL.CoreServer;
using HH.WMS.BLL.MoveStock;
using HH.WMS.BLL.OutStock;
using HH.WMS.Common;
using HH.WMS.Common.Algorithm;
using HH.WMS.Entitys;
using HH.WMS.Entitys.Ams;
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.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace HH.WMS.WebApi.Areas.OutStock.Controllers
{
public class SortingController : BaseController
{
#region (PDA)获取的分拣单
///
/// (PDA)获取的分拣单
///
///
[HttpGet]
public OperateResult GetCurrentSorting(string tokenId, string sortingNo = "")
{
return ValidateToken(tokenId, t =>
{
TN_WM_SORTING_LISTEntity sortingEntity = new TN_WM_SORTING_LISTEntity();
sortingEntity.SortingLocationList = new List();
if (!string.IsNullOrEmpty(sortingNo))
{
sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingEntity == null)
return OperateResult.Error("未找到分拣单:" + sortingNo);
}
else
{
sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_STATE = Constants.Sorting_Being
});
if (sortingEntity == null)
{
sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_STATE = new List() { Constants.Sorting_Stay, Constants.Sorting_Being }
}, " ORDER BY CN_T_CREATE");
if (sortingEntity == null)
{
return OperateResult.Error("");
}
}
}
var sortingLocation = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingEntity.CN_S_SORTING_NO
});
sortingLocation = sortingLocation.GroupBy(x => new { x.CN_S_LOCATION_CODE, x.CN_S_TRAY_CODE })
.Select(y => new TN_WM_SORTING_LOCATIONEntity
{
CN_S_TRAY_CODE = y.Key.CN_S_TRAY_CODE,
CN_S_LOCATION_CODE = y.Key.CN_S_LOCATION_CODE,
CN_F_QUANTITY = y.Sum(z => z.CN_F_QUANTITY)
}).ToList();
var sortingResult = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingEntity.CN_S_SORTING_NO
});
var result = new
{
SortingNo = sortingEntity.CN_S_SORTING_NO,
AreaCode = sortingEntity.CN_S_STOCK_AREA,
SortingState = sortingEntity.CN_S_STATE,
LocationItems = sortingLocation.Select(x => new
{
TrayCode = x.CN_S_TRAY_CODE,
LocationCode = x.CN_S_LOCATION_CODE,
PickNum = x.CN_F_QUANTITY,
PickedNum = sortingResult.Where(y => y.CN_S_LOCATION_CODE.Equals(x.CN_S_LOCATION_CODE)).Sum(z => z.CN_F_QUANTITY),
PickState = sortingResult.Where(y => y.CN_S_LOCATION_CODE.Equals(x.CN_S_LOCATION_CODE)).Sum(z => z.CN_F_QUANTITY) == x.CN_F_QUANTITY ? "已拣" : "未拣"//暂时赋值
}).Where(m => m.PickState != "已拣")
};
return OperateResult.Succeed(null, result);
});
}
#endregion
#region (PDA)分拣单列表
///
/// (PDA)分拣单列表
///
///
///
[HttpGet]
public OperateResult GetSortings(string tokenId, string key = "", string isBig = "")
{
return ValidateToken(tokenId, t =>
{
var allAreas = GetStockArea();
var filterArea = isBig == Constants.Y ?
allAreas.FindAll(f => f.CN_C_IS_AUTO != Constants.Y && f.CN_S_AREA_CLASS != Constants.BigArea) :
allAreas.FindAll(f => f.CN_S_AREA_CLASS == Constants.BigArea);
var sortingList = BLLCreator.CreateDapper().GetList(new
{
CN_S_STATE = new List { Constants.Sorting_Stay, Constants.Sorting_Being },
CN_S_SORTING_NO = Util.ToLike(key),
CN_S_STOCK_AREA = filterArea.Select(s => s.CN_S_AREA_CODE).ToList()
});
return OperateResult.Succeed(null,
sortingList.Select(x => new
{
SortingNo = x.CN_S_SORTING_NO,
AreaCode = (allAreas.Find(f => f.CN_S_AREA_CODE.Equals(x.CN_S_STOCK_AREA)) ?? new AutoBomStockAreaEntity()).CN_S_AREA_NAME,
CreateTime = x.CN_T_CREATE.ToString(),
FromNo = x.CN_S_FROM_NO,
SortingState = x.CN_S_STATE
}));
});
}
#endregion
#region (PDA杭叉)分拣指引
///
/// (PDA杭叉)分拣指引
///
///
///
[HttpGet]
public OperateResult SortingGuide(string sortingNo)
{
return ValidateToken(t =>
{
var sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingEntity == null)
return OperateResult.Error("未找到分拣单:" + sortingNo);
var trayItem = new List();
//待分拣时生成分拣明细
if (sortingEntity.CN_S_STATE == Constants.Sorting_Stay)
{
#region 生成分拣明细
//调用算法获取分拣明细,分拣明细改到执行分拣单的时候生成
var sortingLocationResult = BLLCreator.Create().GetSortingLocation(sortingEntity,
new UserRuleEntity()
{
LoginCode = t.CN_S_LOGIN,
LoginName = t.CN_S_NAME
});
if (!sortingLocationResult.Success)
return sortingLocationResult;
var sortingLocations = sortingLocationResult.GetData>();
sortingEntity.SortingLocationList.AddRange(sortingLocations);
#endregion
#region 生成托盘分配量
//批分托盘物料分配量,改到执行分拣单的时候分配
//组织批分实体
var batchesTrayItem = sortingLocations.Select(x => new BatchesEntity()
{
TrayCode = x.CN_S_TRAY_CODE,
ItemCode = x.CN_S_ITEM_CODE,
Qty = x.CN_F_QUANTITY
}).ToList();
trayItem = BLLCreator.Create>().GetList(new
{
CN_S_ITEM_CODE = batchesTrayItem.Select(x => x.ItemCode).ToList()
});
var or = trayItem.BatchesTrayItemQty(batchesTrayItem, BatchesType.ForwardBatch);
if (!or.Success) return or;
#endregion
#region 执行分拣单
//执行分拣单
or = BLLCreator.Create().ExecuteSorting(sortingEntity, trayItem);
if (!or.Success) return or;
#endregion
}
var currentSortingLocation = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
var result = currentSortingLocation
.Where(w => w.CN_F_QUANTITY > w.CN_F_PICKED_QTY)
.Select(s => new
{
TrayCode = s.CN_S_TRAY_CODE,
Location = s.CN_S_LOCATION_CODE,
Qty = s.CN_F_QUANTITY,
PickedQty = s.CN_F_PICKED_QTY
});
return OperateResult.Succeed(null, result);
});
}
#endregion
#region (PDA杭叉)先拣后播页面数据
///
/// (PDA杭叉)先拣后播页面数据
///
///
///
///
[HttpGet]
public OperateResult GetPickData(string sortingNo, string location)
{
return ValidateToken(t =>
{
if (string.IsNullOrEmpty(sortingNo) || string.IsNullOrEmpty(location))
return OperateResult.Error("分拣单号或货位号不可为空");
var sortingLocations = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
var result = sortingLocations
.Where(w => w.CN_S_LOCATION_CODE == location)
.Select(s => new
{
ItemName = s.CN_S_ITEM_NAME,
ItemCode = s.CN_S_ITEM_CODE,
ItemState = s.CN_S_ITEM_STATE,
ItemLotNo = s.CN_S_LOT_NO,
ItemProLotNo = s.CN_S_PRODUCTION_BATCH,
ItemModel = s.CN_S_MODEL,
ItemFigureNo = s.CN_S_FIGURE_NO,
ItemUnit = s.CN_S_MEASURE_UNIT,
TrayGrid = s.CN_S_TRAY_GRID,
Owner = s.CN_S_OWNER,
PickNum = s.CN_F_QUANTITY,
PickedNum = s.CN_F_PICKED_QTY
});
return OperateResult.Succeed(null, result);
});
}
#endregion
#region (PDA)执行分拣单
///
/// (PDA)执行分拣单
///
///
///
[HttpGet]
public OperateResult ExecuteSorting(string tokenId, string sortingNo, string area = "")
{
return ValidateToken(tokenId, t =>
{
var sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingEntity == null)
return OperateResult.Error("未找到分拣单:" + sortingNo);
if (sortingEntity.CN_S_STATE != Constants.Sorting_Stay)
return OperateResult.Error("当前分拣单不是待分拣,请重新选择");
var trayItem = new List();
if (sortingEntity.CN_S_OP_FROM != Constants.MoveOrder)
{
#region 自动库需要生成出库任务
//生成任务
List endAreas = new List();
var outTaskResult = BLLCreator.Create(t).GetOutTask(ref sortingEntity, ref endAreas, area);
if (!outTaskResult.Success)
{
return outTaskResult;
}
#endregion
}
var result = BLLCreator.Create().ExecuteSorting(sortingEntity, trayItem);
if (!result.Success)
return result;
string isUseAms = GetStrategy(sortingEntity.CN_S_STOCK_CODE,
StrategyKey.IsUseAms);
if (isUseAms == Constants.Y)
{
//return WebApiManager.("api/BillRule/GenBillNo", postData);
var sortingLocation = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
var amsAddTaskList = new List();
amsAddTaskList = sortingLocation.GroupBy(p => p.CN_S_LOCATION_CODE).Select(x => new AmsAddTask
{
businessType = "拣货",
sysName = "WMS",
deviceName = "WMS",
locationFrom = x.Key,
locationTo = "SYS",
priority = 0
}).ToList();
if (amsAddTaskList.Any())
{
Log.Info("ExecuteSorting 调用ams AddTask 发送亮灯指令参数 分拣单:" + sortingNo, JsonConvert.SerializeObject(amsAddTaskList));
string amsResult = WebApiManager.HttpAms_Post("api/HHAms/AddTask", JsonConvert.SerializeObject(amsAddTaskList));
Log.Info("ExecuteSorting 调用ams AddTask 返回值:", amsResult);
}
}
return result;
});
}
#endregion
#region (PDA)获取分拣货位明细
///
/// (PDA)获取分拣货位明细
///
///
///
///
[HttpGet]
public OperateResult GetSortingLocation(string tokenId, string sortingNo, string locationCode)
{
return ValidateToken(tokenId, t =>
{
Log.Info("GetSortingLocation tokenId", tokenId);
Log.Info("GetSortingLocation sortingNo", sortingNo);
Log.Info("GetSortingLocation locationCode", locationCode);
var sortingLocations = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo,
CN_S_LOCATION_CODE = locationCode
});
Log.Info("sortingLocations sortingLocations", JsonConvert.SerializeObject(sortingLocations));
sortingLocations = sortingLocations.GroupBy(x => new
{
x.CN_S_ITEM_CODE,
x.CN_S_ITEM_NAME,
x.CN_S_ITEM_STATE,
x.CN_S_LOT_NO,
x.CN_S_TRAY_CODE,
x.CN_S_TRAY_GRID,
x.CN_S_PRODUCTION_BATCH,
x.CN_S_MODEL,
x.CN_S_FIGURE_NO,
x.CN_S_MEASURE_UNIT,
x.CN_S_OWNER,
x.CN_S_LOCATION_CODE
}).Select(y => new TN_WM_SORTING_LOCATIONEntity()
{
CN_S_ITEM_CODE = y.Key.CN_S_ITEM_CODE,
CN_S_ITEM_NAME = y.Key.CN_S_ITEM_NAME,
CN_S_ITEM_STATE = y.Key.CN_S_ITEM_STATE,
CN_S_LOT_NO = y.Key.CN_S_LOT_NO,
CN_S_TRAY_CODE = y.Key.CN_S_TRAY_CODE,
CN_S_TRAY_GRID = y.Key.CN_S_TRAY_GRID,
CN_S_PRODUCTION_BATCH = y.Key.CN_S_PRODUCTION_BATCH,
CN_S_MODEL = y.Key.CN_S_MODEL,
CN_S_FIGURE_NO = y.Key.CN_S_FIGURE_NO,
CN_S_MEASURE_UNIT = y.Key.CN_S_MEASURE_UNIT,
CN_S_OWNER = y.Key.CN_S_OWNER,
CN_S_LOCATION_CODE = y.Key.CN_S_LOCATION_CODE,
CN_F_QUANTITY = y.Sum(z => z.CN_F_QUANTITY)
}).ToList();
var sortingResult = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
Log.Info("sortingLocations sortingResult", JsonConvert.SerializeObject(sortingResult));
//CN_C_IS_SN
List items = (BLLCreator.Create().GetItemList(sortingLocations.Select(x => x.CN_S_ITEM_CODE).ToList()) ?? new List());
var result = new
{
LocationCode = locationCode,
TrayCode = sortingLocations[0].CN_S_TRAY_CODE,
PickItems = sortingLocations.Select(x =>
{
var currentItem = items.Find(m => m.CN_S_ITEM_CODE.Equals(x.CN_S_ITEM_CODE)) ?? new AutoBomItemEntity();
decimal PackNum = 0;
//包装数量为0取最小包装数,最小包装数为0取1
if (x.CN_F_PACKING_QTY == 0)
{
x.CN_F_PACKING_QTY = currentItem.CN_F_MIN_PACK_QTY;
if (x.CN_F_PACKING_QTY == 0)
x.CN_F_PACKING_QTY = 1;
}
else
{
if (x.CN_F_PACKING_QTY > 1)
{
PackNum = x.CN_F_QUANTITY / x.CN_F_PACKING_QTY.Value;
}
}
return new
{
ItemName = x.CN_S_ITEM_NAME,
ItemCode = x.CN_S_ITEM_CODE,
ItemState = x.CN_S_ITEM_STATE,
ItemLotNo = x.CN_S_LOT_NO,
ItemProLotNo = x.CN_S_PRODUCTION_BATCH,
ItemModel = x.CN_S_MODEL,
TrayGrid = x.CN_S_TRAY_GRID,
ItemFigureNo = x.CN_S_FIGURE_NO,
ItemUnit = x.CN_S_MEASURE_UNIT,
PackUnit = x.CN_S_PACKING_UNIT,
PackQty = x.CN_F_PACKING_QTY,
Owner = x.CN_S_OWNER,
PickNum = x.CN_F_QUANTITY,
IsSn = string.IsNullOrEmpty(currentItem.CN_C_IS_SN) ? "N" : currentItem.CN_C_IS_SN,
PickedNum = sortingResult.FindAll(s =>
{
s.CN_S_LOT_NO = s.CN_S_LOT_NO ?? "";
s.CN_S_PRODUCTION_BATCH = s.CN_S_PRODUCTION_BATCH ?? "";
x.CN_S_LOT_NO = x.CN_S_LOT_NO ?? "";
x.CN_S_PRODUCTION_BATCH = x.CN_S_PRODUCTION_BATCH ?? "";
return s.CN_S_ITEM_CODE.Equals(x.CN_S_ITEM_CODE) &&
s.CN_S_ITEM_STATE.Equals(x.CN_S_ITEM_STATE) &&
s.CN_S_OWNER.Equals(x.CN_S_OWNER) &&
(!string.IsNullOrEmpty(s.CN_S_PRODUCTION_BATCH) || s.CN_S_PRODUCTION_BATCH.Equals(x.CN_S_PRODUCTION_BATCH)) &&
s.CN_S_LOCATION_CODE.Equals(x.CN_S_LOCATION_CODE);
}).Sum(q => q.CN_F_QUANTITY)
};
})
};
Log.Info("sortingLocations result", JsonConvert.SerializeObject(result));
return OperateResult.Succeed(null, result);
});
}
#endregion
#region (PDA三生)获取分拣货位明细
///
///(PDA三生)获取分拣货位明细
///
///
///
///
///
public OperateResult GetSortingLocations(string tokenId, string sortingNo, string locationCode)
{
return ValidateToken(tokenId, t =>
{
Log.Info("GetSortingLocations tokenId", tokenId);
Log.Info("GetSortingLocations sortingNo", sortingNo);
Log.Info("GetSortingLocations locationCode", locationCode);
var sortingLocations = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo,
CN_S_LOCATION_CODE = locationCode
});
Log.Info("sortingLocations sortingLocations", JsonConvert.SerializeObject(sortingLocations));
var sortingResult = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
Log.Info("sortingLocations sortingResult", JsonConvert.SerializeObject(sortingResult));
sortingLocations = sortingLocations.GroupBy(x =>
{
if (x.CN_F_PACKING_QTY > x.CN_F_QUANTITY)
{
x.CN_F_PACKING_QTY = 1;
x.CN_S_PACKING_UNIT = "";
}
return new
{
x.CN_S_ITEM_CODE,
x.CN_S_ITEM_NAME,
x.CN_S_ITEM_STATE,
x.CN_S_TRAY_CODE,
x.CN_S_TRAY_GRID,
x.CN_S_PRODUCTION_BATCH,
x.CN_S_MODEL,
x.CN_S_MEASURE_UNIT,
x.CN_S_OWNER,
x.CN_S_LOCATION_CODE,
x.CN_S_PACKING_UNIT,
x.CN_F_PACKING_QTY
};
}).Select(y =>
{
var currentItemLocationPicked = sortingResult.FindAll(s =>
{
s.CN_S_PRODUCTION_BATCH = s.CN_S_PRODUCTION_BATCH ?? "";
s.CN_S_PACKING_UNIT = s.CN_S_PACKING_UNIT ?? "";
return s.CN_S_ITEM_CODE.Equals(y.Key.CN_S_ITEM_CODE) &&
s.CN_S_ITEM_STATE.Equals(y.Key.CN_S_ITEM_STATE) &&
s.CN_S_OWNER.Equals(y.Key.CN_S_OWNER) &&
(string.IsNullOrEmpty(s.CN_S_PRODUCTION_BATCH) || s.CN_S_PRODUCTION_BATCH == y.Key.CN_S_PRODUCTION_BATCH) &&
s.CN_S_LOCATION_CODE.Equals(y.Key.CN_S_LOCATION_CODE) &&
s.CN_S_PACKING_UNIT == y.Key.CN_S_PACKING_UNIT;
}).Sum(q => q.CN_F_QUANTITY);
bool isMinUnit = false;
isMinUnit = (string.IsNullOrEmpty(y.Key.CN_S_PACKING_UNIT)) || (y.Key.CN_F_PACKING_QTY <= 1);
return new TN_WM_SORTING_LOCATIONEntity()
{
CN_S_ITEM_CODE = y.Key.CN_S_ITEM_CODE,
CN_S_ITEM_NAME = y.Key.CN_S_ITEM_NAME,
CN_S_ITEM_STATE = y.Key.CN_S_ITEM_STATE,
CN_S_TRAY_CODE = y.Key.CN_S_TRAY_CODE,
CN_S_TRAY_GRID = y.Key.CN_S_TRAY_GRID,
CN_S_PRODUCTION_BATCH = y.Key.CN_S_PRODUCTION_BATCH,
CN_S_MODEL = y.Key.CN_S_MODEL,
CN_S_MEASURE_UNIT = y.Key.CN_S_MEASURE_UNIT,
CN_S_OWNER = y.Key.CN_S_OWNER,
CN_S_LOCATION_CODE = y.Key.CN_S_LOCATION_CODE,
CN_S_PACKING_UNIT = y.Key.CN_S_PACKING_UNIT,
CN_F_PACKING_QTY = y.Key.CN_F_PACKING_QTY,
CN_F_QUANTITY = y.Sum(z => z.CN_F_QUANTITY) - currentItemLocationPicked,
IsMinUnit = isMinUnit
};
}).Where(m => m.CN_F_QUANTITY > 0).ToList();
List items = (BLLCreator.Create().GetItemList(sortingLocations.Select(x => x.CN_S_ITEM_CODE).ToList()) ?? new List());
var results = sortingLocations.GroupBy(x => new
{
x.CN_S_ITEM_CODE,
x.CN_S_ITEM_NAME,
x.CN_S_ITEM_STATE,
x.CN_S_PRODUCTION_BATCH,
x.CN_S_MODEL,
x.CN_S_OWNER
}).Select(y =>
{
var currentItem = items.Find(m => m.CN_S_ITEM_CODE.Equals(y.Key.CN_S_ITEM_CODE)) ?? new AutoBomItemEntity();
var currentItems = sortingLocations.Where(m => m.CN_S_ITEM_CODE.Equals(y.Key.CN_S_ITEM_CODE) &&
m.CN_S_ITEM_STATE.Equals(y.Key.CN_S_ITEM_STATE) &&
m.CN_S_OWNER.Equals(y.Key.CN_S_OWNER) &&
m.CN_S_PRODUCTION_BATCH == y.Key.CN_S_PRODUCTION_BATCH).ToList();
//不属于最小包装单位的数据
var currentItemPack = currentItems.Where(o => !o.IsMinUnit).GroupBy(n => new
{
n.CN_S_PACKING_UNIT,
n.CN_F_PACKING_QTY,
n.CN_S_MEASURE_UNIT,
}).Select(m => new TN_WM_SORTING_LOCATIONEntity
{
CN_S_PACKING_UNIT = m.Key.CN_S_PACKING_UNIT,
CN_F_PACKING_QTY = m.Key.CN_F_PACKING_QTY,
CN_S_MEASURE_UNIT = m.Key.CN_S_MEASURE_UNIT,
CN_F_QUANTITY = m.Sum(k => k.CN_F_QUANTITY)
}).ToList();
//最小包装单位的数据
currentItemPack.AddRange(currentItems.Where(o => o.IsMinUnit).GroupBy(n => new
{
n.CN_S_MEASURE_UNIT
}).Select(m => new TN_WM_SORTING_LOCATIONEntity
{
CN_S_MEASURE_UNIT = m.Key.CN_S_MEASURE_UNIT,
CN_F_QUANTITY = m.Sum(k => k.CN_F_QUANTITY)
}).ToList());
string packUnit = string.Empty;
decimal numOfPack = 1;
foreach (var _currentItemPack in currentItemPack)
{
if (string.IsNullOrEmpty(_currentItemPack.CN_S_PACKING_UNIT) || _currentItemPack.CN_F_PACKING_QTY <= 1)
{
if (_currentItemPack.CN_F_PACKING_QTY < 1)
_currentItemPack.CN_F_PACKING_QTY = currentItem.CN_F_MIN_PACK_QTY;
if (_currentItemPack.CN_F_PACKING_QTY < 1)
_currentItemPack.CN_F_PACKING_QTY = 1;
_currentItemPack.WaitPickDetail = _currentItemPack.CN_F_QUANTITY + _currentItemPack.CN_S_MEASURE_UNIT;
TN_WM_B_UNIQUE_BARCODEEntity uniqueBig = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_ITEM_CODE = _currentItemPack.CN_S_ITEM_CODE,
CN_S_PARENT_CODE = ""
});
if (uniqueBig != null)
{
numOfPack = Math.Round(Convert.ToDecimal(uniqueBig.CN_F_PACKING_QTY), 0);
//packUnit = "箱";
packUnit = _currentItemPack.CN_S_PACKING_UNIT;
}
}
else
{
string _packingUnit = "箱";
//packUnit = _packingUnit;// _currentItemPack.CN_S_PACKING_UNIT;
packUnit = _currentItemPack.CN_S_PACKING_UNIT;
numOfPack = _currentItemPack.CN_F_PACKING_QTY != null ? _currentItemPack.CN_F_PACKING_QTY.Value : 1;
_currentItemPack.WaitPickDetail = (_currentItemPack.CN_F_QUANTITY / _currentItemPack.CN_F_PACKING_QTY) + _packingUnit;
}
}
return new
{
ItemName = y.Key.CN_S_ITEM_NAME,
ItemCode = y.Key.CN_S_ITEM_CODE,
ItemState = y.Key.CN_S_ITEM_STATE,
WaitPickDetail = string.Join(",", currentItemPack.Select(o => o.WaitPickDetail)),
TotalNum = currentItems.Sum(o => o.CN_F_QUANTITY),
ItemUnit = currentItems[0].CN_S_MEASURE_UNIT,
PackUnit = packUnit,
NumOfPack = numOfPack,
ItemProLotNo = currentItem.CN_C_IS_LOT_OUT == "Y" ? y.Key.CN_S_PRODUCTION_BATCH : "",
ItemModel = y.Key.CN_S_MODEL,
Owner = y.Key.CN_S_OWNER,
AuxiliaryUnitList = currentItem.AuxiliaryUnitList ?? new List(),
};
});
Log.Info("sortingLocations result", JsonConvert.SerializeObject(results));
return OperateResult.Succeed(null, results);
});
}
#endregion
#region (PDA)确认分拣
///
/// (PDA)确认分拣
///
///
///
[HttpPost]
public OperateResult ConfirmSorting(dynamic confirmSorting)
{
Log.Info("确认分拣", JsonConvert.SerializeObject(confirmSorting));
string tokenId = Util.ToString(confirmSorting.tokenId);
return ValidateToken(tokenId, t =>
{
//分拣单
string sortingNo = Util.ToString(confirmSorting.SortingNo);
//托盘
string trayCode = Util.ToString(confirmSorting.TrayCode);
//当前货位是否全部捡完
bool locationPickFinish = false;// Convert.ToBoolean(confirmSorting.LocationPickFinish ?? false);
if (confirmSorting.SortingResult == null)
return OperateResult.Error("分拣物料不可为空");
//周转箱号
string boxNo = Util.ToString(confirmSorting.BoxNo);
//分拣单实体
TN_WM_SORTING_LISTEntity sortingEntity = new TN_WM_SORTING_LISTEntity();
List sortingResult = JsonConvert.DeserializeObject>(Util.ToString(confirmSorting.SortingResult));
sortingResult.ForEach(p =>
{
p.CN_GUID = Guid.NewGuid().ToString();
p.CN_S_SERIAL_NO = p.CN_S_SERIAL_NO ?? "";
p.CN_S_TRAY_CODE = p.CN_S_TRAY_CODE ?? "";
p.CN_S_TURNOVERBOX_CODE = p.CN_S_TURNOVERBOX_CODE ?? boxNo;
p.CN_S_CREATOR = t.CN_S_LOGIN;
p.CN_S_CREATOR_BY = t.CN_S_NAME;
p.CN_T_CREATE = DateTime.Now;
p.CN_S_MODIFY = t.CN_S_LOGIN;
p.CN_S_MODIFY_BY = t.CN_S_NAME;
p.CN_T_MODIFY = DateTime.Now;
});
bool sortingPicked = false;
//若当前货位捡完了,判断分拣单是否已全部捡完
var sortingLocations = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
var sortingResults = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingLocations.Where(x => x.CN_S_LOCATION_CODE == sortingResult[0].CN_S_LOCATION_CODE).Sum(y => y.CN_F_QUANTITY) ==
(sortingResults.Where(x => x.CN_S_LOCATION_CODE == sortingResult[0].CN_S_LOCATION_CODE).Sum(y => y.CN_F_QUANTITY) + sortingResult.Sum(x => x.CN_F_QUANTITY)))
{
locationPickFinish = true;
}
Log.Info("locationPickFinish", locationPickFinish.ToString());
Log.Info("确认分拣", "locationPickFinish");
sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (locationPickFinish)
{
//分拣单本次全部捡完
if (sortingLocations.Sum(x => x.CN_F_QUANTITY) ==
(sortingResults.Sum(x => x.CN_F_QUANTITY) + sortingResult.Sum(x => x.CN_F_QUANTITY)))
{
sortingPicked = true;
//sortingEntity = BLLCreator.Create>().GetSingleEntity(new
//{
// CN_S_SORTING_NO = sortingNo
//});
Log.Info("确认分拣", "isNeedUniPak");
//如果需要合箱,要判断所有分拣数据是否都已合箱
string isNeedUniPak = GetStrategy(sortingEntity.CN_S_STOCK_CODE,
StrategyKey.IsNeedUniPak);
Log.Info("确认分拣", isNeedUniPak);
if (isNeedUniPak.Equals("Y"))
{
if (!string.IsNullOrEmpty(boxNo))
{
foreach (var s in sortingResults)
{
if (string.IsNullOrEmpty(s.CN_S_TURNOVERBOX_CODE))
{
sortingPicked = false;
break;
}
}
}
else
{
sortingPicked = false;
}
}
Log.Info("确认分拣", "002");
}
}
bool wavePicked = false;
string waveNo = string.Empty;
//分拣单捡完了,判断波次是否捡完
if (sortingPicked)
{
wavePicked = true;
waveNo = sortingEntity.CN_S_FROM_NO;
var sortingList = BLLCreator.Create>().GetList(new
{
CN_S_FROM_NO = sortingEntity.CN_S_FROM_NO
});
//找波次下其他分拣单是否为已分拣
foreach (var s in sortingList.Where(x => x.CN_S_SORTING_NO != sortingNo))
{
if (s.CN_S_STATE != Constants.Sorting_Sorted)
{
wavePicked = false;
break;
}
}
}
Log.Info("确认分拣", "ConfirmSorting");
var result = BLLCreator.Create().ConfirmSorting(sortingPicked, wavePicked, waveNo, sortingResult, boxNo);
Log.Info("确认分拣", "result");
if (!result.Success)
return result;
Log.Info("确认分拣", "result");
//当前货位捡完了,发送灭灯指令
if (locationPickFinish)
{
Log.Info("locationPickFinish", "start");
//分拣单捡完,并且是移库单
if (sortingPicked && sortingEntity.CN_S_OP_FROM.Equals(Constants.MoveOrder))
{
Log.Info("移库单分拣完成", JsonConvert.SerializeObject(sortingEntity));
var moveResult = BLLCreator.Create().MoveSortingComplete(sortingEntity.CN_S_FROM_NO, t.CN_S_LOGIN, t.CN_S_NAME, t.CN_S_ORG_GUID, t.CN_S_ORGFLAG);
Log.Info("调用移库完成接口结果", JsonConvert.SerializeObject(moveResult));
if (!moveResult.Success)
return OperateResult.Error("分拣单已捡完,调用移库完成接口错误:" + moveResult.Exception.Message);
}
string isUseAms = GetStrategy(sortingEntity.CN_S_STOCK_CODE,
StrategyKey.IsUseAms);
Log.Info("sortingEntity.CN_S_STOCK_CODE", sortingEntity.CN_S_STOCK_CODE);
Log.Info("StrategyKey.IsUseAms", StrategyKey.IsUseAms);
//Log.Info("sortingEntity", JsonConvert.SerializeObject(sortingEntity));
Log.Info("isUseAms", isUseAms);
if (isUseAms.Equals("Y"))
{
var completeTaskParam = new
{
EndBit = sortingResult[0].CN_S_LOCATION_CODE,
Status = "作业完成"
};
Log.Info("ConfirmSorting 调用Ams发送灭灯指令参数 分拣单:" + sortingNo + " 货位:" + sortingResult[0].CN_S_LOCATION_CODE, JsonConvert.SerializeObject(completeTaskParam));
string amsResult = WebApiManager.HttpAms_Post("api/HHAms/CompleteTask", JsonConvert.SerializeObject(completeTaskParam));
Log.Info("ConfirmSorting 调用Ams发送灭灯指令返回值", amsResult);
}
}
return result;
});
}
#endregion
#region (PDA)扫描周转箱
///
/// (PDA)扫描周转箱
///
///
///
///
[HttpGet]
public OperateResult ScanBox(string boxNo, string sortingNo)
{
return ValidateToken(t =>
{
var trayInfoEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_TRAY_CODE = boxNo
});
if (trayInfoEntity == null)
return OperateResult.Error("未找到容器:" + boxNo);
if (trayInfoEntity.CN_S_STATE.Equals(Constants.TrayState_InUse))
{
if (!string.IsNullOrEmpty(trayInfoEntity.CN_S_SORTING_CODE) && !trayInfoEntity.CN_S_SORTING_CODE.Equals(sortingNo))
{
return OperateResult.Error("周转箱:" + boxNo + "已绑定了分拣单:" + trayInfoEntity.CN_S_SORTING_CODE);
}
}
return OperateResult.Succeed(null, trayInfoEntity);
});
}
#endregion
#region (PDA)合箱
///
/// (PDA)合箱
///
///
///
///
[HttpGet]
public OperateResult MergeBox(string sortingNo, string boxNo)
{
return ValidateToken(t =>
{
var sortingEntity = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingEntity == null)
return OperateResult.Error("未找到分拣单:" + sortingNo);
if (sortingEntity.CN_S_STATE.Equals(Constants.Sorting_Sorted))
{
return OperateResult.Error("该分拣单已分拣完成,无需合箱");
}
var sortingLocations = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
var sortingResults = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
bool sortingPicked = false;
//分拣单全部捡完
if (sortingLocations.Sum(x => x.CN_F_QUANTITY) ==
(sortingResults.Sum(x => x.CN_F_QUANTITY)))
{
sortingPicked = true;
}
bool wavePicked = false;
string waveNo = string.Empty;
//分拣单捡完了,判断波次是否捡完
if (sortingPicked)
{
wavePicked = true;
waveNo = sortingEntity.CN_S_FROM_NO;
var sortingList = BLLCreator.Create>().GetList(new
{
CN_S_FROM_NO = sortingEntity.CN_S_FROM_NO
});
//找波次下其他分拣单是否为已分拣
foreach (var s in sortingList.Where(x => x.CN_S_SORTING_NO != sortingNo))
{
if (s.CN_S_STATE != Constants.Sorting_Sorted)
{
wavePicked = false;
break;
}
}
}
List sortingResult = new List();
foreach (var s in sortingResults)
{
if (string.IsNullOrEmpty(s.CN_S_TURNOVERBOX_CODE))
{
s.CN_S_TURNOVERBOX_CODE = boxNo;
sortingResult.Add(s);
}
}
if (!sortingResult.Any())
{
return OperateResult.Error("未找到该分拣单需要合箱的数据!");
}
return BLLCreator.Create().MergeBox(sortingResult, sortingPicked, wavePicked, waveNo);
});
}
#endregion
#region (PDA汇聚)根据分拣单获取波次下所有发货通知单和分拣明细
///
/// (PDA汇聚)根据分拣单获取波次下所有发货通知单和分拣明细
///
///
///
///
[HttpGet]
public OperateResult GetBJBBSortingData(string sortingNo, string locationCode)
{
return ValidateToken(t =>
{
var sortingEntity = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingEntity == null)
return OperateResult.Error("未找到分拣单:" + sortingNo);
//当前分拣单当前货位
var currentSortingLocation = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo,
CN_S_LOCATION_CODE = locationCode
});
//当前分拣单波次下所有出库单
var currentWaveOut = BLLCreator.Create().GetOutListByWave(sortingEntity.CN_S_FROM_NO);
//订单拣货数据
var orderSortingRels = BLLCreator.CreateDapper().GetList(new
{
CN_S_ORDER_NO = currentWaveOut.Select(s => s.CN_S_OP_NO).ToList()
});
//批分每个出库单每个物料拣了多少个
foreach (var currentOut in currentWaveOut)
{
var curOrderSorting = orderSortingRels.Where(s => s.CN_S_ORDER_NO == currentOut.CN_S_OP_NO);
foreach (var currentOutDtl in currentOut.OutDtlList)
{
var equalsCurOS = curOrderSorting.Where(w =>
w.CN_S_ITEM_CODE == currentOutDtl.CN_S_ITEM_CODE &&
w.CN_S_ITEM_STATE == currentOutDtl.CN_S_ITEM_STATE &&
w.CN_S_OWNER == currentOut.CN_S_OWNER &&
(w.CN_S_LOT_NO == currentOutDtl.CN_S_LOT_CODE || string.IsNullOrEmpty(currentOutDtl.CN_S_LOT_CODE)));
foreach (var curOS in equalsCurOS)
{
var qty = currentOutDtl.CN_F_QUANTITY - currentOutDtl.CN_F_PICKED_QTY;
if (qty == 0) break;
if (curOS.CN_F_QUANTITY == 0) continue;
if (curOS.CN_F_QUANTITY >= qty)
{
currentOutDtl.CN_F_PICKED_QTY += qty;
curOS.CN_F_QUANTITY -= qty;
}
else
{
currentOutDtl.CN_F_PICKED_QTY += curOS.CN_F_QUANTITY;
curOS.CN_F_QUANTITY = 0;
}
}
}
}
var result = new
{
SortingLocations = currentSortingLocation,
OutData = currentWaveOut,
SortingBit = new string[] { "FJT01", "FJT02", "FJT03", "FJT04", }
};
return OperateResult.Succeed(null, result);
});
}
#endregion
public OperateResult SaveXJHB(dynamic saveData)
{
string tokenId = Util.ToString(saveData.tokenId);
return ValidateToken(tokenId, t =>
{
Log.Info("SaveXJHB", JsonConvert.SerializeObject(saveData));
//分拣结果
List sortingResult = JsonConvert.DeserializeObject>(Util.ToString(saveData.SortingResult));
if (!sortingResult.Any())
return OperateResult.Error("分拣结果数据不可为空");
string sortingNo = Util.ToString(saveData.SortingNo);
if (string.IsNullOrEmpty(sortingNo))
return OperateResult.Error("分拣单号不可为空");
//周转箱号
string boxNo = Util.ToString(saveData.BoxNo);
var sortingLocations = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo,
});
//当前分拣明细的当前分拣物料
var pickedItemLocations = sortingLocations.Where(w =>
w.CN_S_TRAY_CODE == sortingResult[0].CN_S_TRAY_CODE &&
w.CN_S_LOCATION_CODE == sortingResult[0].CN_S_LOCATION_CODE &&
sortingResult.Exists(e => e.CN_S_ITEM_CODE == w.CN_S_ITEM_CODE)).ToList();
//批分分拣明细分拣数量
foreach (var sr in sortingResult)
{
foreach (var pickedItem in pickedItemLocations)
{
if (sr.CN_F_QUANTITY == 0) break;
var stayQty = pickedItem.CN_F_QUANTITY - pickedItem.CN_F_PICKED_QTY;
if (stayQty == 0) continue;
if (sr.CN_F_QUANTITY >= stayQty)
{
pickedItem.CN_F_PICKED_QTY += stayQty;
sr.CN_F_QUANTITY -= stayQty;
}
else
{
pickedItem.CN_F_PICKED_QTY += sr.CN_F_QUANTITY;
sr.CN_F_QUANTITY = 0;
}
}
}
//分拣单,波次是否已分拣
bool sortingPicked = false; bool wavePicked = false;
//分拣单是否全部分拣完 , 必须拣完并且全部合箱
if (sortingLocations.Sum(s => s.CN_F_QUANTITY) == sortingLocations.Sum(s => s.CN_F_PICKED_QTY))
{
var allSortingResult = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo,
});
if (!string.IsNullOrEmpty(boxNo) &&
!allSortingResult.Exists(e => string.IsNullOrEmpty(e.CN_S_TURNOVERBOX_CODE)))
sortingPicked = true;
}
//当前分拣单实体
var currentSorting = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingResult[0].CN_S_SORTING_NO
});
#region 分拣单捡完了,判断波次有没有捡完
//分拣单捡完了,判断波次有没有捡完
if (sortingPicked)
{
var waveSortings = BLLCreator.CreateDapper().GetList(new
{
CN_S_FROM_NO = currentSorting.CN_S_FROM_NO
});
if (!(waveSortings.Exists(e => e.CN_S_STATE != Constants.Sorting_Sorted)))
wavePicked = true;
}
#endregion
#region 如果分拣单拣完了,批分库区降库存
List areaQtyList = new List();
//算法策略
List lstStrate = BLLCreator.Create().GetStrateListByAreaOrStock("", "", Constants.Out)
.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
Log.Info("确认分拣", "lstStrate");
//分拣单都拣完了,批分库区降库存
if (sortingPicked)
{
Log.Info("确认分拣sortingResult", JsonConvert.SerializeObject(sortingResult));
if (currentSorting != null)
{
var currentSortingDtl = BLLCreator.CreateDapper()
.GetList(new
{
CN_S_SORTING_NO = currentSorting.CN_S_SORTING_NO
});
currentSorting.SortingDtlList = currentSortingDtl;
areaQtyList = BLLCreator.CreateDapper().GetList(new
{
CN_S_ITEM_CODE = currentSortingDtl.Select(x => x.CN_S_ITEM_CODE).ToList()
});
//反批分库区分配量
Log.Info("确认分拣反批分库区分配量", "BatchesAreaQty");
var result = areaQtyList.BatchesAreaQty(new List() { currentSorting }, lstStrate, true);
Log.Info("确认分拣反批分库区分配量结果", JsonConvert.SerializeObject(result));
if (!result.Success)
return result;
}
}
#endregion
#region 批分托盘物料关联,降分配量,删子表,解货位
//分拣结果的托盘物料关联数据
var trayItemMstList = BLLCreator.Create().BatchesTrayItemByResult(sortingResult);
var currentTrayLocation = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_TRAY_CODE = sortingResult[0].CN_S_TRAY_CODE
});
#endregion
#region 初始化分拣结果
sortingResult.ForEach(p =>
{
p.CN_GUID = Guid.NewGuid().ToString();
p.CN_S_SERIAL_NO = p.CN_S_SERIAL_NO ?? "";
p.CN_S_TRAY_CODE = p.CN_S_TRAY_CODE ?? "";
p.CN_S_TURNOVERBOX_CODE = p.CN_S_TURNOVERBOX_CODE ?? boxNo;
p.CN_S_CREATOR = t.CN_S_LOGIN;
p.CN_S_CREATOR_BY = t.CN_S_NAME;
p.CN_T_CREATE = DateTime.Now;
p.CN_S_MODIFY = t.CN_S_LOGIN;
p.CN_S_MODIFY_BY = t.CN_S_NAME;
p.CN_T_MODIFY = DateTime.Now;
});
#endregion
SavePickEntity savePickEntity = new SavePickEntity()
{
CurrentSorting = currentSorting,
SortingPicked = sortingPicked,
WavePicked = wavePicked,
BoxNo = boxNo,
WaveNo = currentSorting.CN_S_FROM_NO,
SortingNo = currentSorting.CN_S_SORTING_NO,
SortingResult = sortingResult,
SortingLocation = pickedItemLocations,
TrayItemList = trayItemMstList,
TrayLocation = currentTrayLocation,
AreaQtyList = areaQtyList
};
return BLLCreator.Create().SaveXJHB(savePickEntity);
});
}
#region (PDA汇聚)保存边拣边播
///
/// (PDA汇聚)保存边拣边播
///
///
///
public OperateResult SaveBJBB(dynamic saveData)
{
string tokenId = Util.ToString(saveData.tokenId);
return ValidateToken(tokenId, t =>
{
Log.Info("保存边拣边播SaveBJBB", JsonConvert.SerializeObject(saveData));
//分拣结果
List sortingResult = JsonConvert.DeserializeObject>(Util.ToString(saveData.SortingResult));
if (!sortingResult.Any())
return OperateResult.Error("分拣结果数据不可为空");
List orderSortingRel = JsonConvert.DeserializeObject>(Util.ToString(saveData.OrderSortingRel));
if (!orderSortingRel.Any())
return OperateResult.Error("订单拣货明细不可为空");
//周转箱号
string boxNo = Util.ToString(saveData.BoxNo);
if (string.IsNullOrEmpty(boxNo))
return OperateResult.Error("合箱容器号不可为空");
var sortingLocations = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingResult[0].CN_S_SORTING_NO,
});
var pickedItemLocations = sortingLocations.Where(w =>
w.CN_S_TRAY_CODE == sortingResult[0].CN_S_TRAY_CODE &&
w.CN_S_LOCATION_CODE == sortingResult[0].CN_S_LOCATION_CODE &&
sortingResult.Exists(e => e.CN_S_ITEM_CODE == w.CN_S_ITEM_CODE)).ToList();
//批分分拣明细分拣数量
foreach (var sr in sortingResult)
{
foreach (var pickedItem in pickedItemLocations)
{
if (sr.CN_F_QUANTITY == 0) break;
var stayQty = pickedItem.CN_F_QUANTITY - pickedItem.CN_F_PICKED_QTY;
if (stayQty == 0) continue;
if (sr.CN_F_QUANTITY >= stayQty)
{
pickedItem.CN_F_PICKED_QTY += stayQty;
sr.CN_F_QUANTITY -= stayQty;
}
else
{
pickedItem.CN_F_PICKED_QTY += sr.CN_F_QUANTITY;
sr.CN_F_QUANTITY = 0;
}
}
}
//分拣单,波次是否已分拣
bool sortingPicked = false; bool wavePicked = false;
//分拣单是否全部分拣完
if (sortingLocations.Sum(s => s.CN_F_QUANTITY) == sortingLocations.Sum(s => s.CN_F_PICKED_QTY))
sortingPicked = true;
//当前分拣单实体
var currentSorting = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingResult[0].CN_S_SORTING_NO
});
#region 分拣单捡完了,判断波次有没有捡完
//分拣单捡完了,判断波次有没有捡完
if (sortingPicked)
{
var waveSortings = BLLCreator.CreateDapper().GetList(new
{
CN_S_FROM_NO = currentSorting.CN_S_FROM_NO
});
if (!(waveSortings.Exists(e => e.CN_S_STATE != Constants.Sorting_Sorted)))
wavePicked = true;
}
#endregion
#region 如果分拣单拣完了,批分库区降库存
List areaQtyList = new List();
//算法策略
List lstStrate = BLLCreator.Create().GetStrateListByAreaOrStock("", "", Constants.Out)
.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
Log.Info("确认分拣", "lstStrate");
//分拣单都拣完了,批分库区降库存
if (sortingPicked)
{
Log.Info("确认分拣sortingResult", JsonConvert.SerializeObject(sortingResult));
if (currentSorting != null)
{
var currentSortingDtl = BLLCreator.CreateDapper()
.GetList(new
{
CN_S_SORTING_NO = currentSorting.CN_S_SORTING_NO
});
currentSorting.SortingDtlList = currentSortingDtl;
areaQtyList = BLLCreator.CreateDapper().GetList(new
{
CN_S_ITEM_CODE = currentSortingDtl.Select(x => x.CN_S_ITEM_CODE).ToList()
});
//反批分库区分配量
Log.Info("确认分拣反批分库区分配量", "BatchesAreaQty");
var result = areaQtyList.BatchesAreaQty(new List() { currentSorting }, lstStrate, true);
Log.Info("确认分拣反批分库区分配量结果", JsonConvert.SerializeObject(result));
if (!result.Success)
return result;
}
}
#endregion
#region 批分托盘物料关联,降分配量,删子表,解货位
//分拣结果的托盘物料关联数据
var trayItemMstList = BLLCreator.Create().BatchesTrayItemByResult(sortingResult);
var currentTrayLocation = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_TRAY_CODE = sortingResult[0].CN_S_TRAY_CODE
});
#endregion
#region 初始化分拣结果,订单拣货明细实体
sortingResult.ForEach(p =>
{
p.CN_GUID = Guid.NewGuid().ToString();
p.CN_S_SERIAL_NO = p.CN_S_SERIAL_NO ?? "";
p.CN_S_TRAY_CODE = p.CN_S_TRAY_CODE ?? "";
p.CN_S_TURNOVERBOX_CODE = p.CN_S_TURNOVERBOX_CODE ?? boxNo;
p.CN_S_CREATOR = t.CN_S_LOGIN;
p.CN_S_CREATOR_BY = t.CN_S_NAME;
p.CN_T_CREATE = DateTime.Now;
p.CN_S_MODIFY = t.CN_S_LOGIN;
p.CN_S_MODIFY_BY = t.CN_S_NAME;
p.CN_T_MODIFY = DateTime.Now;
});
orderSortingRel.ForEach(p =>
{
p.CN_GUID = Guid.NewGuid().ToString();
p.CN_S_SERIAL_NO = p.CN_S_SERIAL_NO ?? "";
p.CN_S_CREATOR = t.CN_S_LOGIN;
p.CN_S_CREATOR_BY = t.CN_S_NAME;
p.CN_T_CREATE = DateTime.Now;
p.CN_S_MODIFY = t.CN_S_LOGIN;
p.CN_S_MODIFY_BY = t.CN_S_NAME;
p.CN_T_MODIFY = DateTime.Now;
});
#endregion
SavePickEntity savePickEntity = new SavePickEntity()
{
CurrentSorting = currentSorting,
SortingPicked = sortingPicked,
WavePicked = wavePicked,
BoxNo = boxNo,
WaveNo = currentSorting.CN_S_FROM_NO,
SortingNo = currentSorting.CN_S_SORTING_NO,
SortingResult = sortingResult,
SortingLocation = pickedItemLocations,
OrderSortingRel = orderSortingRel,
TrayItemList = trayItemMstList,
TrayLocation = currentTrayLocation,
AreaQtyList = areaQtyList
};
return BLLCreator.Create().SaveBJBB(savePickEntity);
});
}
#endregion
#region (PDA汇聚)分拣回和搬运
///
/// (PDA汇聚)分拣回和搬运
///
///
///
[HttpGet]
public OperateResult Transport(string trayCode, string endArea, string sortingNo = "")
{
return ValidateToken(t =>
{
//找是否已经存在该托盘未执行完的任务
var existsTask = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_TRAY_CODE = trayCode,
CN_S_STATE = new List() { Constants.TaskState_NoExecuted, Constants.TaskState_Executing },
});
if (existsTask != null)
return OperateResult.Error("托盘:" + trayCode + "存在未执行完的任务");
//当前托盘所在位置
var currentTrayLocation = BLLCreator.CreateDapper()
.GetSingleEntity(new
{
CN_S_TRAY_CODE = trayCode
});
//需要调作业区入库算法,算出货位给出库任务
var inAssignEntity = new InAssignEntity
{
objectType = InAssignEntity.ObjectType.托盘,
objectCode = trayCode,
lockLocation = false,
lstAreaPrior = new List()
{
{
new areaPriorClass{
areaCode = endArea,
Prior = 1
}
}
}
};
Log.Info("调用算法InAssign参数", JsonConvert.SerializeObject(inAssignEntity));
InAssignResultEntity inAssignResultEntity = BLLCreator.Create().InAssign(inAssignEntity);
Log.Info("调用算法InAssign结果", JsonConvert.SerializeObject(inAssignResultEntity));
if (!inAssignResultEntity.Success) return OperateResult.Error(inAssignResultEntity.Msg);
//整托出库任务
string postData = "{\"appCode\":\"" + Constants.appCode + "\",\"ruleName\":\"" + Constants.Rule_TaskNo + "\",\"orgId\":\"\",\"orgFlag\":\"\"}";
string taskNo = WebApiManager.HttpAutoBom_Post("api/BillRule/GenBillNo", postData);
string taskType = string.IsNullOrEmpty(sortingNo) ? Constants.TaskType_Transport : Constants.TaskType_SortingIn;
TN_WM_TASKEntity taskEntity = new TN_WM_TASKEntity()
{
CN_S_TASK_NO = taskNo,
CN_S_TASK_TYPE = taskType,
CN_S_FROM_OP = Constants.Out,
CN_S_FROM_NO = sortingNo,
CN_S_TRAY_CODE = trayCode,
CN_S_STOCK_CODE = currentTrayLocation.CN_S_STOCK_CODE,
CN_S_START_AREA = currentTrayLocation.CN_S_STOCK_AREA,
CN_S_START_BIT = currentTrayLocation.CN_S_LOCATION_CODE,
CN_S_END_AREA = endArea,
CN_S_END_BIT = inAssignResultEntity.locationCode,
CN_S_STATE = Constants.TaskState_NoExecuted,
CN_T_CREATE = DateTime.Now,
CN_T_MODIFY = DateTime.Now
};
return BLLCreator.Create().Transport(taskEntity);
});
}
#endregion
#region 获取分拣明细
///
///获取分拣明细
///
///
///
///
private OperateResult GetSortingLocation(TN_WM_SORTING_LISTEntity sortingEntity, UserRuleEntity user)
{
try
{
List sortingLocationList = new List();
//初始化调用算法数据
List algorItems = sortingEntity.SortingDtlList.GroupBy(x => new
{
x.CN_S_ITEM_CODE,
x.CN_S_ITEM_STATE,
x.CN_S_OWNER,
x.CN_S_LOT_NO,
x.CN_S_PRODUCTION_BATCH
}).Select(y => new itemQueryClass()
{
stockCode = sortingEntity.CN_S_STOCK_CODE,
areaCode = sortingEntity.CN_S_STOCK_AREA,
itemCode = y.Key.CN_S_ITEM_CODE,
batchCode = y.Key.CN_S_LOT_NO,
prodBatchCode = y.Key.CN_S_PRODUCTION_BATCH,
itemState = y.Key.CN_S_ITEM_STATE,
ownerName = y.Key.CN_S_OWNER,
itemQty = y.Sum(z => z.CN_F_QUANTITY)
}).ToList();
var 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("算法异常:" + outResult.Msg);
if (sortingEntity.SortingDtlList.Sum(x => x.CN_F_QUANTITY) != Convert.ToDecimal(outResult.itemLocations.Sum(x => x.itemQty)))
{
return OperateResult.Error("算法异常:返回的物料信息不完整!");
}
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
};
}).ToList();
sortingLocationList.AddRange(locations);
return OperateResult.Succeed(null, sortingLocationList);
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region 分拣单列表
///
/// 分拣单列表
///
///
///
[HttpPost]
public string GetSortingList(SearchModel searchModel)
{
OperateResult result = new OperateResult();
try
{
long total = 0;
DataTable dt = BLLCreator.Create>().GetPagingData(new List() {
new SearchWhere(){ key="CN_S_SORTING_NO", sign= WhereSign.Like, value=Util.ToString(searchModel.SearchCondition.SortingNo)}
}, searchModel.PageIndex, searchModel.PageSize, out total, true, new
{
CN_S_SORTING_NO = "%" + Util.ToString(searchModel.SearchCondition.SortingNo) + "%"
});
dt.Columns["CN_S_STOCK_CODE"].ReadOnly = false;
foreach (DataRow dr in dt.Rows)
{
dr["CN_S_STOCK_CODE"] = GetStock().Find(x => x.CN_S_STOCK_CODE.Equals(dr["CN_S_STOCK_CODE"].ToString().Trim())).CN_S_STOCK_NAME;
dr["CN_S_STOCK_AREA"] = GetStockArea().Find(x => x.CN_S_AREA_CODE.Equals(dr["CN_S_STOCK_AREA"].ToString().Trim())).CN_S_AREA_NAME;
}
result = OperateResult.Succeed("", new
{
rows = dt,
total = total
});
}
catch (Exception ex)
{
result = OperateResult.Error(ex.Message);
}
IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
return JsonConvert.SerializeObject(result, timeFormat);
//return result;
}
#endregion
#region 分拣数据
///
/// 分拣数据
///
///
///
[HttpGet]
public OperateResult GetSortingDtl(string sortingNo)
{
try
{
var sortingDtl = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
return OperateResult.Succeed(null, sortingDtl);
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region 分拣明细
///
/// 分拣明细
///
///
///
[HttpGet]
public OperateResult GetCurrentSortingLocation(string sortingNo)
{
try
{
var sortingDtl = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
return OperateResult.Succeed(null, sortingDtl);
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region 分拣结果
///
/// 分拣结果
///
///
///
[HttpGet]
public OperateResult GetSortingResult(string sortingNo)
{
try
{
var sortingDtl = BLLCreator.Create>().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
return OperateResult.Succeed(null, sortingDtl);
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region 查询分拣单实体
///
/// 查询盘点单实体
///
/// 分拣单号
///
/// [Hanhe(dbs)] creater 2018/12/20
public OperateResult GetSortingModel(string sortingNo)
{
try
{
return ValidateToken(t =>
{
TN_WM_SORTING_LISTEntity sorting = BLLCreator.Create>().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sorting != null)
sorting.CN_S_STOCK_AREA = this.GetStockArea().Find(x => x.CN_S_AREA_CODE.Equals(sorting.CN_S_STOCK_AREA)).CN_S_AREA_NAME;
return OperateResult.Succeed(null, sorting);
});
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region 订单拣货明细
///
/// 订单拣货明细
///
///
///
[HttpGet]
public OperateResult GetOrderSortingRel(string opNo)
{
try
{
var sortingDtl = BLLCreator.Create>().GetList(new
{
CN_S_ORDER_NO = opNo
});
return OperateResult.Succeed(null, sortingDtl);
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region 根据出库单号获取订单拣货明细
///
/// 根据出库单号获取订单拣货明细
///
///
///
[HttpGet]
public OperateResult GetOrderSortingRelByOrderNo(string opNo)
{
try
{
var sortingDtl = BLLCreator.Create>().GetList(new
{
CN_S_ORDER_NO = opNo,
CN_C_ISPACK = "Y"
});
return OperateResult.Succeed(null, sortingDtl);
}
catch (Exception ex)
{
return OperateResult.Error(ex.Message);
}
}
#endregion
#region (cs端)先拣后播扫物料
///
/// ScanItem
///
///
///
[HttpPost]
public OperateResult ScanItem(PostEntity postEntity)
{
return ValidateToken(postEntity.TokenId, t =>
{
var sortingResult = postEntity.GetPostData();
if (sortingResult == null)
return OperateResult.Error("分拣结果数据不可为空");
//当前拣的分拣明细
var sortingLocation = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingResult.CN_S_SORTING_NO,
CN_S_TRAY_CODE = sortingResult.CN_S_TRAY_CODE,
CN_S_ITEM_CODE = sortingResult.CN_S_ITEM_CODE
});
//增加分拣明细分拣数
if (sortingLocation != null)
{
if (sortingResult.CN_F_QUANTITY > (sortingLocation.CN_F_QUANTITY - sortingLocation.CN_F_PACKING_QTY))
return OperateResult.Error("包装数大于分拣数");
sortingLocation.CN_F_PICKED_QTY += sortingResult.CN_F_QUANTITY;
}
#region 批分托盘物料关联,降分配量,删子表,解货位
//算法策略
List lstStrate = BLLCreator.Create().GetStrateListByAreaOrStock("", "", Constants.Out)
.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
//分拣结果的托盘物料关联数据
var trayItemMstList = BLLCreator.CreateDapper().GetList(new
{
CN_S_TRAY_CODE = sortingResult.CN_S_TRAY_CODE,
CN_S_ITEM_CODE = sortingResult.CN_S_ITEM_CODE
});
foreach (var trayItemMst in trayItemMstList)
{
trayItemMst.TrayItemDtlList = new List();
//属于当前托盘,当前物料的分拣明细
var currentSortingResult = sortingResult;
decimal qty = currentSortingResult.CN_F_QUANTITY;
if (trayItemMst.CN_F_QUANTITY >= qty &&
trayItemMst.CN_F_ALLOC_QTY >= qty)
{
trayItemMst.CN_F_QUANTITY -= qty;
trayItemMst.CN_F_ALLOC_QTY -= qty;
Log.Info("确认分拣", "0001");
trayItemMst.TrayItemDtlList = BLLCreator.CreateDapper().GetList(new
{
CN_PARENT_GUID = trayItemMst.CN_GUID
}).OrderBy(x => x.CN_S_LOT_NO).ToList();
Log.Info("确认分拣", "0002");
Log.Info("确认分拣", "0003");
foreach (string stegy in lstStrate)
{
//逐个策略进行计算
switch (stegy)
{
case "FirstInFirstOut":
trayItemMst.TrayItemDtlList = trayItemMst.TrayItemDtlList.OrderBy(o => o.CN_S_LOT_NO).ToList();
break;
case "FirstWarrantFirstOut":
trayItemMst.TrayItemDtlList = trayItemMst.TrayItemDtlList.Select(x => new
{
index = string.IsNullOrEmpty(x.CN_S_PRODUCTION_BATCH) ? 0 : 1,
x
}).OrderByDescending(y => y.index).ThenBy(z => z.x.CN_S_PRODUCTION_BATCH).Select(m => m.x).ToList();
break;
}
}
Log.Info("确认分拣", "0004");
var csQty = currentSortingResult.CN_F_QUANTITY;
foreach (var trayItemDtl in trayItemMst.TrayItemDtlList)
{
if (csQty == 0) break;
if (trayItemDtl.CN_F_QUANTITY == 0) continue;
if (trayItemDtl.CN_F_QUANTITY >= csQty)
{
trayItemDtl.CN_F_QUANTITY -= csQty;
csQty = 0;
}
else
{
csQty -= trayItemDtl.CN_F_QUANTITY;
trayItemDtl.CN_F_QUANTITY = 0;
}
}
}
}
var currentTrayLocation = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_TRAY_CODE = sortingResult.CN_S_TRAY_CODE
});
#endregion
#region 初始化数据
sortingResult.CN_GUID = Guid.NewGuid().ToString();
sortingResult.CN_S_SERIAL_NO = sortingResult.CN_S_SERIAL_NO ?? "";
sortingResult.CN_S_TRAY_CODE = sortingResult.CN_S_TRAY_CODE ?? "";
sortingResult.CN_S_TURNOVERBOX_CODE = sortingResult.CN_S_TURNOVERBOX_CODE ?? "";
sortingResult.CN_S_CREATOR = t.CN_S_LOGIN;
sortingResult.CN_S_CREATOR_BY = t.CN_S_NAME;
sortingResult.CN_T_CREATE = DateTime.Now;
sortingResult.CN_S_MODIFY = t.CN_S_LOGIN;
sortingResult.CN_S_MODIFY_BY = t.CN_S_NAME;
sortingResult.CN_T_MODIFY = DateTime.Now;
var currentSorting = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingResult.CN_S_SORTING_NO,
});
#endregion
SavePickEntity savePickEntity = new SavePickEntity
{
SortingResult = new List() { sortingResult },
TrayItemList = trayItemMstList,
TrayLocation = currentTrayLocation,
CurrentSorting = currentSorting
};
return BLLCreator.Create().ScanItem(savePickEntity);
});
}
#endregion
#region (cs端)先拣后播扫周转箱
///
/// (cs端)先拣后播扫周转箱
///
///
///
///
///
[HttpGet]
public OperateResult ScanTurnoverBox(string sortingNo, string boxNo, string location)
{
return ValidateToken(t =>
{
var trayEntity = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_TRAY_CODE = boxNo
});
if (trayEntity == null)
return OperateResult.Error("不存在周转箱:" + boxNo);
var sortingEntity = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_SORTING_NO = sortingNo
});
if (sortingEntity == null)
return OperateResult.Error("未找到分拣单:" + sortingNo);
var fromOutMst = BLLCreator.CreateDapper().GetSingleEntity(new
{
CN_S_WAVE_CODE = sortingEntity.CN_S_FROM_NO
});
if (fromOutMst == null)
return OperateResult.Error("未找到分拣单波次所属出库单");
//当前波次所有分拣单
var currentWaveSortings = BLLCreator.CreateDapper().GetList(new
{
CN_S_FROM_NO = sortingEntity.CN_S_FROM_NO
});
//同一波次分拣单到同一个集散区
string boxBit = string.Empty;
var existsBitSorting = currentWaveSortings.Find(w => !string.IsNullOrEmpty(w.CN_S_COLLECT_LOCATION));
if (existsBitSorting != null)
boxBit = existsBitSorting.CN_S_COLLECT_LOCATION;
if (string.IsNullOrEmpty(boxBit))
{
var jsArea = BLLCreator.Create().GetSingle("CN_S_AREA_NAME", Constants.JSArea);
if (jsArea == null)
return OperateResult.Error("请维护集散区");
InAssignEntity aEntity = new InAssignEntity()
{
objectType = InAssignEntity.ObjectType.周转箱,
objectCode = boxNo,
lockLocation = false,
lstAreaPrior = new List() {
{
new areaPriorClass()
{
areaCode = jsArea.CN_S_AREA_CODE,
Prior = 1
}
}
},
logicAreaCode = Constants.FixedLogicArea_JS_FROM
};
//根据库区获取货位
InAssignResultEntity resultEntity = BLLCreator.Create().InAssign(aEntity);
if (!resultEntity.Success)
return OperateResult.Error(resultEntity.Msg);
boxBit = resultEntity.locationCode;
}
//当前分拣单分拣明细
var currentSortingLocation = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo
});
//当前分拣单是否分拣完
bool sortingPicked = false;
//当前波次是否捡完
bool wavePicked = false;
//当前分拣单是否分拣完
if (currentSortingLocation.Sum(s => s.CN_F_QUANTITY) == currentSortingLocation.Sum(s => s.CN_F_PICKED_QTY))
sortingPicked = true;
//当前波次是否捡完
var otherSortings = currentWaveSortings.Where(w => w.CN_S_SORTING_NO != sortingNo);
if (sortingPicked &&
!otherSortings.Any() ||
(otherSortings.Count() == otherSortings.Where(w => w.CN_S_STATE == Constants.Sorting_Sorted).Count()))
wavePicked = true;
//当前分拣单未合箱的分拣结果
var staySortingResult = BLLCreator.CreateDapper().GetList(new
{
CN_S_SORTING_NO = sortingNo
}).Where(w => string.IsNullOrEmpty(w.CN_S_TURNOVERBOX_CODE)).ToList();
SavePickEntity savePickEntity = new SavePickEntity()
{
SortingPicked = sortingPicked,
WavePicked = wavePicked,
CurrentSorting = sortingEntity,
IsWx = fromOutMst.CN_S_SALES_STYLE == Constants.SalesStyle_WX,
OutMst = fromOutMst,
SortingResult = staySortingResult,
SortingNo = sortingNo,
BoxNo = boxNo,
StartBit = location,
EndBit = boxBit
};
return OperateResult.Succeed();
});
}
#endregion
}
}