|
@@ -47,6 +47,18 @@ namespace Business.Replenishment
|
|
|
private readonly ISqlRepository<InvMaster> _invMaster;
|
|
private readonly ISqlRepository<InvMaster> _invMaster;
|
|
|
private readonly ISqlRepository<SAPInv> _SAPInv;
|
|
private readonly ISqlRepository<SAPInv> _SAPInv;
|
|
|
private readonly IRepository<srm_purchase, long> _srmPurchase;
|
|
private readonly IRepository<srm_purchase, long> _srmPurchase;
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 交货计划
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ private readonly IRepository<ic_demandschedule, long> _icdemandschedule;
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 交货单
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ private readonly ISqlRepository<srm_polist_ds> _srmpolistds;
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 采购明细表
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ private readonly ISqlRepository<PurOrdDetail> _PurOrdDetail;
|
|
|
private readonly ISqlRepository<MonthlyShipmentPlan> _monthlyShipmentPlan;
|
|
private readonly ISqlRepository<MonthlyShipmentPlan> _monthlyShipmentPlan;
|
|
|
private readonly ISqlRepository<MonthlyShipmentPlanHistory> _monthlyShipmentPlanHistory;
|
|
private readonly ISqlRepository<MonthlyShipmentPlanHistory> _monthlyShipmentPlanHistory;
|
|
|
private readonly ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
|
|
private readonly ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
|
|
@@ -315,6 +327,9 @@ namespace Business.Replenishment
|
|
|
BusinessBangDbContext businessBangDbContext,
|
|
BusinessBangDbContext businessBangDbContext,
|
|
|
BusinessDbContext businessDbContext,
|
|
BusinessDbContext businessDbContext,
|
|
|
ICurrentTenant currentTenant,
|
|
ICurrentTenant currentTenant,
|
|
|
|
|
+ IRepository<ic_demandschedule, long> icdemandschedule,
|
|
|
|
|
+ ISqlRepository<srm_polist_ds> srmpolistds,
|
|
|
|
|
+ ISqlRepository<PurOrdDetail> PurOrdDetail,
|
|
|
IUnitOfWorkManager unitOfWorkManager)
|
|
IUnitOfWorkManager unitOfWorkManager)
|
|
|
{
|
|
{
|
|
|
_replenishmentROPWeekPlan = replenishmentROPWeekPlan;
|
|
_replenishmentROPWeekPlan = replenishmentROPWeekPlan;
|
|
@@ -406,6 +421,9 @@ namespace Business.Replenishment
|
|
|
_businessBangDbContext= businessBangDbContext;
|
|
_businessBangDbContext= businessBangDbContext;
|
|
|
_businessDbContext = businessDbContext;
|
|
_businessDbContext = businessDbContext;
|
|
|
_unitOfWorkManager = unitOfWorkManager;
|
|
_unitOfWorkManager = unitOfWorkManager;
|
|
|
|
|
+ _icdemandschedule = icdemandschedule;
|
|
|
|
|
+ _srmpolistds = srmpolistds;
|
|
|
|
|
+ _PurOrdDetail = PurOrdDetail;
|
|
|
}
|
|
}
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
@@ -6169,17 +6187,184 @@ namespace Business.Replenishment
|
|
|
/// 生成交货单
|
|
/// 生成交货单
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
/// <param name="domain"></param>
|
|
/// <param name="domain"></param>
|
|
|
|
|
+ /// <param name="user"></param>
|
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
|
- public async Task<string> CreateDeliverySchedule(string domain)
|
|
|
|
|
|
|
+ public async Task<string> CreateDeliverySchedule(string domain,string user)
|
|
|
{
|
|
{
|
|
|
string Msg = "OK|交货单生成成功";
|
|
string Msg = "OK|交货单生成成功";
|
|
|
//获取已发布的交货计划数据
|
|
//获取已发布的交货计划数据
|
|
|
- //获取货源清单数据
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ var demandplans = _icdemandschedule.GetListAsync(p=>p.factory_id.ToString() == domain && p.status == "P" && !p.IsDeleted).Result;
|
|
|
|
|
+ if (!demandplans.Any())
|
|
|
|
|
+ {
|
|
|
|
|
+ Msg = "OK|没有需要生成的交货单";
|
|
|
|
|
+ return Msg;
|
|
|
|
|
+ }
|
|
|
|
|
+ //获取货源清单数据(配额比例为0的排除)
|
|
|
|
|
+ List<string> itemnums = demandplans.Select(p => p.itemnum).ToList();
|
|
|
|
|
+ var purchases = _srmPurchase.GetListAsync(p => p.factory_id.ToString() == domain && p.is_active == "否" && itemnums.Contains(p.number) && p.quota_rate > 0 && !p.IsDeleted).Result;
|
|
|
|
|
+ //获取PO可用明细数据:未关闭,且未交货数量(需求数量-已收数量)>0
|
|
|
|
|
+ List<PurOrdDetail> purOrdDetails = _PurOrdDetail.Select(p => p.Domain == domain && itemnums.Contains(p.ItemNum) && p.Status.ToUpper() != "C" && (p.QtyOrded - p.RctQty)>0).OrderBy(p=>p.DueDate).ToList();
|
|
|
|
|
+ if (!purOrdDetails.Any())
|
|
|
|
|
+ {
|
|
|
|
|
+ Msg = "NO|没有可用的采购单";
|
|
|
|
|
+ return Msg;
|
|
|
|
|
+ }
|
|
|
|
|
+ //获取占用可用PO明细的交货单
|
|
|
|
|
+ List<srm_polist_ds> dbPolistds = _srmpolistds.Select(p => purOrdDetails.Select(m => m.PurOrd).Contains(p.ponumber)).ToList();
|
|
|
|
|
+
|
|
|
|
|
+ //生成交货单
|
|
|
|
|
+ srm_polist_ds entity;
|
|
|
|
|
+ List<srm_polist_ds> inserts = new List<srm_polist_ds>();
|
|
|
|
|
+ //采购明细剩余未交数量
|
|
|
|
|
+ decimal sumRestQty = 0m;
|
|
|
|
|
+ //交货单占用数量
|
|
|
|
|
+ decimal sumDbOccupy = 0m;
|
|
|
|
|
+ //本次计算占用数量
|
|
|
|
|
+ decimal sumCurOccupy = 0m;
|
|
|
|
|
+ //剩余可用数量
|
|
|
|
|
+ decimal restQty = 0m;
|
|
|
|
|
+ foreach (var item in demandplans)
|
|
|
|
|
+ {
|
|
|
|
|
+ //获取当前交货计划物料对应的货源清单
|
|
|
|
|
+ var curChaes = purchases.Where(p => p.number == item.itemnum).ToList();
|
|
|
|
|
+ //获取当前交货计划物料对应的采购单明细数据
|
|
|
|
|
+ var curPurDtls = purOrdDetails.Where(p => p.ItemNum == item.itemnum).OrderBy(p=>p.DueDate).ToList();
|
|
|
|
|
+ //数据库中当前采购单明细被交货单占用情况
|
|
|
|
|
+ var curDbOccupys = dbPolistds.Where(p => curPurDtls.Select(m => m.PurOrd).Contains(p.ponumber) && p.itemnum == item.itemnum).ToList();
|
|
|
|
|
+ //本次计算中采购单明细被交货单占用情况
|
|
|
|
|
+ var curCalcOccupys = inserts.Where(p => curPurDtls.Select(m => m.PurOrd).Contains(p.ponumber) && p.itemnum == item.itemnum).ToList();
|
|
|
|
|
+ #region 校验
|
|
|
|
|
+ //校验1:如果当前物料没有维护货源清单,则跳过
|
|
|
|
|
+ if (!curChaes.Any())
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ //校验2:如果当前物料没有可用的采购明细,则跳过
|
|
|
|
|
+ if (!curPurDtls.Any())
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ //校验3:如果当前物料对应的采购明细可用数量不满足,则跳过
|
|
|
|
|
+ //采购单明细的剩余未交数量:采购明细的需求数量-已交数量
|
|
|
|
|
+ sumRestQty = curPurDtls.Sum(p => p.QtyOrded - p.RctQty);
|
|
|
|
|
+ //交货单占用数量:交货单的剩余需要采购数量
|
|
|
|
|
+ sumDbOccupy = curDbOccupys.Sum(p => p.restqty);
|
|
|
|
|
+ //本次计算交货单占用数量:本次计算交货单的需求数量
|
|
|
|
|
+ sumCurOccupy = curCalcOccupys.Sum(p => p.schedqty);
|
|
|
|
|
+ //剩余可用数量
|
|
|
|
|
+ restQty = sumRestQty - sumDbOccupy - sumCurOccupy;
|
|
|
|
|
+ if (restQty < item.tosechedqty)
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ //当前供应商分配数量数量
|
|
|
|
|
+ decimal needQty = 0m;
|
|
|
|
|
+ //已分配数量合计
|
|
|
|
|
+ decimal sumNeedQty = 0m;
|
|
|
|
|
+ //剩余需要分配数量
|
|
|
|
|
+ decimal remainQty = 0m;
|
|
|
|
|
+ //存在货源清单,po可用数量满足当前交货计划,则先计算供应商配额,然后,再占用po可用数量
|
|
|
|
|
+ foreach (var pch in curChaes)
|
|
|
|
|
+ {
|
|
|
|
|
+ //计算当前供应商分配数量
|
|
|
|
|
+ needQty = item.tosechedqty * pch.quota_rate.GetValueOrDefault();
|
|
|
|
|
+ //按照采购单明细数据交货日期从小到大开始占用
|
|
|
|
|
+ foreach (var pud in curPurDtls)
|
|
|
|
|
+ {
|
|
|
|
|
+ //当前采购明细剩余数量=订单数量-已收数量
|
|
|
|
|
+ decimal syQty = pud.QtyOrded - pud.RctQty;
|
|
|
|
|
+ //当前采购明细被占用数量(已占用数量)
|
|
|
|
|
+ var occupy = curDbOccupys.Where(p => p.ponumber == pud.PurOrd && p.itemnum == pud.ItemNum && p.poline == pud.Line).ToList();
|
|
|
|
|
+ decimal yzyQty = occupy.Sum(p => p.restqty);
|
|
|
|
|
+ //当前计算中采购明细被占用数量(本次计算占用数量)
|
|
|
|
|
+ var calcs = inserts.Where(p=> p.ponumber == pud.PurOrd && p.itemnum == pud.ItemNum && p.poline == pud.Line).ToList();
|
|
|
|
|
+ decimal bzyQty = calcs.Sum(p=>p.schedqty);
|
|
|
|
|
+
|
|
|
|
|
+ //当前采购明细可用数量
|
|
|
|
|
+ decimal kyQty = syQty - yzyQty - bzyQty;
|
|
|
|
|
+ //剩余需要分配数量
|
|
|
|
|
+ remainQty = needQty - sumNeedQty;
|
|
|
|
|
+ //当前采购明细已被全部占用,循环下一条采购明细
|
|
|
|
|
+ if (kyQty == 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ decimal xqQty = 0m;
|
|
|
|
|
+ //当前采购明细的可用数量不满足交货单剩余需要分配数量
|
|
|
|
|
+ if (kyQty < remainQty)
|
|
|
|
|
+ {
|
|
|
|
|
+ //占用当前采购明细剩余可用数量
|
|
|
|
|
+ xqQty = kyQty;
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ xqQty = remainQty;
|
|
|
|
|
+ //按照最小包装量圆整:最小包装量为0,则不需要圆整
|
|
|
|
|
+ decimal yzQty = pch.packaging_qty.GetValueOrDefault() == 0 ? remainQty : Math.Ceiling(remainQty / pch.packaging_qty.GetValueOrDefault()) * pch.packaging_qty.GetValueOrDefault();
|
|
|
|
|
+ //如果可用数量大于圆整数量
|
|
|
|
|
+ if (kyQty >= yzQty)
|
|
|
|
|
+ {
|
|
|
|
|
+ xqQty = yzQty;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //生成实体
|
|
|
|
|
+ entity = new srm_polist_ds();
|
|
|
|
|
+ entity.Id = help.NextId();
|
|
|
|
|
+ entity.domain = domain;
|
|
|
|
|
+ entity.icdsid = item.Id;
|
|
|
|
|
+ //TODO:调用存储过程生成交货单号
|
|
|
|
|
+ entity.dsnum = "";
|
|
|
|
|
+ entity.status = "N";
|
|
|
|
|
+ entity.itemnum = item.itemnum;
|
|
|
|
|
+ entity.suppliercode = pch.supplier_number;
|
|
|
|
|
+ entity.supplier = pch.supplier_name;
|
|
|
|
|
+ entity.requestdate = item.arrivaldate;
|
|
|
|
|
+ entity.needdate = item.requestdate;
|
|
|
|
|
+ entity.ponumber = pud.PurOrd;
|
|
|
|
|
+ entity.poline = pud.Line;
|
|
|
|
|
+ entity.schedqty = xqQty;
|
|
|
|
|
+ entity.lastsentqty = 0m;
|
|
|
|
|
+ entity.sentqty = 0m;
|
|
|
|
|
+ entity.restqty = xqQty;
|
|
|
|
|
+ entity.createtime = DateTime.Now;
|
|
|
|
|
+ entity.createuser = user;
|
|
|
|
|
+ inserts.Add(entity);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ if (inserts.Any())
|
|
|
|
|
+ {
|
|
|
|
|
+ //获取交货单号
|
|
|
|
|
+ List<string> GenerateMoList = new List<string>();
|
|
|
|
|
+ var nbrlist = _serialNumberAppService.GetBillNo(domain, "M8", inserts.Count, "", 1);
|
|
|
|
|
+ if (!nbrlist.Any() || nbrlist.Count != inserts.Count)
|
|
|
|
|
+ {
|
|
|
|
|
+ Msg = "NO|交货单号生成失败";
|
|
|
|
|
+ return Msg;
|
|
|
|
|
+ }
|
|
|
|
|
+ inserts = inserts.OrderBy(p => p.createtime).ToList();
|
|
|
|
|
+ for (int i = 0; i < inserts.Count; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ inserts[i].dsnum = nbrlist[i].NbrResult;
|
|
|
|
|
+ }
|
|
|
|
|
+ //数据插入
|
|
|
|
|
+ using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ _srmpolistds.Insert(inserts);
|
|
|
|
|
+ await unitOfWork.CompleteAsync();
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception e)
|
|
|
|
|
+ {
|
|
|
|
|
+ unitOfWork.Dispose();
|
|
|
|
|
+ new NLogHelper("ReplenishmentAppService").WriteLog("CreateDeliverySchedule", "交货计划生成交货单失败:" + e.Message, _currentTenant.Id.ToString());
|
|
|
|
|
+ Msg = "NO|交货单保存失败:" + e.Message;
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
return Msg;
|
|
return Msg;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|