| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- using Business.Core.Enum;
- using Business.Core.Utilities;
- using Business.Domain;
- using Business.Dto;
- using Business.EntityFrameworkCore.SqlRepositories;
- using Business.SaleForecast;
- using Business.StructuredDB.SaleFcst;
- using Business.StructuredDB.WMS;
- using NetTopologySuite.Algorithm;
- using RazorEngine;
- using Spire.Pdf.General.Render.Decode.Jpeg2000.j2k.wavelet.synthesis;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Volo.Abp.Application.Dtos;
- using Volo.Abp.Application.Services;
- using Volo.Abp.DependencyInjection;
- using Volo.Abp.Domain.Repositories;
- using Volo.Abp.MultiTenancy;
- using Volo.Abp.Uow;
- using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
- namespace Business.SaleForecastManagement
- {
- public class AnnualProductionOutlineAppService : ApplicationService, ITransientDependency, IAnnualProductionOutlineAppService
- {
- #region 服务
- /// <summary>
- /// 工作单元
- /// </summary>
- private readonly IUnitOfWorkManager _unitOfWorkManager;
- /// <summary>
- /// 日志
- /// </summary>
- private readonly ICurrentTenant _currentTenant;
- /// <summary>
- /// 年度销售预测
- /// </summary>
- private IRepository<YearDemandManagement, long> _yearDemandManagement;
- /// <summary>
- /// 年度销售预测历史记录
- /// </summary>
- private IRepository<YearDemandManagementHistory, long> _yearDemandManagementHistory;
- /// <summary>
- /// 年度生产大纲
- /// </summary>
- private IRepository<AnnualProductionOutline, long> _annualProductionOutline;
- /// <summary>
- /// 生产线明细
- /// </summary>
- private ISqlRepository<ProdLineDetail> _prodLineDetail;
- /// <summary>
- /// 标准工艺流程表
- /// </summary>
- private ISqlRepository<RoutingOpDetail> _routingOpDetail;
- /// <summary>
- /// 库存表
- /// </summary>
- private ISqlRepository<LocationDetail> _locationDetail;
- /// <summary>
- /// 平台库存表
- /// </summary>
- private readonly IRepository<WMS_PlatformInventory, long> _PlatformInventory;
- /// <summary>
- /// 雪花算法
- /// </summary>
- SnowFlake help = new SnowFlake();
- #endregion
- #region 构造函数
- /// <summary>
- /// 构造函数
- /// </summary>
- public AnnualProductionOutlineAppService(
- IUnitOfWorkManager unitOfWorkManager,
- ICurrentTenant currentTenant,
- IRepository<YearDemandManagement, long> yearDemandManagement,
- IRepository<AnnualProductionOutline, long> annualProductionOutline,
- IRepository<YearDemandManagementHistory, long> yearDemandManagementHistory,
- ISqlRepository<ProdLineDetail> prodLineDetail,
- IRepository<WMS_PlatformInventory, long> PlatformInventory,
- ISqlRepository<RoutingOpDetail> routingOpDetail,
- ISqlRepository<LocationDetail> locationDetail
- )
- {
- _unitOfWorkManager = unitOfWorkManager;
- _currentTenant = currentTenant;
- _PlatformInventory = PlatformInventory;
- _prodLineDetail = prodLineDetail;
- _routingOpDetail = routingOpDetail;
- _locationDetail = locationDetail;
- _yearDemandManagement = yearDemandManagement;
- _yearDemandManagementHistory = yearDemandManagementHistory;
- _annualProductionOutline = annualProductionOutline;
- }
- #endregion
- /// <summary>
- /// 生成年度生产大纲
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- /// <exception cref="NotImplementedException"></exception>
- public async Task<string> SaveAnnualProductionOutline(InputDto input)
- {
- //获取当前导入或修改数据
- List<YearDemandManagement> yearDemands = _yearDemandManagement.GetListAsync(p => p.Year == input.year && p.tenant_id == input.tenant_id && p.company_id == input.company_id && p.factory_id == input.factory_id && !p.IsDeleted).Result.OrderBy(p => p.OrderNum).ThenBy(o => o.PlanMonth).ToList();
- //标准工艺路径表
- List<RoutingOpDetail> routingOps = _routingOpDetail.Select(p => yearDemands.Select(m => m.SAPItemNumber).Contains(p.RoutingCode) && p.Domain == input.factory_id.ToString() && p.IsActive);
- var routingOpList = routingOps.Where(x => x.Descr == "组装").ToList();
- //生产线明细表
- List<ProdLineDetail> prodLines = _prodLineDetail.Select(p => yearDemands.Select(m => m.SAPItemNumber).Contains(p.Part) && p.Domain == input.factory_id.ToString() && p.IsActive && routingOpList.Select(m => m.Op).Contains(p.Op)).OrderBy(x => x.Sequence).ToList();
- List<LocationDetail> locations = _locationDetail.Select(x => yearDemands.Select(m => m.SAPItemNumber).Contains(x.ItemNum) && x.Domain == input.factory_id.ToString() && x.IsActive).ToList();
- //平台库存
- var platformInvList = _PlatformInventory.GetListAsync(a => yearDemands.Select(m => m.SAPItemNumber).Contains(a.SAPItemNumber) && a.tenant_id == input.tenant_id && a.factory_id == input.factory_id).Result;
- //取上一个月发货出库记录
- //IEnumerable<ASNBOLShipperDetail> shipList = _ASNBOLShipperDetail.Select(a => a.Domain == input.factory_id.ToString() && a.IsActive && a.shtype == "SH" && a.Typed != "S" && a.RealQty > 0 && planItemList.Contains(a.ContainerItem)).Where(s => s.ShipDate >= getMonthStartTime(-1) && s.ShipDate <= getMonthEndTime(-1));
- //在制 -- 工单计划中的数量 工单数量-完成数=生产中的在制
- //年度生产大纲实体
- List<AnnualProductionOutline> annualProductionOutlines = new List<AnnualProductionOutline>();
- List<YearDemandManagement> frontYearDemand = new List<YearDemandManagement>();
- foreach (var item in yearDemands)
- {
- var routingOp = routingOps.Where(x => x.RoutingCode == item.SAPItemNumber).ToList();
- var Assembly = routingOp.Where(x => x.Descr == "组装").FirstOrDefault();
- var HeatSealing = routingOp.Where(x => x.Descr == "热封").FirstOrDefault();
- var Packaging = routingOp.Where(x => x.Descr == "包装").FirstOrDefault();
- var prodLine = prodLines.Where(x => x.Part == item.SAPItemNumber).OrderBy(x => x.Sequence).FirstOrDefault();
- //不同库位库存数量
- var locationList = locations.Where(x => x.ItemNum == item.SAPItemNumber).ToList();
- var platformInvs = platformInvList.Where(x => x.SAPItemNumber == item.SAPItemNumber).ToList();
- var QtySum = yearDemands.Where(x => x.SAPItemNumber == item.SAPItemNumber).ToList();
- //排产批量:(AVG(1 - 12月销售预测)/ 100 )=(0.45 = 1 小数向上取整) *100 = 100
- var pcpl = Math.Ceiling(QtySum.Sum(p => p.Qty) / QtySum.Count()) * 100;
- //库存合计 + 在制+已发货
- var locationSum = (locationList.Count == 0 ? 0 : locationList.Sum(x => x.QtyOnHand)) + (platformInvs.Count == 0 ? 0 : platformInvs.Sum(x => x.InventoryQuantity));
- //if (annualProductionOutlines.Count > 0)
- //{
- //前面N个月的生产数量
- var frontQtySum = annualProductionOutlines.Sum(x => x.Qty);
- var num = (locationSum + frontQtySum) - frontYearDemand.Sum(m => m.Qty) - item.Qty / 2;
- if (num < 0)
- {
- num = pcpl * Math.Ceiling((-(locationSum + frontQtySum)) + frontYearDemand.Sum(m => m.Qty) + item.Qty / 2);
- }
- // }
- //生产数量:3月为例子,(库存和前2月生产数量)-(前2个月销售预测数据)-当月销售预测数据 / 2 < 0 else 排产批量 *((-库存合计数量 + 前2个月销售预测数量 + 当月销售预测数量 / 2)/ 批量排产)
- //生成年度生产大纲
- AnnualProductionOutline annualProductionOutline = new AnnualProductionOutline();
- //TODO:取值
- annualProductionOutline.Year = item.Year;
- annualProductionOutline.Area = item.Area;
- annualProductionOutline.ProdLine = item.ProdLine;
- annualProductionOutline.ProdRange = item.ProdRange;
- annualProductionOutline.WorkshopLine = prodLine == null ? "" : prodLine.Line;
- annualProductionOutline.SAPItemNumber = item.SAPItemNumber;
- annualProductionOutline.Model = item.Model;
- annualProductionOutline.Languages = item.Languages;
- annualProductionOutline.PlanMonth = item.PlanMonth;
- annualProductionOutline.Qty = num;
- annualProductionOutline.StandardHours = (Assembly == null ? 0 : Assembly.RunTime) + (HeatSealing == null ? 0 : HeatSealing.RunTime) + (Packaging == null ? 0 : Packaging.RunTime);
- //组装热封包装工时乘以数量 =单月工时
- annualProductionOutline.AssemblyHours = Assembly == null ? 0 : Assembly.RunTime * num;
- annualProductionOutline.HeatSealingHours = HeatSealing == null ? 0 : HeatSealing.RunTime * num;
- annualProductionOutline.PackagingHours = Packaging == null ? 0 : Packaging.RunTime * num;
- annualProductionOutline.Totalhours = annualProductionOutline.AssemblyHours + annualProductionOutline.HeatSealingHours + annualProductionOutline.Totalhours;
- annualProductionOutline.OrderNum = item.OrderNum;
- annualProductionOutlines.Add(annualProductionOutline);
- frontYearDemand.Add(item);
- }
- //保存数据
- using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
- {
- try
- {
- await _annualProductionOutline.InsertManyAsync(annualProductionOutlines);
- await unitOfWork.CompleteAsync();
- }
- catch (Exception e)
- {
- unitOfWork.Dispose();
- new NLogHelper("AnnualProductionOutlineAppService").WriteLog("SaveAnnualProductionOutline", "【" + input.year + "年" + "】月度需求预测更新失败:" + e.Message, _currentTenant.Id.ToString());
- return "NO|" + e.Message;
- };
- }
- return "OK";
- }
- }
- }
|