Jelajahi Sumber

整体需求计划生成月度产能共识

heteng 2 tahun lalu
induk
melakukan
62c7701f06

+ 238 - 1
MicroServices/Business/Business.Application/SaleForecastManagement/MonthlyCapacityLoadAppService.cs

@@ -1,13 +1,27 @@
 using Abp.Application.Services;
+using Business.Core.Utilities;
 using Business.Dto;
+using Business.EntityFrameworkCore;
+using Business.EntityFrameworkCore.SqlRepositories;
+using Business.Model.MES.IC;
+using Business.Model.Production;
+using Business.Model.SRM;
+using Business.MongoModel.MES.IC;
+using Business.MongoModel.Production;
+using Business.MongoModel.SRM;
 using Business.ResourceExamineManagement;
 using Business.SaleForecast;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.EntityFrameworkCore.Migrations;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Uow;
 
 namespace Business.SaleForecastManagement
 {
@@ -16,6 +30,100 @@ namespace Business.SaleForecastManagement
     /// </summary>
     public class MonthlyCapacityLoadAppService : ApplicationService, IMonthlyCapacityLoadAppService, ITransientDependency
     {
+        #region 服务
+        /// <summary>
+        /// 物料
+        /// </summary>
+        private IRepository<ic_item, long> _ic_item;
+
+        /// <summary>
+        /// 整体需求计划明细
+        /// </summary>
+        private ISqlRepository<OverallDemandPlanDtl> _overallDemandPlanDtl;
+
+        /// <summary>
+        /// 生产线明细
+        /// </summary>
+        private ISqlRepository<ProdLineDetail> _prodLineDetail;
+
+        /// <summary>
+        /// 工作日历数据
+        /// </summary>
+        private ISqlRepository<ShopCalendarWorkCtr> _shopCalendarWorkCtr;
+
+        /// <summary>
+        /// 产线休息时间记录表
+        /// </summary>
+        private ISqlRepository<QualityLineWorkDetail> _qualityLineWorkDetail;
+
+        /// <summary>
+        /// 节假日记录表
+        /// </summary>
+        private ISqlRepository<HolidayMaster> _holidayMaster;
+
+        /// <summary>
+        /// 月度产能共识主表
+        /// </summary>
+        private ISqlRepository<MonthlyProdCapacityMain> _monthlyProdCapacityMain;
+
+        /// <summary>
+        /// 月度产能共识明细表
+        /// </summary>
+        private ISqlRepository<MonthlyProdCapacityDtl> _monthlyProdCapacityDtl;
+
+        /// <summary>
+        /// 标准物料规格型号设置表
+        /// </summary>
+        private ISqlRepository<StandardItemModelSet> _standardItemModelSet;
+
+        /// <summary>
+        /// 工作单元
+        /// </summary>
+        private readonly IUnitOfWorkManager _unitOfWorkManager;
+
+        /// <summary>
+        /// 日志
+        /// </summary>
+        private readonly ICurrentTenant _currentTenant;
+
+        /// <summary>
+        /// 雪花算法
+        /// </summary>
+        SnowFlake help = new SnowFlake();
+        #endregion
+
+        #region 构造函数
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        public MonthlyCapacityLoadAppService(
+            IRepository<ic_item, long> ic_item,
+            ISqlRepository<OverallDemandPlanDtl> overallDemandPlanDtl,
+            ISqlRepository<ProdLineDetail> prodLineDetail,
+            ISqlRepository<ShopCalendarWorkCtr> shopCalendarWorkCtr,
+            ISqlRepository<QualityLineWorkDetail> qualityLineWorkDetail,
+            ISqlRepository<HolidayMaster> holidayMaster,
+            ISqlRepository<MonthlyProdCapacityMain> monthlyProdCapacityMain,
+            ISqlRepository<MonthlyProdCapacityDtl> monthlyProdCapacityDtl,
+            IUnitOfWorkManager unitOfWorkManager,
+            ICurrentTenant currentTenant,
+            ISqlRepository<StandardItemModelSet> standardItemModelSet
+            ) 
+        { 
+            _ic_item= ic_item;
+            _overallDemandPlanDtl= overallDemandPlanDtl;
+            _prodLineDetail= prodLineDetail;
+            _shopCalendarWorkCtr= shopCalendarWorkCtr;
+            _qualityLineWorkDetail= qualityLineWorkDetail;
+            _holidayMaster= holidayMaster;
+            _monthlyProdCapacityMain= monthlyProdCapacityMain;
+            _monthlyProdCapacityDtl= monthlyProdCapacityDtl;
+            _unitOfWorkManager= unitOfWorkManager;
+            _currentTenant= currentTenant;
+            _standardItemModelSet= standardItemModelSet;
+        }
+        #endregion
+
         /// <summary>
         /// 产能分析
         /// </summary>
@@ -24,7 +132,136 @@ namespace Business.SaleForecastManagement
         /// <exception cref="NotImplementedException"></exception>
         public async Task<string> CapacityAnalysis(InputDto input)
         {
-            return "ok";
+            //1、获取数据
+            //1.1 根据年、月、版本号获取整体需求计划明细
+            List<OverallDemandPlanDtl> planDtls = _overallDemandPlanDtl.Select(p=>p.Year == input.year && p.Month == input.month && p.Version == input.version && p.tenant_id == input.tenant_id && p.factory_id == input.factory_id).OrderBy(p=>p.ProdLine).ThenBy(p=>p.ProdRange).ThenBy(p=>p.Model).ThenBy(p=>p.PlanDate).ToList();
+            //1.2 根据规格型号获取物料数据
+            List<string> models = planDtls.Select(p => p.Model).Distinct().ToList();
+            List<StandardItemModelSet> standards = _standardItemModelSet.Select(p=> models.Contains(p.Model) && p.tenant_id == input.tenant_id && p.factory_id == input.factory_id);
+            //1.3 根据物料编码获取产线数据
+            List<ProdLineDetail> lines = _prodLineDetail.Select(p => standards.Select(m => m.ItemNumber).Contains(p.Part) && p.Domain == input.factory_id.ToString() && p.IsActive);
+            //1.4 根据产线获取工作日历数据和产线休息配置数据
+            List<ShopCalendarWorkCtr> calendars = _shopCalendarWorkCtr.Select(p=> lines.Select(m=>m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
+            List<QualityLineWorkDetail> lineWorks = _qualityLineWorkDetail.Select(p => lines.Select(m => m.Line).Contains(p.ProdLine) && p.Domain == input.factory_id.ToString() && p.IsActive);
+            //1.5 获取当前年和下一年的节假日配置数据
+            List<HolidayMaster> holidays = _holidayMaster.Select(p => (p.Dated.Value.Year == input.year || p.Dated.Value.Year == (input.year + 1)) && p.Domain == input.factory_id.ToString() && p.IsActive);
+
+            //月度产能共识主表
+            List<MonthlyProdCapacityMain> capacityMains = new List<MonthlyProdCapacityMain>();
+            //月度产能共识明细表
+            List<MonthlyProdCapacityDtl> capacityDtls = new List<MonthlyProdCapacityDtl>();
+            foreach (var item in planDtls)
+            {
+                //获取当前产品的生产线
+                var std = standards.FirstOrDefault(p => p.Model == item.Model);
+                if (std == null)
+                {
+                    new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "规格型号【" + item.Model + "】没有维护标准物料数据", _currentTenant.Id.ToString());
+                    return "NO|规格型号【" + item.Model + "】没有维护标准物料数据,请维护后再发布!";
+                }
+                var curLines = lines.Where(p=>p.Part == std.ItemNumber).OrderBy(p => p.Line).ToList();
+                //过滤产线
+                var distLines = curLines.Select(p => p.Line).Distinct().ToList();
+                if (distLines.Count() == 0)
+                {
+                    new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "物料【" + std.ItemNumber + "】没有维护产线数据", _currentTenant.Id.ToString());
+                    return "NO|物料【" + std.ItemNumber + "】没有维护产线数据,请维护后再发布!";
+                }
+                foreach (var dl in distLines)
+                {
+                    //添加月度产能共识主表数据
+                    MonthlyProdCapacityMain main = new MonthlyProdCapacityMain();
+                    main.Id = help.NextId();
+                    main.Version = input.version;//整体需求计划版本号
+                    main.Year = Convert.ToInt16(item.PlanDate.Substring(0, 4));
+                    main.Month = Convert.ToInt16(item.PlanDate.Substring(4, 2));
+                    main.ProdRange = item.ProdRange;
+                    main.Model = item.Model;
+                    main.ProdQty = item.Qty;
+                    main.ProdLine = dl;
+                    main.Qty = item.Qty;
+                    main.tenant_id = item.tenant_id;
+                    main.factory_id = item.factory_id;
+                    main.Version = item.Version;
+                    main.CreateTime = DateTime.Now;
+                    capacityMains.Add(main);
+
+                    //添加月度产能共识产能效率数据
+                    MonthlyProdCapacityDtl dtl = new MonthlyProdCapacityDtl();
+                    dtl.MainId = main.Id;
+                    dtl.Version = input.version;
+                    dtl.Year = main.Year;
+                    dtl.Month = main.Month;
+                    dtl.ProdLine = dl;
+                    //计算每天工作时间
+                    var curCal = calendars.FirstOrDefault(p => p.ProdLine == dl);
+                    if (curCal == null) {
+                        continue;
+                    }
+                    dtl.DailyWorks = curCal.ShiftsHours1;
+                    dtl.FlightQty = 1;
+                    //计算当月工作天数
+                    var curHoildays = holidays.Where(p => p.Dated.Value.Year == main.Year && p.Dated.Value.Month == main.Month).ToList();
+                    //当月天数
+                    int days = DateTime.DaysInMonth(main.Year.Value, main.Month.Value);
+                    //当月周末天数
+                    int weekDays = CalcWeekDays(days,Convert.ToDateTime(main.Year.ToString()+"-"+main.Month.ToString()+"-01"));
+                    dtl.YearWorks= days-weekDays-curHoildays.Where(p=>p.Ufld1 == "休假").Count() + curHoildays.Where(p=>p.Ufld1 == "调班").Count();
+                    dtl.AvailableTimes= dtl.DailyWorks * dtl.FlightQty * dtl.YearWorks;
+                    //计算产线耗时
+                    var line = curLines.Where(p => p.Line == dl).OrderByDescending(p=>p.Op).First();
+                    dtl.NeedWorks= line.Rate == 0? 0:( Math.Ceiling(main.Qty.GetValueOrDefault() / line.Rate));
+                    dtl.ProdRate= 100;
+                    dtl.Rate= dtl.AvailableTimes == 0? 0: Math.Floor(dtl.NeedWorks.GetValueOrDefault()/ dtl.AvailableTimes.GetValueOrDefault() * 100);
+                    dtl.IsOverTime = dtl.NeedWorks > dtl.YearWorks ? "是" : "否";
+                    dtl.OverTimes = dtl.IsOverTime == "是" ? (dtl.NeedWorks - dtl.YearWorks) : 0;
+                    dtl.tenant_id = main.tenant_id;
+                    dtl.factory_id = main.factory_id;
+                    capacityDtls.Add(dtl);
+                }
+            }
+            //保存数据
+            using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
+            {
+                try
+                {
+                    //先删除数据
+                    _monthlyProdCapacityMain.Delete(p =>p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
+                    _monthlyProdCapacityDtl.Delete(p => p.tenant_id == input.tenant_id && p.factory_id == input.factory_id && p.Version.Contains(input.version.Substring(0, 7)));
+
+                    //插入数据
+                    _monthlyProdCapacityMain.Insert(capacityMains);
+                    _monthlyProdCapacityDtl.Insert(capacityDtls);
+                    await unitOfWork.CompleteAsync();
+                }
+                catch (Exception e)
+                {
+                    unitOfWork.Dispose();
+                    new NLogHelper("MonthlyCapacityLoadAppService").WriteLog("CapacityAnalysis", "生成【"+input.year+"年"+input.month+"月】月度产能共识失败:" + e.Message, _currentTenant.Id.ToString());
+                    return "NO|" + e.Message;
+                };
+            }
+            return "OK|发布成功!";
+        }
+
+        /// <summary>
+        /// 计算当月有多少个周末
+        /// </summary>
+        /// <param name="days"></param>
+        /// <param name="startDay"></param>
+        /// <returns></returns>
+        private int CalcWeekDays(int days, DateTime startDay)
+        {
+            int sumDays = 0;
+            for (int i = 0; i < days; i++)
+            {
+                int weekDays = (int)startDay.AddDays(i).DayOfWeek;
+                if (weekDays == 0 || weekDays == 6)
+                {
+                    sumDays++;
+                }
+            }
+            return sumDays;
         }
     }
 }

+ 25 - 0
MicroServices/Business/Business.EntityFrameworkCore/EntityFrameworkCore/DOP/BusinessDbContext.cs

@@ -148,6 +148,31 @@ namespace Business.EntityFrameworkCore
         public DbSet<LocationDetail> LocationDetail { get; set; }
 
         public DbSet<ItemPackMaster> ItemPackMaster { get; set; }
+
+        /// <summary>
+        /// 月度共识产能主表
+        /// </summary>
+        public DbSet<MonthlyProdCapacityMain> MonthlyProdCapacityMain { get; set; }
+
+        /// <summary>
+        /// 月度共识产能明细表
+        /// </summary>
+        public DbSet<MonthlyProdCapacityDtl> MonthlyProdCapacityDtl { get; set; }
+
+        /// <summary>
+        /// 整体需求计划主表
+        /// </summary>
+        public DbSet<OverallDemandPlanMain> OverallDemandPlanMain { get; set; }
+
+        /// <summary>
+        /// 整体需求计划明细表
+        /// </summary>
+        public DbSet<OverallDemandPlanDtl> OverallDemandPlanDtl { get; set; }
+
+        /// <summary>
+        /// 标准物料规格型号设置表
+        /// </summary>
+        public DbSet<StandardItemModelSet> StandardItemModelSet { get; set; }
         #endregion
 
         //Code generation...

+ 11 - 0
MicroServices/Business/Bussiness.Model/Production/MonthlyProdCapacityDtl.cs

@@ -24,6 +24,11 @@ namespace Business.Model.Production
         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
         public long Id { get; set; }
 
+        /// <summary>
+        /// 主表id
+        /// </summary>
+        public long MainId { get; set; }
+
         /// <summary>
         /// 年
         /// </summary>
@@ -107,5 +112,11 @@ namespace Business.Model.Production
         /// </summary>
         [Comment("工厂id")]
         public long? factory_id { get; set; }
+
+        /// <summary>
+        /// 整体需求计划版本号
+        /// </summary>
+        [Comment("整体需求计划版本号")]
+        public string? Version { get; set; }
     }
 }

