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)获取的分拣单
|
/// <summary>
|
/// (PDA)获取的分拣单
|
/// </summary>
|
/// <returns></returns>
|
[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<TN_WM_SORTING_LOCATIONEntity>();
|
if (!string.IsNullOrEmpty(sortingNo))
|
{
|
sortingEntity = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
if (sortingEntity == null)
|
return OperateResult.Error("未找到分拣单:" + sortingNo);
|
}
|
else
|
{
|
sortingEntity = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().GetSingleEntity(new
|
{
|
CN_S_STATE = Constants.Sorting_Being
|
});
|
if (sortingEntity == null)
|
{
|
sortingEntity = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().GetSingleEntity(new
|
{
|
CN_S_STATE = new List<string>() { Constants.Sorting_Stay, Constants.Sorting_Being }
|
}, " ORDER BY CN_T_CREATE");
|
if (sortingEntity == null)
|
{
|
return OperateResult.Error("");
|
}
|
}
|
}
|
|
var sortingLocation = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().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<DapperBLL<TN_WM_SORTING_RESULTEntity>>().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)分拣单列表
|
/// <summary>
|
/// (PDA)分拣单列表
|
/// </summary>
|
/// <param name="key"></param>
|
/// <returns></returns>
|
[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<TN_WM_SORTING_LISTEntity>().GetList(new
|
{
|
CN_S_STATE = new List<string> { 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杭叉)分拣指引
|
/// <summary>
|
/// (PDA杭叉)分拣指引
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult SortingGuide(string sortingNo)
|
{
|
return ValidateToken(t =>
|
{
|
var sortingEntity = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
if (sortingEntity == null)
|
return OperateResult.Error("未找到分拣单:" + sortingNo);
|
|
var trayItem = new List<TN_WM_B_TRAY_ITEM_MSTEntity>();
|
//待分拣时生成分拣明细
|
if (sortingEntity.CN_S_STATE == Constants.Sorting_Stay)
|
{
|
#region 生成分拣明细
|
//调用算法获取分拣明细,分拣明细改到执行分拣单的时候生成
|
var sortingLocationResult = BLLCreator.Create<TN_WM_SORTING_LISTBLL>().GetSortingLocation(sortingEntity,
|
new UserRuleEntity()
|
{
|
LoginCode = t.CN_S_LOGIN,
|
LoginName = t.CN_S_NAME
|
});
|
if (!sortingLocationResult.Success)
|
return sortingLocationResult;
|
var sortingLocations = sortingLocationResult.GetData<List<TN_WM_SORTING_LOCATIONEntity>>();
|
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<DapperBLL<TN_WM_B_TRAY_ITEM_MSTEntity>>().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<TN_WM_SORTING_LISTBLL>().ExecuteSorting(sortingEntity, trayItem);
|
if (!or.Success) return or;
|
#endregion
|
}
|
|
var currentSortingLocation = BLLCreator.CreateDapper<TN_WM_SORTING_LOCATIONEntity>().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杭叉)先拣后播页面数据
|
/// <summary>
|
/// (PDA杭叉)先拣后播页面数据
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <param name="location"></param>
|
/// <returns></returns>
|
[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<TN_WM_SORTING_LOCATIONEntity>().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)执行分拣单
|
/// <summary>
|
/// (PDA)执行分拣单
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult ExecuteSorting(string tokenId, string sortingNo, string area = "")
|
{
|
return ValidateToken(tokenId, t =>
|
{
|
var sortingEntity = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().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<TN_WM_B_TRAY_ITEM_MSTEntity>();
|
if (sortingEntity.CN_S_OP_FROM != Constants.MoveOrder)
|
{
|
#region 自动库需要生成出库任务
|
|
//生成任务
|
List<string> endAreas = new List<string>();
|
var outTaskResult = BLLCreator.Create<TN_WM_SORTING_LISTBLL>(t).GetOutTask(ref sortingEntity, ref endAreas, area);
|
|
if (!outTaskResult.Success)
|
{
|
return outTaskResult;
|
}
|
|
#endregion
|
}
|
var result = BLLCreator.Create<TN_WM_SORTING_LISTBLL>().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<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
var amsAddTaskList = new List<AmsAddTask>();
|
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)获取分拣货位明细
|
/// <summary>
|
/// (PDA)获取分拣货位明细
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <param name="locationCode"></param>
|
/// <returns></returns>
|
[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<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().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<DapperBLL<TN_WM_SORTING_RESULTEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
|
Log.Info("sortingLocations sortingResult", JsonConvert.SerializeObject(sortingResult));
|
//CN_C_IS_SN
|
|
List<AutoBomItemEntity> items = (BLLCreator.Create<TN_WMS_ITEMBLL>().GetItemList(sortingLocations.Select(x => x.CN_S_ITEM_CODE).ToList()) ?? new List<AutoBomItemEntity>());
|
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三生)获取分拣货位明细
|
/// <summary>
|
///(PDA三生)获取分拣货位明细
|
/// </summary>
|
/// <param name="tokenId"></param>
|
/// <param name="sortingNo"></param>
|
/// <param name="locationCode"></param>
|
/// <returns></returns>
|
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<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo,
|
CN_S_LOCATION_CODE = locationCode
|
});
|
Log.Info("sortingLocations sortingLocations", JsonConvert.SerializeObject(sortingLocations));
|
|
var sortingResult = BLLCreator.Create<DapperBLL<TN_WM_SORTING_RESULTEntity>>().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<AutoBomItemEntity> items = (BLLCreator.Create<TN_WMS_ITEMBLL>().GetItemList(sortingLocations.Select(x => x.CN_S_ITEM_CODE).ToList()) ?? new List<AutoBomItemEntity>());
|
|
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<TN_WM_B_UNIQUE_BARCODEEntity>().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<AuxiliaryEntity>(),
|
};
|
});
|
Log.Info("sortingLocations result", JsonConvert.SerializeObject(results));
|
return OperateResult.Succeed(null, results);
|
});
|
}
|
#endregion
|
|
#region (PDA)确认分拣
|
/// <summary>
|
/// (PDA)确认分拣
|
/// </summary>
|
/// <param name="sortingResult"></param>
|
/// <returns></returns>
|
[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<TN_WM_SORTING_RESULTEntity> sortingResult = JsonConvert.DeserializeObject<List<TN_WM_SORTING_RESULTEntity>>(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<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
var sortingResults = BLLCreator.Create<DapperBLL<TN_WM_SORTING_RESULTEntity>>().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<DapperBLL<TN_WM_SORTING_LISTEntity>>().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<DapperBLL<TN_WM_SORTING_LISTEntity>>().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<DapperBLL<TN_WM_SORTING_LISTEntity>>().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<TN_WM_SORTING_LISTBLL>().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<TN_WM_MOVE_MSTBLL>().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)扫描周转箱
|
/// <summary>
|
/// (PDA)扫描周转箱
|
/// </summary>
|
/// <param name="boxNo"></param>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult ScanBox(string boxNo, string sortingNo)
|
{
|
return ValidateToken(t =>
|
{
|
var trayInfoEntity = BLLCreator.Create<DapperBLL<TN_WM_B_TRAY_INFOEntity>>().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)合箱
|
/// <summary>
|
/// (PDA)合箱
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <param name="boxNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult MergeBox(string sortingNo, string boxNo)
|
{
|
return ValidateToken(t =>
|
{
|
var sortingEntity = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().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<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
var sortingResults = BLLCreator.Create<DapperBLL<TN_WM_SORTING_RESULTEntity>>().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<DapperBLL<TN_WM_SORTING_LISTEntity>>().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<TN_WM_SORTING_RESULTEntity> sortingResult = new List<TN_WM_SORTING_RESULTEntity>();
|
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<TN_WM_SORTING_LISTBLL>().MergeBox(sortingResult, sortingPicked, wavePicked, waveNo);
|
});
|
}
|
#endregion
|
|
#region (PDA汇聚)根据分拣单获取波次下所有发货通知单和分拣明细
|
/// <summary>
|
/// (PDA汇聚)根据分拣单获取波次下所有发货通知单和分拣明细
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <param name="locationCode"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult GetBJBBSortingData(string sortingNo, string locationCode)
|
{
|
return ValidateToken(t =>
|
{
|
var sortingEntity = BLLCreator.CreateDapper<TN_WM_SORTING_LISTEntity>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
if (sortingEntity == null)
|
return OperateResult.Error("未找到分拣单:" + sortingNo);
|
//当前分拣单当前货位
|
var currentSortingLocation = BLLCreator.CreateDapper<TN_WM_SORTING_LOCATIONEntity>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo,
|
CN_S_LOCATION_CODE = locationCode
|
});
|
//当前分拣单波次下所有出库单
|
var currentWaveOut = BLLCreator.Create<TN_WM_OUT_MSTBLL>().GetOutListByWave(sortingEntity.CN_S_FROM_NO);
|
//订单拣货数据
|
var orderSortingRels = BLLCreator.CreateDapper<TN_WM_ORDER_SORTING_RELEntity>().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<TN_WM_SORTING_RESULTEntity> sortingResult = JsonConvert.DeserializeObject<List<TN_WM_SORTING_RESULTEntity>>(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<TN_WM_SORTING_LOCATIONEntity>().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<TN_WM_SORTING_RESULTEntity>().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<TN_WM_SORTING_LISTEntity>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingResult[0].CN_S_SORTING_NO
|
});
|
|
#region 分拣单捡完了,判断波次有没有捡完
|
//分拣单捡完了,判断波次有没有捡完
|
if (sortingPicked)
|
{
|
var waveSortings = BLLCreator.CreateDapper<TN_WM_SORTING_LISTEntity>().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<TN_WM_B_AREA_QTYEntity> areaQtyList = new List<TN_WM_B_AREA_QTYEntity>();
|
//算法策略
|
List<string> lstStrate = BLLCreator.Create<TN_WM_B_STRATEGYBLL>().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<TN_WM_SORTING_DTLEntity>()
|
.GetList(new
|
{
|
CN_S_SORTING_NO = currentSorting.CN_S_SORTING_NO
|
});
|
currentSorting.SortingDtlList = currentSortingDtl;
|
|
areaQtyList = BLLCreator.CreateDapper<TN_WM_B_AREA_QTYEntity>().GetList(new
|
{
|
CN_S_ITEM_CODE = currentSortingDtl.Select(x => x.CN_S_ITEM_CODE).ToList()
|
});
|
//反批分库区分配量
|
Log.Info("确认分拣反批分库区分配量", "BatchesAreaQty");
|
var result = areaQtyList.BatchesAreaQty(new List<TN_WM_SORTING_LISTEntity>() { currentSorting }, lstStrate, true);
|
Log.Info("确认分拣反批分库区分配量结果", JsonConvert.SerializeObject(result));
|
if (!result.Success)
|
return result;
|
}
|
}
|
#endregion
|
|
#region 批分托盘物料关联,降分配量,删子表,解货位
|
//分拣结果的托盘物料关联数据
|
var trayItemMstList = BLLCreator.Create<TN_WM_SORTING_LISTBLL>().BatchesTrayItemByResult(sortingResult);
|
var currentTrayLocation = BLLCreator.CreateDapper<TN_WM_B_TRAY_LOCATIONEntity>().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<TN_WM_SORTING_LISTBLL>().SaveXJHB(savePickEntity);
|
});
|
}
|
|
#region (PDA汇聚)保存边拣边播
|
/// <summary>
|
/// (PDA汇聚)保存边拣边播
|
/// </summary>
|
/// <param name="saveData"></param>
|
/// <returns></returns>
|
public OperateResult SaveBJBB(dynamic saveData)
|
{
|
string tokenId = Util.ToString(saveData.tokenId);
|
return ValidateToken(tokenId, t =>
|
{
|
Log.Info("保存边拣边播SaveBJBB", JsonConvert.SerializeObject(saveData));
|
//分拣结果
|
List<TN_WM_SORTING_RESULTEntity> sortingResult = JsonConvert.DeserializeObject<List<TN_WM_SORTING_RESULTEntity>>(Util.ToString(saveData.SortingResult));
|
if (!sortingResult.Any())
|
return OperateResult.Error("分拣结果数据不可为空");
|
|
List<TN_WM_ORDER_SORTING_RELEntity> orderSortingRel = JsonConvert.DeserializeObject<List<TN_WM_ORDER_SORTING_RELEntity>>(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<TN_WM_SORTING_LOCATIONEntity>().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<TN_WM_SORTING_LISTEntity>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingResult[0].CN_S_SORTING_NO
|
});
|
|
#region 分拣单捡完了,判断波次有没有捡完
|
//分拣单捡完了,判断波次有没有捡完
|
if (sortingPicked)
|
{
|
var waveSortings = BLLCreator.CreateDapper<TN_WM_SORTING_LISTEntity>().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<TN_WM_B_AREA_QTYEntity> areaQtyList = new List<TN_WM_B_AREA_QTYEntity>();
|
//算法策略
|
List<string> lstStrate = BLLCreator.Create<TN_WM_B_STRATEGYBLL>().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<TN_WM_SORTING_DTLEntity>()
|
.GetList(new
|
{
|
CN_S_SORTING_NO = currentSorting.CN_S_SORTING_NO
|
});
|
currentSorting.SortingDtlList = currentSortingDtl;
|
|
areaQtyList = BLLCreator.CreateDapper<TN_WM_B_AREA_QTYEntity>().GetList(new
|
{
|
CN_S_ITEM_CODE = currentSortingDtl.Select(x => x.CN_S_ITEM_CODE).ToList()
|
});
|
//反批分库区分配量
|
Log.Info("确认分拣反批分库区分配量", "BatchesAreaQty");
|
var result = areaQtyList.BatchesAreaQty(new List<TN_WM_SORTING_LISTEntity>() { currentSorting }, lstStrate, true);
|
Log.Info("确认分拣反批分库区分配量结果", JsonConvert.SerializeObject(result));
|
if (!result.Success)
|
return result;
|
}
|
}
|
#endregion
|
|
#region 批分托盘物料关联,降分配量,删子表,解货位
|
//分拣结果的托盘物料关联数据
|
var trayItemMstList = BLLCreator.Create<TN_WM_SORTING_LISTBLL>().BatchesTrayItemByResult(sortingResult);
|
var currentTrayLocation = BLLCreator.CreateDapper<TN_WM_B_TRAY_LOCATIONEntity>().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<TN_WM_SORTING_LISTBLL>().SaveBJBB(savePickEntity);
|
});
|
}
|
#endregion
|
|
#region (PDA汇聚)分拣回和搬运
|
/// <summary>
|
/// (PDA汇聚)分拣回和搬运
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult Transport(string trayCode, string endArea, string sortingNo = "")
|
{
|
return ValidateToken(t =>
|
{
|
//找是否已经存在该托盘未执行完的任务
|
var existsTask = BLLCreator.CreateDapper<TN_WM_TASKEntity>().GetSingleEntity(new
|
{
|
CN_S_TRAY_CODE = trayCode,
|
CN_S_STATE = new List<string>() { Constants.TaskState_NoExecuted, Constants.TaskState_Executing },
|
});
|
if (existsTask != null)
|
return OperateResult.Error("托盘:" + trayCode + "存在未执行完的任务");
|
//当前托盘所在位置
|
var currentTrayLocation = BLLCreator.CreateDapper<TN_WM_B_TRAY_LOCATIONEntity>()
|
.GetSingleEntity(new
|
{
|
CN_S_TRAY_CODE = trayCode
|
});
|
|
//需要调作业区入库算法,算出货位给出库任务
|
var inAssignEntity = new InAssignEntity
|
{
|
objectType = InAssignEntity.ObjectType.托盘,
|
objectCode = trayCode,
|
lockLocation = false,
|
lstAreaPrior = new List<areaPriorClass>()
|
{
|
{
|
new areaPriorClass{
|
areaCode = endArea,
|
Prior = 1
|
}
|
}
|
}
|
};
|
Log.Info("调用算法InAssign参数", JsonConvert.SerializeObject(inAssignEntity));
|
InAssignResultEntity inAssignResultEntity = BLLCreator.Create<In_AlgorBLL>().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<TN_WM_SORTING_LISTBLL>().Transport(taskEntity);
|
});
|
}
|
#endregion
|
|
#region 获取分拣明细
|
/// <summary>
|
///获取分拣明细
|
/// </summary>
|
/// <param name="sortingEntity"></param>
|
/// <param name="user"></param>
|
/// <returns></returns>
|
private OperateResult GetSortingLocation(TN_WM_SORTING_LISTEntity sortingEntity, UserRuleEntity user)
|
{
|
try
|
{
|
List<TN_WM_SORTING_LOCATIONEntity> sortingLocationList = new List<TN_WM_SORTING_LOCATIONEntity>();
|
//初始化调用算法数据
|
List<itemQueryClass> 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<Out_AlgorBLL>().OutNew(new OutAlgorEnitty()
|
{
|
lstDevice = new List<Device>(),
|
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<TN_WMS_ITEMBLL>().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 分拣单列表
|
/// <summary>
|
/// 分拣单列表
|
/// </summary>
|
/// <param name="searchModel"></param>
|
/// <returns></returns>
|
[HttpPost]
|
public string GetSortingList(SearchModel searchModel)
|
{
|
OperateResult result = new OperateResult();
|
try
|
{
|
long total = 0;
|
DataTable dt = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().GetPagingData(new List<SearchWhere>() {
|
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 分拣数据
|
/// <summary>
|
/// 分拣数据
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult GetSortingDtl(string sortingNo)
|
{
|
try
|
{
|
var sortingDtl = BLLCreator.Create<DapperBLL<TN_WM_SORTING_DTLEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
return OperateResult.Succeed(null, sortingDtl);
|
}
|
catch (Exception ex)
|
{
|
return OperateResult.Error(ex.Message);
|
}
|
}
|
#endregion
|
|
#region 分拣明细
|
/// <summary>
|
/// 分拣明细
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult GetCurrentSortingLocation(string sortingNo)
|
{
|
try
|
{
|
var sortingDtl = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LOCATIONEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
return OperateResult.Succeed(null, sortingDtl);
|
}
|
catch (Exception ex)
|
{
|
return OperateResult.Error(ex.Message);
|
}
|
}
|
#endregion
|
|
#region 分拣结果
|
/// <summary>
|
/// 分拣结果
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult GetSortingResult(string sortingNo)
|
{
|
try
|
{
|
var sortingDtl = BLLCreator.Create<DapperBLL<TN_WM_SORTING_RESULTEntity>>().GetList(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
return OperateResult.Succeed(null, sortingDtl);
|
}
|
catch (Exception ex)
|
{
|
return OperateResult.Error(ex.Message);
|
}
|
}
|
#endregion
|
|
#region 查询分拣单实体
|
/// <summary>
|
/// 查询盘点单实体
|
/// </summary>
|
/// <param name="sortingNo">分拣单号</param>
|
/// <returns></returns>
|
/// <History>[Hanhe(dbs)] creater 2018/12/20</History>
|
public OperateResult GetSortingModel(string sortingNo)
|
{
|
try
|
{
|
return ValidateToken(t =>
|
{
|
TN_WM_SORTING_LISTEntity sorting = BLLCreator.Create<DapperBLL<TN_WM_SORTING_LISTEntity>>().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 订单拣货明细
|
/// <summary>
|
/// 订单拣货明细
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult GetOrderSortingRel(string opNo)
|
{
|
try
|
{
|
var sortingDtl = BLLCreator.Create<DapperBLL<TN_WM_ORDER_SORTING_RELEntity>>().GetList(new
|
{
|
CN_S_ORDER_NO = opNo
|
});
|
return OperateResult.Succeed(null, sortingDtl);
|
}
|
catch (Exception ex)
|
{
|
return OperateResult.Error(ex.Message);
|
}
|
}
|
#endregion
|
|
#region 根据出库单号获取订单拣货明细
|
/// <summary>
|
/// 根据出库单号获取订单拣货明细
|
/// </summary>
|
/// <param name="opNo"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult GetOrderSortingRelByOrderNo(string opNo)
|
{
|
try
|
{
|
var sortingDtl = BLLCreator.Create<DapperBLL<TN_WM_ORDER_SORTING_RELEntity>>().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端)先拣后播扫物料
|
/// <summary>
|
/// ScanItem
|
/// </summary>
|
/// <param name="postEntity"></param>
|
/// <returns></returns>
|
[HttpPost]
|
public OperateResult ScanItem(PostEntity postEntity)
|
{
|
return ValidateToken(postEntity.TokenId, t =>
|
{
|
var sortingResult = postEntity.GetPostData<TN_WM_SORTING_RESULTEntity>();
|
if (sortingResult == null)
|
return OperateResult.Error("分拣结果数据不可为空");
|
|
//当前拣的分拣明细
|
var sortingLocation = BLLCreator.CreateDapper<TN_WM_SORTING_LOCATIONEntity>().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<string> lstStrate = BLLCreator.Create<TN_WM_B_STRATEGYBLL>().GetStrateListByAreaOrStock("", "", Constants.Out)
|
.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
|
|
//分拣结果的托盘物料关联数据
|
var trayItemMstList = BLLCreator.CreateDapper<TN_WM_B_TRAY_ITEM_MSTEntity>().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<TN_WM_B_TRAY_ITEM_DTLEntity>();
|
//属于当前托盘,当前物料的分拣明细
|
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<TN_WM_B_TRAY_ITEM_DTLEntity>().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<TN_WM_B_TRAY_LOCATIONEntity>().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<TN_WM_SORTING_LISTEntity>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingResult.CN_S_SORTING_NO,
|
});
|
|
#endregion
|
|
SavePickEntity savePickEntity = new SavePickEntity
|
{
|
SortingResult = new List<TN_WM_SORTING_RESULTEntity>() { sortingResult },
|
TrayItemList = trayItemMstList,
|
TrayLocation = currentTrayLocation,
|
CurrentSorting = currentSorting
|
};
|
|
return BLLCreator.Create<TN_WM_SORTING_LISTBLL>().ScanItem(savePickEntity);
|
});
|
}
|
#endregion
|
|
#region (cs端)先拣后播扫周转箱
|
/// <summary>
|
/// (cs端)先拣后播扫周转箱
|
/// </summary>
|
/// <param name="sortingNo"></param>
|
/// <param name="boxNo"></param>
|
/// <param name="location"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public OperateResult ScanTurnoverBox(string sortingNo, string boxNo, string location)
|
{
|
return ValidateToken(t =>
|
{
|
var trayEntity = BLLCreator.CreateDapper<TN_WM_B_TRAY_INFOEntity>().GetSingleEntity(new
|
{
|
CN_S_TRAY_CODE = boxNo
|
});
|
if (trayEntity == null)
|
return OperateResult.Error("不存在周转箱:" + boxNo);
|
var sortingEntity = BLLCreator.CreateDapper<TN_WM_SORTING_LISTEntity>().GetSingleEntity(new
|
{
|
CN_S_SORTING_NO = sortingNo
|
});
|
if (sortingEntity == null)
|
return OperateResult.Error("未找到分拣单:" + sortingNo);
|
var fromOutMst = BLLCreator.CreateDapper<TN_WM_OUT_MSTEntity>().GetSingleEntity(new
|
{
|
CN_S_WAVE_CODE = sortingEntity.CN_S_FROM_NO
|
});
|
if (fromOutMst == null)
|
return OperateResult.Error("未找到分拣单波次所属出库单");
|
|
//当前波次所有分拣单
|
var currentWaveSortings = BLLCreator.CreateDapper<TN_WM_SORTING_LISTEntity>().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<TN_AB_B_STOCK_AREABLL>().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<areaPriorClass>() {
|
{
|
new areaPriorClass()
|
{
|
areaCode = jsArea.CN_S_AREA_CODE,
|
Prior = 1
|
}
|
}
|
},
|
logicAreaCode = Constants.FixedLogicArea_JS_FROM
|
};
|
//根据库区获取货位
|
InAssignResultEntity resultEntity = BLLCreator.Create<In_AlgorBLL>().InAssign(aEntity);
|
if (!resultEntity.Success)
|
return OperateResult.Error(resultEntity.Msg);
|
boxBit = resultEntity.locationCode;
|
}
|
//当前分拣单分拣明细
|
var currentSortingLocation = BLLCreator.CreateDapper<TN_WM_SORTING_LOCATIONEntity>().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<TN_WM_SORTING_RESULTEntity>().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
|
}
|
}
|