| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- using Business.Domain;
- using Business.Dto;
- using Business.ResourceExamineManagement.Dto;
- using MongoDB.Driver.Linq;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Volo.Abp.Application.Services;
- namespace Business.ResourceExamineManagement
- {
- /// <summary>
- /// 产能检查
- /// </summary>
- public class ProductExamineAppService: ApplicationService
- {
- #region 服务
- /// <summary>
- /// 生产线明细表
- /// </summary>
- public List<ProdLineDetail> prodLines = new List<ProdLineDetail>();
- /// <summary>
- /// 标准工艺路径表
- /// </summary>
- public List<RoutingOpDetail> routingOps = new List<RoutingOpDetail>();
- /// <summary>
- /// 排产记录表
- /// </summary>
- public List<PeriodSequenceDet> periodSequences = new List<PeriodSequenceDet>();
- /// <summary>
- /// 工作日历
- /// </summary>
- public List<ShopCalendarWorkCtr> calendarWorks = new List<ShopCalendarWorkCtr>();
- /// <summary>
- /// 休息时间段
- /// </summary>
- public List<QualityLineWorkDetail> qualityLineWorks = new List<QualityLineWorkDetail>();
- /// <summary>
- /// 节假日
- /// </summary>
- public List<HolidayMaster> holidays = new List<HolidayMaster>();
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- public ProductExamineAppService()
- {
- }
- /// <summary>
- /// 根据标准工艺获取生产时长(天)
- /// </summary>
- /// <param name="param"></param>
- /// <returns></returns>
- public int ProductTime(ProdExamineParamDto param)
- {
- var allOps = routingOps.Where(s => s.RoutingCode == param.ItemNum && s.Domain == param.Domain).ToList();
- if (allOps.Any())
- {
- decimal maxRt = allOps.Max(s => s.RunTime);
- decimal sumRt = allOps.Sum(s => s.RunTime);
- decimal totalTime = (param.QtyOrd - 1) * maxRt + sumRt;//总计生产小时
- return (int)(Math.Ceiling(totalTime / 8));
- }
- return 1;
- }
- /// <summary>
- /// 产能计算-批量
- /// </summary>
- /// <param name="param">产能检查入参</param>
- /// <returns>生产时长(天)</returns>
- public DateTime ProductiveExamine(ProdExamineParamDto param)
- {
- //生产结束时间
- DateTime planEnd = param.PlanStart.Date;
- if (param.QtyOrd <= 0)
- {
- return planEnd;
- }
- //获取当前产品的工艺路线:主产线,最后一道工序
- var curRoutingOps = routingOps.Where(p => p.RoutingCode == param.ItemNum && p.ParentOp == 0).OrderByDescending(p => p.Op).ToList();
- if (curRoutingOps.Count == 0)
- {
- return planEnd;
- }
- var lastOp = curRoutingOps.First();
- //获取产线
- var curProdLine = prodLines.FirstOrDefault(p => p.Part == param.ItemNum && p.Op == lastOp.Op);
- if (curProdLine == null)
- {
- return planEnd;
- }
- //获取产线工作日历
- var curCalendars = calendarWorks.Where(p => p.ProdLine == curProdLine.Line).ToList();
- if (curCalendars.Count == 0 || curCalendars.Count != 7)
- {
- return planEnd;
- }
- //获取产线休息时间
- var curqualityLines = qualityLineWorks.Where(p=>p.ProdLine == curProdLine.Line).ToList();
- //生产数量
- decimal sumAmount = 0m;
- do
- {
- //获取工作日
- planEnd = GetNextWorkDay(planEnd, curCalendars);
- //计算工作日的产能
- sumAmount += CalcCapacity(planEnd, curProdLine, curCalendars, curqualityLines);
- planEnd = planEnd.AddDays(1);
- } while (sumAmount < param.QtyOrd);
- return planEnd.AddDays(-1);
- }
- /// <summary>
- /// 获取工作日
- /// </summary>
- /// <param name="weekDay">当前周几</param>
- /// <param name="startTime">开始时间:年-月-日</param>
- /// <param name="curCalendars">当前产线的工作日历</param>
- /// <returns></returns>
- public DateTime GetNextWorkDay(DateTime startTime, List<ShopCalendarWorkCtr> curCalendars)
- {
- DateTime rtnData = startTime;
- int weekDay = (int)startTime.DayOfWeek;
- var calendar = curCalendars.FirstOrDefault(p => p.WeekDay == weekDay);
- //判断当天是否是工作日
- if (weekDay == 0 || weekDay == 6)//周六,周日
- {
- if (!holidays.Exists(p => p.Dated.GetValueOrDefault().Date == startTime && p.Ufld1 == "调班"))//今天是周末
- {
- //递归继续找下一个工作日
- rtnData = GetNextWorkDay(startTime.AddDays(1), curCalendars);
- return rtnData;
- }
- return rtnData;
- }
- //今天不是周六周日,需要判断是不是节假日
- if (holidays.Exists(p => p.Dated.GetValueOrDefault().Date == startTime && p.Ufld1 == "休假"))//是节假日
- {
- //递归继续找下一个工作日
- rtnData = GetNextWorkDay(startTime.AddDays(1), curCalendars);
- return rtnData;
- }
- return rtnData;
- }
- /// <summary>
- /// 计算当天的产能
- /// </summary>
- /// <param name="startTime"></param>
- /// <param name="prodLine"></param>
- /// <param name="curCalendars"></param>
- /// <param name="curQualityLines"></param>
- /// <returns></returns>
- public decimal CalcCapacity(DateTime startTime,ProdLineDetail prodLine, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQualityLines)
- {
- decimal sumQty = 0m;
- //获取休息时长(分钟)
- decimal sumResrt = curQualityLines.Sum(p => p.RestTime);
- //获取当天的工作时长(分钟)
- decimal workTime = curCalendars.First(p => p.WeekDay == (int)startTime.DayOfWeek).ShiftsHours1 * 60;
- //计算产能
- sumQty = Math.Ceiling((workTime - sumResrt) / 60 * prodLine.Rate);
- return sumQty;
- }
- /// <summary>
- /// 计算订单行的建议交期(产能/物料)
- /// </summary>
- /// <param name="sentrys"></param>
- /// <param name="kittingTimes"></param>
- /// <returns></returns>
- public void CalcSuggestTime(List<crm_seorderentry> sentrys, List<KittingTimeDto> kittingTimes, List<mo_ic_item> icitemlist)
- {
- ProdExamineParamDto param;
- foreach (var item in sentrys)
- {
- var dto = kittingTimes.FirstOrDefault(p=>p.sentry_id == item.Id);
- if (dto == null)
- {
- continue;
- }
- var icitem = icitemlist.Find(s => s.number == item.item_number);
- if (dto.LackQty == 0)//当前订单行库存足够
- {
- if (icitem != null)
- {
- //加上自检、入库、发运提前期
- dto.kitting_time = dto.kitting_time.AddDays((double)(icitem.self_inspection_date.GetValueOrDefault() + icitem.Warehousing_date.GetValueOrDefault() + icitem.Shipping_date.GetValueOrDefault()+icitem.RoutingDesignTime.GetValueOrDefault()));
- dto.kitting_time= dto.kitting_time<=item.plan_date.GetValueOrDefault()? item.plan_date.GetValueOrDefault(): dto.kitting_time;
- }
- item.sys_material_date = dto.kitting_time;
- item.sys_capacity_date = dto.kitting_time;
- continue;
- }
- //计算系统建议交期(物料)
- param = new ProdExamineParamDto
- {
- ItemNum = item.item_number,
- QtyOrd = dto.LackQty,
- PlanStart = dto.kitting_time.Date.AddDays(1)
- };
- var time = ProductiveExamine(param);
- item.sys_material_date = time;
- item.sys_capacity_date = time;
- if (icitem != null)
- {
- //加上自检、入库、发运提前期
- item.sys_material_date = time.AddDays((double)(icitem.self_inspection_date.GetValueOrDefault() + icitem.Warehousing_date.GetValueOrDefault() + icitem.Shipping_date.GetValueOrDefault() + icitem.RoutingDesignTime.GetValueOrDefault()));
- }
- //param.PlanStart = dto.kitting_time.Date.AddDays(3);
- //计算系统交期(产能)
- //获取主线最后一道工序
- List<PeriodSequenceDet> schedules = new List<PeriodSequenceDet>();
- var routings = routingOps.Where(p => p.RoutingCode == item.item_number && p.ParentOp == 0).OrderBy(p=>p.Op).ToList();
- if (routings.Count != 0)
- {
- //获取产线
- var prodLine = prodLines.FirstOrDefault(p => p.Part == item.item_number && p.Op == routings.Last().Op);
- if (prodLine != null)
- {
- //获取产线空闲开始时间
- schedules = periodSequences.Where(p => p.ItemNum == item.item_number && p.Op == prodLine.Op && p.Line == prodLine.Line).OrderByDescending(p => p.PlanDate).ToList();
- }
- }
- if (schedules.Any())
- {
- //产线空闲开始时间
- var lastTime = schedules.First().PlanDate.GetValueOrDefault().Date;
- if (lastTime >= param.PlanStart)//如果产线空闲时间大于或者等于系统建议交期(物料)的开工时间
- {
- param.PlanStart = lastTime;
- item.sys_capacity_date = ProductiveExamine(param);
- }
- else {
- item.sys_capacity_date = ProductiveExamine(param);
- }
- }
- else {
- item.sys_capacity_date = ProductiveExamine(param);
- }
- if (icitem != null)
- {
- //加上自检、入库、发运提前期
- item.sys_capacity_date = item.sys_capacity_date.GetValueOrDefault().AddDays((double)(icitem.self_inspection_date.GetValueOrDefault() + icitem.Warehousing_date.GetValueOrDefault() + icitem.Shipping_date.GetValueOrDefault() + icitem.RoutingDesignTime.GetValueOrDefault()));
- }
- item.sys_capacity_date = item.sys_capacity_date <= item.plan_date ? item.plan_date : item.sys_capacity_date;
- }
- }
- }
- }
|