+ 12 - 1
MicroServices/Business/Bussiness.Model/Production/MonthlyProdCapacityMain.cs

@@ -21,7 +21,6 @@ namespace Business.Model.Production
         /// </summary>
         [Comment("主键")]
         [Key]
-        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
         public long Id { get; set; }
 
         /// <summary>
@@ -77,5 +76,17 @@ namespace Business.Model.Production
         /// </summary>
         [Comment("工厂id")]
         public long? factory_id { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("创建时间")]
+        public DateTime? CreateTime { get; set; }
+
+        /// <summary>
+        /// 整体需求计划版本号
+        /// </summary>
+        [Comment("整体需求计划版本号")]
+        public string? Version { get; set; }
     }
 }

+ 7 - 1
MicroServices/Business/Bussiness.Model/Production/OverallDemandPlanDtl.cs

@@ -61,11 +61,17 @@ namespace Business.Model.Production
         public string? Model { get; set; }
 
         /// <summary>
-        /// 计划月份:M0,M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11
+        /// 计划月份
         /// </summary>
         [Comment("计划月份")]
         public string? PlanDate { get; set; }
 
+        /// <summary>
+        /// 月份计数:M0,M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11
+        /// </summary>
+        [Comment("月份计数")]
+        public string? MonthTimes { get; set; }
+
         /// <summary>
         /// 计划数量
         /// </summary>

+ 58 - 0
MicroServices/Business/Bussiness.Model/Production/StandardItemModelSet.cs

@@ -0,0 +1,58 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Business.Model.Production
+{
+    /// <summary>
+    /// 标准物料规格型号设置表
+    /// </summary>
+    [Comment("标准物料规格型号设置表")]
+    [Index(nameof(Model), nameof(tenant_id), nameof(factory_id), IsUnique = true)]
+    public class StandardItemModelSet
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Comment("主键")]
+        [Key]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 规格型号
+        /// </summary>
+        [Comment("规格型号")]
+        public string Model { get; set; }
+
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        [Comment("物料编码")]
+        public string ItemNumber { get; set; }
+
+        /// <summary>
+        /// 集团id
+        /// </summary>
+        [Comment("集团id")]
+        public long tenant_id { get; set; }
+
+        /// <summary>
+        /// 工厂id
+        /// </summary>
+        [Comment("工厂id")]
+        public long factory_id { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        [Comment("创建时间")]
+        public DateTime CreateTime { get; set; }
+    }
+}