|
|
@@ -35,6 +35,7 @@ using System.ComponentModel.Design;
|
|
|
using Volo.Abp.Validation.StringValues;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
using MongoDB.Driver;
|
|
|
+using Hangfire.Annotations;
|
|
|
|
|
|
namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
@@ -600,28 +601,26 @@ namespace Business.ResourceExamineManagement
|
|
|
{
|
|
|
string childNum = dto.num + "." + idx.ToString();
|
|
|
var icitem = icitemlist.WhereIf(true, a => a.Id == c.icitem_id).FirstOrDefault();
|
|
|
+ var childBom = bomlist.WhereIf(true, a => a.icitem_id == c.icitem_id).FirstOrDefault();
|
|
|
//如果此明细查的到BOM信息,则代表此child是一个子BOM。
|
|
|
- if (c.is_bom == 1)
|
|
|
+ if (childBom != null)
|
|
|
{
|
|
|
- var childBom = bomlist.WhereIf(true, a => a.icitem_id == c.icitem_id).FirstOrDefault();
|
|
|
- if (childBom != null)
|
|
|
- {
|
|
|
- var cdto = new BomChildExamineDto();
|
|
|
- cdto.id = help.NextId();
|
|
|
- cdto.level = level;
|
|
|
- cdto.parent_id = dto.id;
|
|
|
- cdto.qty = c.qty.Value;
|
|
|
- cdto.backflush = c.backflush;
|
|
|
- cdto.num = childNum;
|
|
|
- cdto.isbom = 1;
|
|
|
- cdto.is_replace = c.is_replace;
|
|
|
- cdto.haveicsubs = c.haveicsubs;
|
|
|
- cdto.substitute_code = c.substitute_code;
|
|
|
- cdto.icitem_ids = c.icitem_ids;
|
|
|
- cdto.type = type;
|
|
|
- //递归寻找子级
|
|
|
- GetBomList(bomlist, bomchildlist, icitemlist, cdto, returnlist, type);
|
|
|
- }
|
|
|
+ var cdto = new BomChildExamineDto();
|
|
|
+ cdto.id = help.NextId();
|
|
|
+ cdto.level = level;
|
|
|
+ cdto.parent_id = dto.id;
|
|
|
+ cdto.bom_child_id = c.Id;
|
|
|
+ cdto.qty = c.qty.Value;
|
|
|
+ cdto.backflush = c.backflush;
|
|
|
+ cdto.num = childNum;
|
|
|
+ cdto.isbom = 1;
|
|
|
+ cdto.is_replace = c.is_replace;
|
|
|
+ cdto.haveicsubs = c.haveicsubs;
|
|
|
+ cdto.substitute_code = c.substitute_code;
|
|
|
+ cdto.icitem_ids = c.icitem_ids;
|
|
|
+ cdto.type = type;
|
|
|
+ //递归寻找子级
|
|
|
+ GetBomList(bomlist, bomchildlist, icitemlist, cdto, returnlist, type);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -630,6 +629,7 @@ namespace Business.ResourceExamineManagement
|
|
|
var childDto = new BomChildExamineDto();
|
|
|
childDto.level = level++;
|
|
|
childDto.bom_id = dto.bom_id;
|
|
|
+ childDto.bom_child_id = c.Id;
|
|
|
childDto.id = help.NextId();
|
|
|
childDto.parent_id = dto.id;
|
|
|
childDto.item_id = icitem.Id;
|
|
|
@@ -665,19 +665,32 @@ namespace Business.ResourceExamineManagement
|
|
|
var sublist = _ic_substitute.GetManyByCondition(s => s.substitute_code.IsIn(returnlist.Select(c => c.substitute_code))).Result.ToList();
|
|
|
var suballlist = _ic_substitute_all.GetManyByCondition(s => s.substitute_id.IsIn(sublist.Select(c => c.Id))).Result.ToList();
|
|
|
var subdtllist = _ic_substitute_all_dtl.GetManyByCondition(s => s.substitute_allid.IsIn(suballlist.Select(c => c.Id))).Result.ToList();
|
|
|
-
|
|
|
- List<long> dicIds = new List<long>();
|
|
|
+ List<long> childidList = new List<long>();
|
|
|
var help = new SnowFlake();
|
|
|
int type = 1;
|
|
|
//除顶级外,其他层级关系全带出来。生成平铺
|
|
|
foreach (var item in returnlist)
|
|
|
{
|
|
|
//最顶级、虚拟件
|
|
|
- if (item.level != 1 && item.erp_cls != 4)
|
|
|
+ if (item.level != 1 && item.erp_cls != 4 && !childidList.Contains(item.bom_child_id.GetValueOrDefault()))
|
|
|
{
|
|
|
//有替代关系
|
|
|
if (item.haveicsubs == 1)
|
|
|
{
|
|
|
+ if (!string.IsNullOrEmpty(item.icitem_ids))
|
|
|
+ {
|
|
|
+ long cid = 1;
|
|
|
+ var cids = item.icitem_ids.Split(',');
|
|
|
+ foreach (var c in cids)
|
|
|
+ {
|
|
|
+ if (long.TryParse(c, out cid))
|
|
|
+ {
|
|
|
+ childidList.Add(cid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
//找到当前物料的替代群组关系集
|
|
|
var sl = sublist.Find(s => s.substitute_code == item.substitute_code);
|
|
|
if (sl != null)
|
|
|
@@ -688,8 +701,11 @@ namespace Business.ResourceExamineManagement
|
|
|
var sadl = subdtllist.Where(s => s.substitute_allid == sal.Id).ToList();
|
|
|
foreach (var dtl in sadl)
|
|
|
{
|
|
|
- //递归将替代关系组装出来。
|
|
|
- SubstitutePretreatment(sl, sal, dtl, item, returnlist, icitemlist, bomlist, bomchildlist,type);
|
|
|
+ if (dtl.ismain == 0)
|
|
|
+ {
|
|
|
+ //递归将替代关系组装出来。
|
|
|
+ SubstitutePretreatment(sl, sal, dtl, item, returnlist, icitemlist, bomlist, bomchildlist, type);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -740,9 +756,10 @@ namespace Business.ResourceExamineManagement
|
|
|
dto.haveicsubs = 0;
|
|
|
dto.substitute_code = "";
|
|
|
dto.icitem_ids = "";
|
|
|
- dto.substitute_strategy = sl.substitute_strategy.Value;
|
|
|
- dto.substitute_mode = sl.substitute_mode.Value;
|
|
|
+ dto.substitute_strategy = sl.substitute_strategy.Value;//替代策略
|
|
|
+ dto.substitute_mode = sl.substitute_mode.Value;//替代方式
|
|
|
dto.type = type;
|
|
|
+ dto.substitute_all_num = sal.order_num;//群组优先级
|
|
|
if (bom != null)
|
|
|
{
|
|
|
dto.bom_id = bom.Id;
|
|
|
@@ -786,5 +803,152 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 替代关系检查计算
|
|
|
+ /// </summary>
|
|
|
+ public void CalcIcitemSubstitute(List<BomChildExamineDto> returnlist,int count)
|
|
|
+ {
|
|
|
+ returnlist = returnlist.OrderBy(s => s.num).ToList();
|
|
|
+ //1.如果主料够的时候,不需要显示替代料的平铺视图,如果主料不够,显示替代料的平铺视图。
|
|
|
+ //2.替代策略和替代方式,影响到的是甲乙组概念,替代按主料有限,取代按组的优先级。A与B的替代,则A和B各自会存在一个组。
|
|
|
+ List<long> calcIds = new List<long>();
|
|
|
+ //先处理下最顶级的产品需要数量
|
|
|
+ returnlist[0].needCount = returnlist[0].qty * count;
|
|
|
+ returnlist[0].satisfyNum = returnlist[0].sqty;
|
|
|
+ returnlist[0].lack_qty = returnlist[0].needCount - returnlist[0].satisfyNum;
|
|
|
+ returnlist[0].is_show = true;
|
|
|
+ foreach (var item in returnlist)
|
|
|
+ {
|
|
|
+ //循环平铺整个资源检查的物料库存情况、缺料情况
|
|
|
+ CaclMaterialShortage(returnlist,item, count);
|
|
|
+ }
|
|
|
+ foreach (var item in returnlist)
|
|
|
+ {
|
|
|
+ //替代件不计算,替代件通过标准件的替代关系,去计算需要使用哪些物料
|
|
|
+ if (item.type == 1)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ CaclBomChildUseShortage(returnlist, item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 物料计算
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="returnlist"></param>
|
|
|
+ /// <param name="item"></param>
|
|
|
+ /// <param name="count"></param>
|
|
|
+ public void CaclBomChildUseShortage(List<BomChildExamineDto> returnlist, BomChildExamineDto item)
|
|
|
+ {
|
|
|
+ //判断是否是BOM,如果是BOM,还需要向下展开
|
|
|
+ var bomchild = returnlist.Where(s => s.parent_id == item.id && s.type == 0).ToList();
|
|
|
+ if (bomchild.Count > 0)
|
|
|
+ {
|
|
|
+ foreach (var child in bomchild)
|
|
|
+ {
|
|
|
+ CaclBomChildUseShortage(returnlist, item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var tolist = returnlist.Where(s => s.parent_id == item.parent_id && s.num == item.num).ToList();
|
|
|
+ //有替代关系
|
|
|
+ if (item.haveicsubs == 1)
|
|
|
+ {
|
|
|
+ //首先判断标准件库存是否满足。
|
|
|
+ //如果是BOM,也需要向下展开,看子物料是否满足。
|
|
|
+ //不满足的情况下,则需要展开替代关系,根据替代策略和替代方式,来判定替代件的库存。
|
|
|
+ //假设子BOM有替代关系,则子BOM的子物料,也是有替代关系存在的,需要展开来看。
|
|
|
+ //1.假设标准件库存满足,则不计算替代件关系。
|
|
|
+ //2.如果标准件不满足,则替代件开始计算并展示。
|
|
|
+ //注意:不管是否需要替代件,标准件都需要展开。
|
|
|
+ var sublist = returnlist.Where(s => s.parent_id == item.parent_id && s.num == item.num && s.level == item.level).OrderBy(c => c.substitute_all_num).ToList();
|
|
|
+ //sublist找出当前含替代关系的标准件和替代件。
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (item.substitute_mode == 0)
|
|
|
+ {
|
|
|
+ //替代
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ //取代
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //无替代关系
|
|
|
+ if (item.stock_state==0)
|
|
|
+ {
|
|
|
+ item.use_qty = item.needCount;
|
|
|
+ item.is_show = true;
|
|
|
+ item.stock_state = 0;
|
|
|
+ }
|
|
|
+ else if (item.stock_state == 1)
|
|
|
+ {
|
|
|
+ // 缺料数量 item.lack_qty
|
|
|
+ // 使用数量将库存全部使用了 item.use_qty = item.sqty;
|
|
|
+ if (item.erp_cls == 2 || item.erp_cls == 3)
|
|
|
+ {
|
|
|
+ //委外、外购
|
|
|
+ //生成委外工单、采购申请单
|
|
|
+ //得到单据到货时间。
|
|
|
+ //todo:初步设置为7天到货期,后期根据实际业务来补充修改。
|
|
|
+ item.kitting_time = DateTime.Now.AddDays(7);
|
|
|
+ }
|
|
|
+ else if (item.erp_cls == 1)
|
|
|
+ {
|
|
|
+ //自制
|
|
|
+ //调用产能计算,得到物料自制后的齐套时间。
|
|
|
+ //todo:初步设置为7天完成,等沟通调用方法,来修改此处。
|
|
|
+ item.kitting_time = DateTime.Now.AddDays(7);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 平铺物料缺料情况,展示所有主料+替代料的库存情况、缺料情况
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="returnlist"></param>
|
|
|
+ /// <param name="item"></param>
|
|
|
+ /// <param name="count"></param>
|
|
|
+ public void CaclMaterialShortage(List<BomChildExamineDto> returnlist, BomChildExamineDto item, int count)
|
|
|
+ {
|
|
|
+ var parent = returnlist.Find(s => s.id == item.parent_id);
|
|
|
+ //当前物料总共需要数量
|
|
|
+ item.needCount = parent.needCount * item.qty;
|
|
|
+ item.satisfyNum = item.sqty;//5
|
|
|
+ item.lack_qty = item.needCount - item.satisfyNum;
|
|
|
+
|
|
|
+ //如果不满足,计算子物料,或者计算替代料
|
|
|
+ if (item.lack_qty < 0)
|
|
|
+ {
|
|
|
+ //库存满足
|
|
|
+ item.stock_state = 0;
|
|
|
+ item.lack_qty = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //找出自己的子集,存在子集则是BOM,不存在子集,则自己非BOM。
|
|
|
+ var childList = returnlist.Where(s => s.parent_id == item.id && s.type == item.type).ToList();
|
|
|
+ if (childList.Count > 0)
|
|
|
+ {
|
|
|
+ //自己是BOM
|
|
|
+ foreach (var child in childList)
|
|
|
+ {
|
|
|
+ //循环子集判断库存
|
|
|
+ CaclMaterialShortage(returnlist, child, count);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ item.stock_state = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|