using MailKit.Search;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Org.BouncyCastle.Asn1.X509;
using Rhea.Common;
using SqlSugar;
using System;
using System.IO;
using Tiger.Business.WMS.Transaction;
using Tiger.IBusiness;
using Tiger.Model;
using Tiger.Model.Base;
using Tiger.Model.Entitys.MES.U9C;
using Tiger.Model.MES.Yada;
namespace Tiger.Business.WMS.Extensions
{
///
/// 工单发料扩展方法
///
public static class OutExtension
{
///
/// 根据发料类型,获取来源单据编码
///
///
///
public static string GetSourceCode(this BIZ_WMS_PREP.BIZ_TYPEs type)
{
switch (type)
{
case BIZ_WMS_PREP.BIZ_TYPEs.Others:
return nameof(BIZ_U9_MISC_OUT);
case BIZ_WMS_PREP.BIZ_TYPEs.WorkOrder:
return nameof(BIZ_MES_WO);
case BIZ_WMS_PREP.BIZ_TYPEs.Outsourcing:
return nameof(BIZ_U9_SCM_OUT);
case BIZ_WMS_PREP.BIZ_TYPEs.Transfer:
return nameof(BIZ_WMS_TRANSFER);
case BIZ_WMS_PREP.BIZ_TYPEs.Requisition:
default:
return "";
}
}
///
/// 根据发料类型,获取发料单据来源明细
///
///
///
///
public static List GetPickList(this BIZ_WMS_PREP.BIZ_TYPEs type, string orderNo)
{
// 查询单据明细
var pickList = new List();
switch (type)
{
case BIZ_WMS_PREP.BIZ_TYPEs.Others:
{
var dtls = Biz.Db.Queryable().Where(q => q.ORDER_NO == orderNo).ToList();
pickList = dtls.Select(q => q.GetPickItem()).ToList();
}
break;
case BIZ_WMS_PREP.BIZ_TYPEs.WorkOrder:
{
var dtls = Biz.DataSource["YadaU9C"].Client.Queryable().Where(q => q.MoDocNo == orderNo).ToList();
pickList = dtls.Select(q => q.GetPickItem()).ToList();
}
break;
case BIZ_WMS_PREP.BIZ_TYPEs.Outsourcing:
{
var dtls = Biz.DataSource["YadaU9C"].Client.Queryable().Where(q => q.PoDocNo == orderNo).ToList();
pickList = dtls.Select(q => q.GetPickItem()).ToList();
}
break;
case BIZ_WMS_PREP.BIZ_TYPEs.Transfer:
{
var dtls = Biz.Db.Queryable().Where(q => q.ORDER_NO == orderNo).ToList();
pickList = dtls.Select(q => q.GetPickItem()).ToList();
}
break;
case BIZ_WMS_PREP.BIZ_TYPEs.Requisition:
default:
break;
}
return pickList;
}
///
/// 实际需求数量计算方法
///
///
///
///
public static double GetActReqQty(this BIZ_WMS_PREP.BIZ_TYPEs type, BIZ_WMS_PREP_DTL dtl)
{
switch (type)
{
case BIZ_WMS_PREP.BIZ_TYPEs.Others:
case BIZ_WMS_PREP.BIZ_TYPEs.WorkOrder:
case BIZ_WMS_PREP.BIZ_TYPEs.Outsourcing:
case BIZ_WMS_PREP.BIZ_TYPEs.Transfer:
case BIZ_WMS_PREP.BIZ_TYPEs.Requisition:
default:
return dtl.QTY_REQ;
}
}
///
/// 根据发料类型,调用相应发料单据的ERP接口
///
///
///
///
///
public static async Task CommitToERP(this BIZ_WMS_PREP.BIZ_TYPEs type, Out_BIZ_WMS_PREP trans, BaseInput input)
{
switch (type)
{
case BIZ_WMS_PREP.BIZ_TYPEs.Others:
return await MiscShipApprove(trans, input);
case BIZ_WMS_PREP.BIZ_TYPEs.WorkOrder:
return await CreateIssueDoc(trans, input);
case BIZ_WMS_PREP.BIZ_TYPEs.Outsourcing:
return await CreatePMIssueDoc(trans, input);
case BIZ_WMS_PREP.BIZ_TYPEs.Transfer:
case BIZ_WMS_PREP.BIZ_TYPEs.Requisition:
default:
throw new NotImplementedException($"发料单据类型[{type.GetDesc()}]未实现ERP接口调用");
}
}
///
/// U9杂发单审核
///
///
///
///
private static async Task MiscShipApprove(Out_BIZ_WMS_PREP trans, BaseInput input)
{
var action = new ApiAction();
var dtls = trans.MainDB.Queryable().Where(q => q.ORDER_NO == trans.CurPREP.Order.ORDER_NO).ToList();
var noFinish = dtls.Where(q => q.QTY_PREP < BIZ_WMS_PREP.BIZ_TYPEs.Others.GetActReqQty(q));
if (noFinish.Any())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("备料任务[{0}]未能提交审核,未备料完成的行如下:{1}");
action.LocaleMsg = Biz.L("WMS.BIZ_WMS_PREP.MiscShipApprove.NoFinish", trans.CurPREP.Order.ORDER_NO, string.Join(",", noFinish.Select(q => q.ORDER_LINE)));
return action;
}
var iInput = new MiscShipApproveInput { MiscShipApproveParam = trans.CurPREP.Order.SourceOrders.Select(q => new MiscShipApproveParam() { Code = q.ORDER_NO }).ToList() };
var result = await DI.Resolve().MiscShipApprove(iInput);
if (!result.IsSuccessed)
{
action.IsSuccessed = false;
action.LocaleMsg = result.LocaleMsg;
return action;
}
var curBatch = trans.CurPREP.Order.CurBatch;
curBatch.STATUS = BIZ_WMS_PREP_BTH.STATUSs.Sended.GetValue();
curBatch.PREP_PERSON = trans.UserCode;
curBatch.FINISH_TIME = DateTime.Now;
curBatch.REQ_PERSON = trans.UserCode;
curBatch.DLVY_TIME = DateTime.Now;
foreach (var item in trans.CurPREP.Order.SourceDetails)
{
item.QTY_ACT_DLVY = item.QTY_ACT_REQ;
}
trans.CurPREP.Order.STATUS = BIZ_WMS_PREP.STATUSs.Sended.GetValue();
var orders = trans.MainDB.Queryable().Where(q => trans.CurPREP.Order.SourceOrders.Select(s => s.SOURCE_ORDER).Contains(q.ORDER_NO)).ToList();
foreach (var item in orders)
{
item.STATUS = BIZ_U9_MISC_OUT.STATUSs.Sended.GetValue();
item.PREP_PERSON = trans.UserCode;
item.FINISH_TIME = DateTime.Now;
item.REQ_PERSON = trans.UserCode;
item.DLVY_TIME = DateTime.Now;
}
//使用统一的事务DB对象
var db = trans.GetCommitDB();
var dbTran = db.UseTran(() =>
{
db.Updateable(trans.CurPREP.Order, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS }).ExecuteCommand();
db.Updateable(trans.CurPREP.Order.SourceDetails, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.QTY_ACT_DLVY }).ExecuteCommand();
db.Updateable(curBatch, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.PREP_PERSON, q.FINISH_TIME, q.REQ_PERSON, q.DLVY_TIME }).ExecuteCommand();
db.Updateable(orders, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.PREP_PERSON, q.FINISH_TIME, q.REQ_PERSON, q.DLVY_TIME }).ExecuteCommand();
});
if (dbTran.IsSuccess)
{
//action.LocaleMsg = Biz.L($"杂发单审核成功,单号如下:{0}");
action.LocaleMsg = Biz.L("WMS.BIZ_WMS_PREP.MiscShipApprove.Success", string.Join(",", trans.CurPREP.Order.SourceOrders.Select(s => s.SOURCE_ORDER)));
}
else
{
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
//抛出异常
throw dbTran.ErrorException;
}
return action;
}
///
/// U9创建生产领料单
///
///
///
///
private static async Task CreateIssueDoc(Out_BIZ_WMS_PREP trans, BaseInput input)
{
var action = new ApiAction();
var sns = trans.MainDB.Queryable().Where(q => q.ORDER_NO == trans.CurPREP.Order.ORDER_NO && q.ORDER_BATCH == trans.CurPREP.Order.CurBatch.BATCH.ToString()).ToList();
if (!sns.Any())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("创建生产领料单失败,备料任务[{0}]批次[{1}]未找到已下架的物料数据");
action.LocaleMsg = Biz.L("WMS.BIZ_WMS_PREP.CreateIssueDoc.NoSns", trans.CurPREP.Order.ORDER_NO, trans.CurPREP.Order.CurBatch.BATCH);
return action;
}
var wos = Biz.DataSource["YadaU9C"].Client.Queryable().Where(q => trans.CurPREP.Order.SourceOrders.Select(s => s.SOURCE_ORDER).Contains(q.DocNo)).ToList();
var temp = sns.GroupBy(q => new { q.ITEM_CODE, q.UNIT, q.WH_CODE, q.LOCATION_CODE })
.Select(g => new PickListDTOs
{
Item = new() { Code = g.Key.ITEM_CODE },
IssueWh = new() { Code = g.Key.WH_CODE },
IssueBin = new() { code = g.Key.LOCATION_CODE },
IssueQty = g.Sum(q => q.QTY),
IssuedQty = g.Sum(q => q.QTY),
IssueUOM = new() { Code = g.Key.UNIT.IsNullOrEmpty("PCS") },
Lot = new() { code = g.Max(q => q.LOTNO) },
}).ToList();
var pickList = new List();
var prepSrcList = new List();
foreach (var dtl in temp)
{
var remain = dtl.IssueQty;
var srcDtls = trans.CurPREP.Order.SourceDetails.Where(q => q.ITEM_CODE == dtl.Item.Code).ToList();
var count = srcDtls.Count;
foreach (var src in srcDtls)
{
var actQty = src.QTY_ACT_REQ - src.QTY_ACT_DLVY;
if (remain > 0 && actQty > 0)
{
//实际需求大于剩余待分配数量,或者当前是最后一个来源明细行,则分配剩余数量
var dlvy = (actQty > remain || count == 1) ? remain : actQty;
src.QTY_ACT_DLVY += dlvy;
prepSrcList.Add(src);
var pick = new PickListDTOs
{
Item = dtl.Item,
IssueWh = dtl.IssueWh,
IssueBin = dtl.IssueBin,
IssueQty = dlvy,
IssuedQty = dlvy,
IssueUOM = dtl.IssueUOM,
MOPickList = src.SOURCE_ID.ToInt64(),
Lot = dtl.Lot,
};
pickList.Add(pick);
remain -= pick.IssueQty;
}
count--;
}
}
var iInput = new CreateProdMaterialReqInput {CreateProdMaterialReqParam = new() { new() {
MOs = trans.CurPREP.Order.SourceOrders.Select(q => new MOs { Code = q.SOURCE_ORDER }).ToList(),
PickListDTOs = pickList,
BusinessType = wos.First().BusinessType,
}}};
var result = await DI.Resolve().CreateProdMaterialReq(iInput);
if (!result.IsSuccessed)
{
action.IsSuccessed = false;
action.LocaleMsg = result.LocaleMsg;
return action;
}
var curBatch = trans.CurPREP.Order.CurBatch;
curBatch.STATUS = BIZ_WMS_PREP_BTH.STATUSs.Sended.GetValue();
curBatch.PREP_PERSON = trans.UserCode;
curBatch.FINISH_TIME = DateTime.Now;
curBatch.REQ_ID = string.Join(",", result.Data.Select(q => q.m_iD));
curBatch.REQ_ORDER = string.Join(",", result.Data.Select(q => q.m_code));
curBatch.REQ_PERSON = trans.UserCode;
curBatch.DLVY_TIME = DateTime.Now;
var dtls = trans.MainDB.Queryable().Where(q => q.ORDER_NO == trans.CurPREP.Order.ORDER_NO).ToList();
var noFinish = dtls.Where(q => q.QTY_PREP < BIZ_WMS_PREP.BIZ_TYPEs.Others.GetActReqQty(q));
if (!noFinish.Any())
{
trans.CurPREP.Order.STATUS = BIZ_WMS_PREP.STATUSs.Sended.GetValue();
}
//使用统一的事务DB对象
var db = trans.GetCommitDB();
var dbTran = db.UseTran(() =>
{
db.Updateable(trans.CurPREP.Order, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS }).ExecuteCommand();
db.Updateable(prepSrcList, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.QTY_ACT_DLVY }).ExecuteCommand();
db.Updateable(curBatch, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.PREP_PERSON, q.FINISH_TIME, q.REQ_ID, q.REQ_ORDER, q.REQ_PERSON, q.DLVY_TIME }).ExecuteCommand();
});
if (dbTran.IsSuccess)
{
//action.LocaleMsg = Biz.L($"创建生产领料单[{0}]成功,来源单号如下:{1}");
action.LocaleMsg = Biz.L("WMS.BIZ_WMS_PREP.CreateIssueDoc.Success", curBatch.REQ_ORDER, string.Join(",", trans.CurPREP.Order.SourceOrders.Select(s => s.SOURCE_ORDER)));
}
else
{
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
//抛出异常
throw dbTran.ErrorException;
}
return action;
}
///
/// U9创建委外生产领料单
///
///
///
///
private static async Task CreatePMIssueDoc(Out_BIZ_WMS_PREP trans, BaseInput input)
{
var action = new ApiAction();
var sns = trans.MainDB.Queryable().Where(q => q.ORDER_NO == trans.CurPREP.Order.ORDER_NO && q.ORDER_BATCH == trans.CurPREP.Order.CurBatch.BATCH.ToString()).ToList();
if (!sns.Any())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("创建委外生产领料单失败,备料任务[{0}]批次[{1}]未找到已下架的物料数据");
action.LocaleMsg = Biz.L("WMS.BIZ_WMS_PREP.CreatePMIssueDoc.NoSns", trans.CurPREP.Order.ORDER_NO, trans.CurPREP.Order.CurBatch.BATCH);
return action;
}
var temp = sns.GroupBy(q => new { q.ITEM_CODE, q.UNIT, q.WH_CODE, q.LOCATION_CODE })
.Select(g => new PickListDTOs2
{
Item = new() { Code = g.Key.ITEM_CODE },
IssueWh = new() { Code = g.Key.WH_CODE },
IssueBin = new() { code = g.Key.LOCATION_CODE },
IssueQty = g.Sum(q => q.QTY),
IssuedQty = g.Sum(q => q.QTY),
IssueUOM = new() { Code = g.Key.UNIT.IsNullOrEmpty("PCS") },
Lot = new() { code = g.Max(q => q.LOTNO) },
}).ToList();
var pickList = new List();
var prepSrcList = new List();
foreach (var dtl in temp)
{
var remain = dtl.IssueQty;
var srcDtls = trans.CurPREP.Order.SourceDetails.Where(q => q.ITEM_CODE == dtl.Item.Code).ToList();
var count = srcDtls.Count;
foreach (var src in srcDtls)
{
var actQty = src.QTY_ACT_REQ - src.QTY_ACT_DLVY;
if (remain > 0 && actQty > 0)
{
//实际需求大于剩余待分配数量,或者当前是最后一个来源明细行,则分配剩余数量
var dlvy = (actQty > remain || count == 1) ? remain : actQty;
src.QTY_ACT_DLVY += dlvy;
prepSrcList.Add(src);
var pick = new PickListDTOs2
{
Item = dtl.Item,
IssueWh = dtl.IssueWh,
IssueBin = dtl.IssueBin,
IssueQty = dlvy,
IssuedQty = dlvy,
IssueUOM = dtl.IssueUOM,
SCMOPickList = src.SOURCE_ID.ToInt64(),
Lot = dtl.Lot,
};
pickList.Add(pick);
remain -= pick.IssueQty;
}
count--;
}
}
var iInput = new CreateOutProdMaterialReqInput { CreateOutProdMaterialReqParam = new() { new() {
POLine = trans.CurPREP.Order.SourceOrders.Select(q => new POLine { Code = q.SOURCE_ORDER }).ToList(),
BusinessDate = DateTime.Now.ToString("yyyy-MM-dd"),
PickListDTOs = pickList,
BusinessCreatedOn = DateTime.Now.ToString("yyyy-MM-dd"),
}}};
var result = await DI.Resolve().CreateOutProdMaterialReq(iInput);
if (!result.IsSuccessed)
{
action.IsSuccessed = false;
action.LocaleMsg = result.LocaleMsg;
return action;
}
var curBatch = trans.CurPREP.Order.CurBatch;
curBatch.STATUS = BIZ_WMS_PREP_BTH.STATUSs.Sended.GetValue();
curBatch.PREP_PERSON = trans.UserCode;
curBatch.FINISH_TIME = DateTime.Now;
curBatch.REQ_ID = string.Join(",", result.Data.Select(q => q.m_iD));
curBatch.REQ_ORDER = string.Join(",", result.Data.Select(q => q.m_code));
curBatch.REQ_PERSON = trans.UserCode;
curBatch.DLVY_TIME = DateTime.Now;
var dtls = trans.MainDB.Queryable().Where(q => q.ORDER_NO == trans.CurPREP.Order.ORDER_NO).ToList();
var noFinish = dtls.Where(q => q.QTY_PREP < BIZ_WMS_PREP.BIZ_TYPEs.Others.GetActReqQty(q));
var orders = new List();
if (!noFinish.Any())
{
trans.CurPREP.Order.STATUS = BIZ_WMS_PREP.STATUSs.Sended.GetValue();
orders = trans.MainDB.Queryable().Where(q => trans.CurPREP.Order.SourceOrders.Select(s => s.SOURCE_ORDER).Contains(q.ORDER_NO)).ToList();
foreach (var item in orders)
{
item.STATUS = BIZ_U9_SCM_OUT.STATUSs.Sended.GetValue();
item.PREP_PERSON = trans.UserCode;
item.FINISH_TIME = DateTime.Now;
item.REQ_PERSON = trans.UserCode;
item.DLVY_TIME = DateTime.Now;
}
}
//使用统一的事务DB对象
var db = trans.GetCommitDB();
var dbTran = db.UseTran(() =>
{
db.Updateable(trans.CurPREP.Order, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS }).ExecuteCommand();
db.Updateable(prepSrcList, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.QTY_ACT_DLVY }).ExecuteCommand();
db.Updateable(curBatch, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.PREP_PERSON, q.FINISH_TIME, q.REQ_ID, q.REQ_ORDER, q.REQ_PERSON, q.DLVY_TIME }).ExecuteCommand();
if (orders.Any())
{
db.Updateable(orders, trans.UserCode).UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.STATUS, q.PREP_PERSON, q.FINISH_TIME, q.REQ_PERSON, q.DLVY_TIME }).ExecuteCommand();
}
});
if (dbTran.IsSuccess)
{
//action.LocaleMsg = Biz.L($"创建委外生产领料单[{0}]成功,来源单号如下:{1}");
action.LocaleMsg = Biz.L("WMS.BIZ_WMS_PREP.CreatePMIssueDoc.Success", curBatch.REQ_ORDER, string.Join(",", trans.CurPREP.Order.SourceOrders.Select(s => s.SOURCE_ORDER)));
}
else
{
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
//抛出异常
throw dbTran.ErrorException;
}
return action;
}
}//endClass
}