shgx_tz_mom/ZR.Service/mes/wms/WmOutOrderService.cs
2024-08-05 17:26:08 +08:00

953 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Data;
using System.Linq;
using Infrastructure.Attribute;
using Mapster;
using SqlSugar;
using ZR.Model;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
using ZR.Repository;
using ZR.Service.mes.wms.IService;
using ZR.Service.Utils;
namespace ZR.Service.mes.wms
{
/// <summary>
/// 出货单(物料+客户Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(IWmOutOrderService), ServiceLifetime = LifeTime.Transient)]
public class WmOutOrderService : BaseService<WmOutOrder>, IWmOutOrderService
{
private NLog.Logger logger;
public WmOutOrderService()
{
logger = NLog.LogManager.GetCurrentClassLogger();
}
/// <summary>
/// 查询出货单(物料+客户)列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<WmOutOrderDto> GetList(WmOutOrderQueryDto parm)
{
var predicate = Expressionable
.Create<WmOutOrder>()
.AndIF(
!string.IsNullOrEmpty(parm.ShipmentNum),
it => it.ShipmentNum.Contains(parm.ShipmentNum)
)
.AndIF(
!string.IsNullOrEmpty(parm.CustomNo),
it => it.CustomNo.Contains(parm.CustomNo)
)
.AndIF(parm.Type > 0, it => it.Type == parm.Type)
.AndIF(parm.Status > -1, it => it.Status == parm.Status)
.AndIF(parm.Year > 0, it => it.Year == parm.Year)
.AndIF(parm.Week > 0, it => it.Year == parm.Week)
.AndIF(parm.Date > 0, it => it.Year == parm.Date);
var response = Queryable()
.Where(predicate.ToExpression())
.OrderByDescending(it => it.CreatedTime)
.ToPage<WmOutOrder, WmOutOrderDto>(parm);
return response;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="ShipmentNum"></param>
/// <returns></returns>
public WmOutOrder_material_num GetInfo(string ShipmentNum)
{
WmOutOrder WmOutOrderList = Context
.Queryable<WmOutOrder>()
.Where(it => it.ShipmentNum == ShipmentNum)
.First();
WmOutOrder_material_num wmOutOrderItem = null;
if (WmOutOrderList != null)
{
wmOutOrderItem = WmOutOrderList.Adapt<WmOutOrder_material_num>();
List<WmMaterialOutorder> moList = Context
.Queryable<WmMaterialOutorder>()
.Where(it => it.FkOutorderId == WmOutOrderList.ShipmentNum)
.ToList();
if (moList != null && moList.Count > 0)
{
List<WmMaterialQuery_stockQuantityDto2> Material_stock =
new List<WmMaterialQuery_stockQuantityDto2>();
foreach (var moItem in moList)
{
WmMaterial material = Context
.Queryable<WmMaterial>()
.Where(it => it.Id == moItem.FkMaterialId)
.First();
if (material != null)
{
WmMaterialQuery_stockQuantityDto2 dto2 =
material.Adapt<WmMaterialQuery_stockQuantityDto2>();
dto2.requireOutNum = moItem.OuthouseNum;
Material_stock.Add(dto2);
}
}
wmOutOrderItem.MaterialList = Material_stock;
}
}
return wmOutOrderItem;
}
/// <summary>
/// 添加出货单(物料+客户)
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public WmOutOrder AddWmOutOrder(WmOutOrder_materialDto model)
{
try
{
string today_id = "EG" + DateTime.Now.ToString("yyMMdd");
string last_outorder_ShipmentNum = Context
.Queryable<WmOutOrder>()
.Where(it => it.ShipmentNum.StartsWith(today_id))
.Max(it => it.ShipmentNum);
if (string.IsNullOrEmpty(last_outorder_ShipmentNum))
{
model.ShipmentNum = today_id + "001";
}
else
{
int flow =
int.Parse(
last_outorder_ShipmentNum.Substring(
last_outorder_ShipmentNum.Length - 3,
3
)
) + 1;
model.ShipmentNum = today_id + flow.ToString("000");
}
WmOutOrder wmOutOrder = model.Adapt<WmOutOrder>();
// 关联表也要新增
if (model.MaterialList != null)
{
if (model.MaterialList.Count > 0)
{
List<WmMaterialOutorder> materialOutorderList =
new List<WmMaterialOutorder>();
foreach (var item in model.MaterialList)
{
WmMaterialOutorder materialOutorder = new WmMaterialOutorder();
materialOutorder.FkMaterialId = item.Id;
materialOutorder.FkOutorderId = model.ShipmentNum;
materialOutorder.OuthouseNum = item.requireOutNum;
materialOutorder.CreatedBy = model.CreatedBy;
materialOutorder.CreatedTime = DateTime.Now;
materialOutorderList.Add(materialOutorder);
}
;
int result = Context.Insertable(materialOutorderList).ExecuteCommand();
}
}
return Context.Insertable(wmOutOrder).ExecuteReturnEntity();
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// 删除出货单关联的物料出货单
/// </summary>
/// <param name="primarys"></param>
/// <returns></returns>
public int Delete_fk_matrial(string[] primarys)
{
if (primarys.Count() > 0)
{
for (int i = 0; i < primarys.Length; i++)
{
Context
.Deleteable<WmMaterialOutorder>()
.Where(it => it.FkOutorderId == primarys[i])
.ExecuteCommand();
}
}
return 1;
}
/// <summary>
/// 修改出货单(物料+客户)
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateWmOutOrder(WmOutOrder model)
{
//var response = Update(w => w.ShipmentNum == model.ShipmentNum, it => new WmOutOrder()
//{
// CustomNo = model.CustomNo,
// CustomName = model.CustomName,
// CustomAddress = model.CustomAddress,
// Remarks = model.Remarks,
// Type = model.Type,
// Status = model.Status,
// Year = model.Year,
// Week = model.Week,
// Date = model.Date,
// CreatedBy = model.CreatedBy,
// CreatedTime = model.CreatedTime,
// UpdatedBy = model.UpdatedBy,
// UpdatedTime = model.UpdatedTime,
//});
//return response;
return Update(model, true);
}
/// <summary>
/// 获取用户信息
/// </summary>
/// <returns></returns>
public List<WmCustom> GetCustominfo()
{
return Context.Queryable<WmCustom>().ToList();
}
/// <summary>
/// 查询物料记录表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public (List<WmMaterialQuery_stockQuantityDto>, int) GetmaterialList(
WmMaterialQueryDto parm
)
{
int total = 0;
var predicate = Expressionable
.Create<WmMaterial>()
.AndIF(parm.Partnumber != null, it => it.Partnumber.Contains(parm.Partnumber))
.AndIF(
parm.U8InventoryCode != null,
it => it.U8InventoryCode.Contains(parm.U8InventoryCode)
)
.AndIF(parm.ProductName != null, it => it.ProductName.Contains(parm.ProductName))
.AndIF(parm.Color != null, it => it.Color.Contains(parm.Color))
.AndIF(
parm.Specification != null,
it => it.Specification.Contains(parm.Specification)
)
.AndIF(parm.Description != null, it => it.Description.Contains(parm.Description))
.AndIF(
parm.Search1 != null,
it => it.Search1.Contains(parm.Search1) || it.Search2.Contains(parm.Search1)
)
.AndIF(parm.Status > -1, it => it.Status == parm.Status);
List<WmMaterial> materialList = Context
.Queryable<WmMaterial>()
.Where(predicate.ToExpression())
.OrderByDescending(it => it.CreatedTime)
.ToPageList(parm.PageNum, parm.PageSize, ref total);
List<WmMaterialQuery_stockQuantityDto> material_stockQuantity_list =
new List<WmMaterialQuery_stockQuantityDto>();
if (materialList.Count > 0)
{
foreach (WmMaterial item in materialList)
{
WmMaterialQuery_stockQuantityDto wmMaterialQuery_Stock_item =
item.Adapt<WmMaterialQuery_stockQuantityDto>();
int material_num = 0;
List<WmGoodsNowProduction> productioList = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.Partnumber == item.Partnumber)
.ToList();
if (productioList.Count > 0)
{
foreach (var product in productioList)
{
int num = product.GoodsNumAction ?? 0;
material_num += num;
}
}
wmMaterialQuery_Stock_item.stockQuantity = material_num;
material_stockQuantity_list.Add(wmMaterialQuery_Stock_item);
}
}
return (material_stockQuantity_list, total);
}
/// <summary>
/// 查询出货单的物料信息
/// </summary>
/// <param name="shipment_num"></param>
/// <returns></returns>
public List<WmMaterialQuery_print> Queryoutoder_matrials(string shipment_num)
{
List<WmMaterialQuery_print> stockList = Context
.Queryable<WmMaterialOutorder>()
.LeftJoin<WmMaterial>((mo, m) => mo.FkMaterialId == m.Id)
.Where(mo => mo.FkOutorderId == shipment_num)
.Select(
(mo, m) =>
new WmMaterialQuery_print()
{
//物料号
Partnumber = m.Partnumber,
// 描述
ProductName = m.ProductName,
//需求零件数
RequireOutNum = mo.OuthouseNum
}
)
.ToList();
if (stockList != null && stockList.Count > 0)
{
foreach (var stock in stockList)
{
//库存箱数
stock.PackageNum = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.Partnumber == stock.Partnumber)
.Count();
//库存零件数
int? num = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.Partnumber == stock.Partnumber)
.Sum(it => it.GoodsNumAction);
stock.ItemNum = num ?? 0;
// 需求箱数
List<WmGoodsNowProduction> list = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.Partnumber == stock.Partnumber)
.OrderByDescending(it => it.PackageCodeClient)
.ToList();
int sum = 0;
foreach (var item in list)
{
sum = sum + item.GoodsNumLogic ?? 0;
if (sum >= stock.RequireOutNum)
{
stock.Require_pack_num = list.IndexOf(item) + 1;
break;
}
}
}
}
return stockList;
}
/// <summary>
/// 生成出库单的出货计划
/// </summary>
/// <param name="shipment_num">出货单号</param>
/// <returns></returns>
public List<WmOutOrderPlan> Generate_outorderplan(string shipment_num)
{
// 最终结果
List<WmOutOrderPlan> planList = new List<WmOutOrderPlan>();
// 获取当前出货单下的物料信息
List<WmMaterialQuery_print> materialQuery_Prints = this.Queryoutoder_matrials(
shipment_num
);
if (materialQuery_Prints != null && materialQuery_Prints.Count > 0)
{
// 物料解析
foreach (var material in materialQuery_Prints)
{
//1. 物料需求量
int require_num = material.RequireOutNum;
// 物料号
string partnumber = material.Partnumber;
// 该物料下 ,现有货物列表,零件号相同,根据批次号从小到大排序
List<WmGoodsNowProduction> wmGoodsNowsList = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.Partnumber == partnumber)
.Where(it => it.LocationCode != "Z1-01")
.OrderBy(it => it.PackageCodeClient)
.ToList();
// 判断要出多少批次的货
List<WmOutOrderPlan> wmOutOrderPlans = new List<WmOutOrderPlan>();
// 当前累计批次货物总数
int accumulation_num = 0;
foreach (var witem in wmGoodsNowsList)
{
if (require_num >= accumulation_num)
{
WmOutOrderPlan orderPlan = new WmOutOrderPlan();
orderPlan.FkOutOrderId = shipment_num;
orderPlan.Patchcode = witem.PackageCodeClient;
orderPlan.Patchcode_short = witem.PackageCodeClient.Split("_")[0];
orderPlan.MaterialCode = witem.Partnumber;
orderPlan.WarehouseCode = witem.LocationCode;
orderPlan.PackageNum = material.PackageNum;
// 获得批次的总零件数
orderPlan.PartnumberNum = witem.GoodsNumLogic;
orderPlan.RequireNum = require_num;
orderPlan.ReceivedPackNum = 0;
orderPlan.Patchtime = Resolution_bath(witem.PackageCodeOriginal);
wmOutOrderPlans.Add(orderPlan);
// 实际值计算
accumulation_num = accumulation_num + witem.GoodsNumLogic ?? 0;
}
}
// 进行聚合
if (wmOutOrderPlans.Count > 0)
{
// 根据批次号下划线前进行聚合
List<WmOutOrderPlan> material_plan_item = wmOutOrderPlans
.GroupBy(it => it.Patchcode_short)
.Select(g => new WmOutOrderPlan
{
FkOutOrderId = g.Max(p => p.FkOutOrderId),
Patchcode = g.Max(p => p.Patchcode_short),
Patchcode_short = g.Max(p => p.Patchcode_short),
WarehouseCode = g.Max(p => p.WarehouseCode),
MaterialCode = g.Max(p => p.MaterialCode),
PackageNum = g.Count(),
PartnumberNum = g.Sum(p => p.PartnumberNum),
RequireNum = g.Max(p => p.RequireNum),
ReceivedPackNum = 0,
Patchtime = g.Max(p => p.Patchtime),
})
.ToList();
planList = planList.Concat(material_plan_item).ToList();
}
}
}
// 添加序号
int count = 1;
foreach (var witem in planList)
{
witem.Id = count;
witem.Outorder = count;
count++;
witem.Inventory_pack_num = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.PackageCodeClient.Contains(witem.Patchcode))
.Count();
witem.Inventory_num =
Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.PackageCodeClient.Contains(witem.Patchcode))
.Sum(it => it.GoodsNumLogic) ?? 0;
}
return planList;
}
/// <summary>
/// 根据出库单号与货物批次号,向出库记录添加数据,并且成品库表数据删除
/// </summary>
/// <param name="doMaterialOut"></param>
/// <returns></returns>
public (int, int) DoMaterialOut(WmDoMaterialOut_Dto doMaterialOut, string Createby)
{
try
{
Context.Ado.BeginTran();
List<string> deleteList = new();
List<WmGoodsOutRecord> insertList = new();
string shipnumber = doMaterialOut.ShipmentNum;
if (doMaterialOut.PatchCode == null || doMaterialOut.PatchCode.Length == 0)
{
Context.Ado.RollbackTran();
throw new Exception("批次号列表为空,不可出库" + doMaterialOut.PatchCode);
}
// 统计记录
List<string> partnumbers = new();
int totalPackage = 0;
int totalPartnumber = 0;
List<string> packageCodeRemark = new();
foreach (var item in doMaterialOut.PatchCode)
{
Context
.Updateable<WmOutOrderPlan>()
.SetColumns(it => it.ReceivedPackNum == it.ReceivedPackNum + 1)
.Where(it => it.FkOutOrderId == shipnumber)
.Where(it => it.Patchcode == item)
.ExecuteCommand();
WmGoodsOutRecord record =
new() { Id = SnowFlakeSingle.Instance.NextId().ToString() };
WmGoodsNowProduction nowProduction = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.PackageCodeClient == item)
.First();
if (nowProduction == null)
{
Context.Ado.RollbackTran();
throw new Exception("成品仓库未查到此货物,无法出库!" + item);
}
record.FkNowProductionId = nowProduction.Id;
record.PackageCodeClient = nowProduction.PackageCodeClient;
record.PackageCode = nowProduction.PackageCode;
record.PackageCodeOriginal = nowProduction.PackageCodeOriginal;
record.LocationCode = nowProduction.LocationCode;
record.Partnumber = nowProduction.Partnumber;
record.GoodsNumLogic = nowProduction.GoodsNumLogic;
record.GoodsNumAction = nowProduction.GoodsNumAction;
record.EntryWarehouseTime = nowProduction.EntryWarehouseTime;
record.OutTime = DateTime.Now;
record.CreatedTime = DateTime.Now;
record.CreatedBy = Createby;
record.FkOutOrderId = shipnumber;
insertList.Add(record);
deleteList.Add(nowProduction.Id);
// 记录统计
totalPackage++;
if (!partnumbers.Contains(nowProduction.Partnumber))
{
partnumbers.Add(nowProduction.Partnumber);
}
totalPartnumber += nowProduction.GoodsNumAction ?? 0;
packageCodeRemark.Add(nowProduction.PackageCodeClient);
}
int sum_insert = Context.Insertable(insertList).ExecuteCommand();
int sum_delete = Context
.Deleteable<WmGoodsNowProduction>()
.In(deleteList.ToArray())
.ExecuteCommand();
if (sum_insert != sum_delete)
{
Context.Ado.RollbackTran();
throw new Exception(
"出库操作出现异常!失败原因记录不一致:添加数据" + sum_insert + "删除数据:" + sum_delete
);
}
packageCodeRemark.Sort();
// 插入记录
WmGoodsRecord wmGoodsRecord =
new()
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
FkInventoryId = SnowFlakeSingle.Instance.NextId().ToString(),
Code = "PDA_OUT",
Partnumber = string.Join(',', partnumbers),
BlankNum = "",
ChangeType = 2,
ChangeQuantity = totalPartnumber,
ActionTime = DateTime.Now,
Status = 1,
Remark =
"PDA出库"
+ "\n出库单:"
+ shipnumber
+ "\n总箱数:"
+ totalPackage
+ "\n总零件数:"
+ totalPartnumber
+ "\n涉及批次号:\n"
+ string.Join(',', packageCodeRemark),
CreatedBy = Createby,
CreatedTime = DateTime.Now,
};
int recordNum = Context.Insertable(wmGoodsRecord).ExecuteCommand();
if (recordNum == 0)
{
Context.Ado.RollbackTran();
throw new Exception("记录插入失败");
}
Context.Ado.CommitTran();
return (sum_delete, sum_insert);
}
catch (Exception e)
{
Context.Ado.RollbackTran();
throw new Exception(e.Message);
}
}
public bool OverOutorderplan(string shipment_num)
{
int reult = Context
.Updateable<WmOutOrder>()
.Where(it => it.ShipmentNum == shipment_num)
.SetColumns(it => it.Type == 2)
.ExecuteCommand();
if (reult > 0)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 传入批次号 解析出时间 BNW240318007_105
/// </summary>
/// <param name="production_packcode">原始编码</param>
/// <returns></returns>
private string Resolution_bath(string production_packcode)
{
MaterialUtils materialToos = new MaterialUtils();
ResultionPackageCodeDto resultionPackage = materialToos.ResolutionPackage(
production_packcode
);
if (resultionPackage == null)
{
return "时间解析异常";
}
return resultionPackage.ProductionTime;
}
/// <summary>
/// 8.5 PDA端 获取出库单的持久化存储出库计划并计算计划批次当前已出库数量
/// </summary>
/// <param name="shipment_num">出库单号</param>
/// <returns></returns>
public List<WmOutPlanAndGoodsOutProductionNumDto> GetOutOrderPlanAndOutProductionNum(
string shipment_num,
string partnumber
)
{
try
{
List<WmOutPlanAndGoodsOutProductionNumDto> result = new();
// 当前工单出库计划
var exp = Expressionable
.Create<WmOutOrderPlan>()
.And(it => it.FkOutOrderId == shipment_num)
.AndIF(!string.IsNullOrEmpty(partnumber), it => it.MaterialCode == partnumber)
.ToExpression();
List<WmOutOrderPlan> wmOutOrderPlan = Context
.Queryable<WmOutOrderPlan>()
.Where(exp)
.OrderBy(it => it.Outorder)
.ToList();
// 查询每个计划具体出库数据
foreach (WmOutOrderPlan item in wmOutOrderPlan)
{
// 库存记录
List<WmGoodsNowProduction> nowProductionList = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.PackageCodeClient.Contains(item.Patchcode))
.ToList();
int nowPackageNum = 0;
int nowPartnumberNum = 0;
foreach (WmGoodsNowProduction outItem in nowProductionList)
{
nowPackageNum += 1;
nowPartnumberNum += (int)outItem.GoodsNumAction;
}
// 出库记录
List<WmGoodsOutRecord> outPackageList = Context
.Queryable<WmGoodsOutRecord>()
.Where(it => it.PackageCodeClient.Contains(item.Patchcode))
.Where(it => it.FkOutOrderId == shipment_num)
.ToList();
int outPackageNum = 0;
int outPartnumberNum = 0;
foreach (WmGoodsOutRecord outItem in outPackageList)
{
outPackageNum += 1;
outPartnumberNum += (int)outItem.GoodsNumAction;
}
WmMaterial material = Context
.Queryable<WmMaterial>()
.Where(it => it.Partnumber.Contains(item.MaterialCode))
.First();
WmOutPlanAndGoodsOutProductionNumDto newItem =
new()
{
OutOrder = (int)item.Outorder,
PackageCode = item.Patchcode,
Partnumber = item.MaterialCode,
Description = !string.IsNullOrEmpty(material.Description)
? material.Description
: material.ProductName,
WarehouseCode = item.WarehouseCode,
RequireNum = (int)item.RequireNum,
PackageNum = (int)nowPackageNum,
PartnumberNum = (int)nowPartnumberNum,
PackagePlanNum = (int)item.PackageNum,
PartnumberPlanNum = (int)item.PartnumberNum,
OutPackageNum = outPackageNum,
OutPartnumberNum = outPartnumberNum,
IsError = (nowPartnumberNum + outPartnumberNum) != item.PartnumberNum,
IsOver = outPartnumberNum > item.PartnumberNum
};
result.Add(newItem);
}
return result;
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// 检查是否可出库
/// </summary>
/// <param name="production_packcode"></param>
/// <param name="shipment_num"></param>
/// <returns></returns>
public string CheckProductionOut(
string parnumber,
string production_packcode,
string shipment_num
)
{
try
{
if (shipment_num == "" || production_packcode == "")
{
return "传入数据为空!请检查参数";
}
// 1.判断工单是否处于已完成状态
bool isOutOrderCanUse = Context
.Queryable<WmOutOrder>()
.Where(it => it.ShipmentNum == shipment_num)
.Where(it => it.Type == 1)
.Any();
if (!isOutOrderCanUse)
{
return "出库单已完成或已弃用!请检查出库单";
}
MaterialUtils materialToos = new MaterialUtils();
// 2.解析标签编码
ResultionPackageCodeDto resultionPackage = materialToos.ResolutionPackage(
production_packcode
);
if (resultionPackage == null)
{
return "标签解析异常!请检查标签";
}
//3 判断箱子是否配置零件号
if (parnumber != resultionPackage.PartNumner)
{
return "此箱子不是选择的物料号";
}
// 3.1判断是否已入库
bool isExistedWarehouse = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.PackageCodeClient == resultionPackage.PatchCode)
.Any();
if (!isExistedWarehouse)
{
return "该箱号未入库!请先入库";
}
// 3.2 判断是否是计划中的物料(大概率不执行)
bool flag1 = false;
List<WmMaterial> materialOutorders = Context
.Queryable<WmMaterialOutorder>()
.LeftJoin<WmMaterial>((wmo, wm) => wmo.FkMaterialId == wm.Id)
.Where(wmo => wmo.FkOutorderId == shipment_num)
.Select((wmo, wm) => new WmMaterial { Partnumber = wm.Partnumber })
.ToList();
foreach (WmMaterial materialOption in materialOutorders)
{
if (materialOption.Partnumber == resultionPackage.PartNumner)
{
flag1 = true;
}
}
if (!flag1)
{
return "该箱标签物料号不在出库单物料清单内!";
}
// 4. 判断出库单是否启用出库规则
var shipment = Context
.Queryable<WmOutOrder>()
.Where(it => it.ShipmentNum == shipment_num)
.First();
if (shipment.Status == 0)
{
return "ok";
}
// 5. 确保出最早批次
string short_path = resultionPackage.PatchCode.Split('_')[0];
// 严格规则(出库规则判断)
return CheckRuleJudgmentFirstInFirstOut(shipment_num, short_path, parnumber);
/*WmOutOrderPlan plan_item = Context.Queryable<WmOutOrderPlan>()
.Where(it => it.FkOutOrderId == shipment_num)
.Where(it => it.Patchcode == short_path)
.OrderBy(it => it.Outorder)
.First();
if (plan_item != null)
{
// 查看此批次号在此工单下已出库箱子数量
int patchInNum = Context.Queryable<WmGoodsOutRecord>()
.Where(it => it.PackageCodeClient.Contains(short_path))
.Where(it => it.FkOutOrderId == shipment_num)
.Count();
var plan_earliest = Context.Queryable<WmOutOrderPlan>()
.Where(it => it.FkOutOrderId == shipment_num)
.Where(it => it.MaterialCode == plan_item.MaterialCode)
.Where(it => it.PackageNum > patchInNum)
.OrderBy(it => it.Outorder)
.First();
//已经出库完成,没有可以出库的了
if (plan_earliest == null)
{
return "此物料在计划中已经全部出库完成,无法继续出库";
}
// 批次号是最早批次
*/
/*if (plan_earliest.Id == plan_item.Id)
{
return "ok";
}*/
/*
if (plan_earliest.Patchcode == short_path)
{
return "ok";
}
else
{
return "不是此物料最早批次,无法出库";
}
}*/
// 6 .还差一个 数量超过要出库的箱子
return "此箱标签不可出库,批次号不在出库单计划内!请检查出库单计划!";
}
catch (Exception ex)
{
return "此箱标签存在异常不可出库!";
}
}
/// <summary>
/// 持久化存储
/// </summary>
/// <param name="shipment_num"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public int PersistenceOutorderplan(string shipment_num)
{
List<WmOutOrderPlan> orderPlans = Generate_outorderplan(shipment_num);
var x = Context
.Storageable(orderPlans)
.WhereColumns(it => it.FkOutOrderId)
.WhereColumns(it => it.MaterialCode)
.WhereColumns(it => it.Patchcode)
.ToStorage();
int result = x.AsInsertable.ExecuteCommand(); //执行插入
x.AsUpdateable.ExecuteCommand(); //执行更新 
return result;
}
/// <summary>
/// 出库单先进先出规则判断(严格复杂版)
/// </summary>
/// <param name="shipment_num">工单号</param>
/// <param name="shortPackageCode">短批次号</param>
/// <returns> "ok" 代表通过,其余返回错误提示</returns>
/// <exception cref="NotImplementedException"></exception>
public string CheckRuleJudgmentFirstInFirstOut(
string shipment_num,
string shortPackageCode,
string parnumber
)
{
// 1.检查是否有记录
var exp1 = Expressionable
.Create<WmOutOrderPlan>()
.And(it => it.FkOutOrderId == shipment_num)
.And(it => it.Patchcode == shortPackageCode)
.ToExpression();
bool hasRecord = Context.Queryable<WmOutOrderPlan>().Where(exp1).Any();
if (!hasRecord)
{
return "此批次号不在出库单计划中!";
}
// 1.取出出库单计划
List<WmOutOrderPlan> plans = Context
.Queryable<WmOutOrderPlan>()
.Where(it => it.FkOutOrderId == shipment_num)
.OrderBy(it => it.Outorder)
.ToList();
foreach (WmOutOrderPlan plan in plans)
{
// 不是同零件号的跳过
if (plan.MaterialCode != parnumber)
{
continue;
}
// 2.此出库单下的批次号的已出库记录
var exp2 = Expressionable
.Create<WmGoodsOutRecord>()
.And(it => it.PackageCodeClient.Contains(plan.Patchcode))
.And(it => it.Partnumber == plan.MaterialCode)
.And(it => it.FkOutOrderId == shipment_num)
.ToExpression();
List<WmGoodsOutRecord> outPackageList = Context
.Queryable<WmGoodsOutRecord>()
.Where(exp2)
.ToList();
int outPackageNum = 0;
int outPartnumberNum = 0;
foreach (WmGoodsOutRecord outItem in outPackageList)
{
outPackageNum += 1;
outPartnumberNum += (int)outItem.GoodsNumAction;
}
// 按顺序检查是否出完
if (plan.Patchcode != shortPackageCode)
{
// 此批次是否还有库存
bool hasAny = Context
.Queryable<WmGoodsNowProduction>()
.Where(it => it.PackageCodeClient.Contains(plan.Patchcode))
.Where(it => it.Partnumber == plan.MaterialCode)
.Any();
// 检查此批次是否出完
if (outPartnumberNum >= plan.RequireNum || !hasAny)
{
// 出完了或仓库里没了
continue;
}
else
{
return "不是出库单计划中此物料的最早批次,无法出库! 计划中批次:" + plan.Patchcode + "未出完!";
}
}
else
{
// 检查此批次是否出完
if (outPartnumberNum < plan.RequireNum)
{
return "ok";
}
else
{
// 出完了
return "此批次已在出库计划中出完! 当前已出库:" + outPartnumberNum + "个零件!";
}
}
}
return "经检查,此批次号不在出库单计划中!";
}
}
}