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