using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application; using _0_Framework.InfraStructure; using Company.Domain.ClassificationSchemeAgg; using CompanyManagment.App.Contracts.ClassificationScheme; using CompanyManagment.App.Contracts.LeftWork; using CompanyManagment.App.Contracts.YearlySalary; using Microsoft.EntityFrameworkCore; using PersianTools.Core; namespace CompanyManagment.EFCore.Repository; public class ClassificationSchemeRepository :RepositoryBase, IClassificationSchemeRepository { private readonly CompanyContext _context; public ClassificationSchemeRepository(CompanyContext context) : base(context) { _context = context; } public async Task GetClassificationSchemeList(long workshopId) { var hasScheme =await _context.ClassificationSchemes.AnyAsync(x => x.WorkshopId == workshopId); if (!hasScheme) return new ClassificationSchemeListDto() { HasScheme = false, }; var schemeList =await _context.ClassificationSchemes.Where(x => x.WorkshopId == workshopId).Select(x => new SchemeListDto() { Id = x.id, IncludingDateFa = x.IncludingDateGr.ToFarsi(), ExecutionDateFa = x.ExecutionDateGr.ToFarsi(), DesignerFullName = x.DesignerFullName, }).ToListAsync(); return new ClassificationSchemeListDto() { HasScheme = true, WorkshopId = workshopId, ClassificationSchemesList = schemeList }; } /// /// دریافت اطلاعات طرح برای ویرایش /// /// /// public Task GetClassificationScheme(long id) { return _context.ClassificationSchemes.Select(x => new EditClassificationSchemeDto() { Id = x.id, IncludingDateFa = x.IncludingDateGr.ToFarsi(), ExecutionDateFa = x.ExecutionDateGr.ToFarsi(), DesignerFullName = x.DesignerFullName, DesignerPhone = x.DesignerPhone, TypeOfCoefficient = x.TypeOfCoefficient }).FirstOrDefaultAsync(x => x.Id == id); } /// /// دریافت اطلاعات طر برای محاسبات /// /// /// public Task GetClassificationSchemeToCompute(long id) { return _context.ClassificationSchemes.Select(x => new EditClassificationScheme() { Id = x.id, WorkshopId = x.WorkshopId, ExecutionDateGr = x.ExecutionDateGr, EndSchemeDateGr = x.EndSchemeDateGr, IncludingDateFa = x.IncludingDateGr.ToFarsi(), ExecutionDateFa = x.ExecutionDateGr.ToFarsi(), DesignerFullName = x.DesignerFullName, DesignerPhone = x.DesignerPhone, TypeOfCoefficient = x.TypeOfCoefficient }).FirstOrDefaultAsync(x => x.Id == id); } /// /// متد محاسبه پایه سنوات برا افراد تک گروه /// /// تاریخ شروع طرح /// تاریخ پاین طرح، اجباری نیست /// تاریخ شروع قراداد /// تاریخ پایان قراداد /// شماره گروه /// آی دی پرسنل /// آی دی کارگاه /// public async Task BaseYearComputeOneGroup(DateTime schemeStart, DateTime? schemeEnd, DateTime contractStart, DateTime contractEnd, string groupNo, long employeeId, long workshopId) { //خروجی متد var baseYearResult = new BaseYearDataViewModel(); baseYearResult.WorkshopId = workshopId; baseYearResult.EmployeeId = employeeId; //بدست آوردن اطلاعات گروهبندی پرسنل var employeeGroupMember = await _context.ClassificationEmployees.Include(x=>x.ClassificationGroup) .Where(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId).OrderBy(x=>x.StartGroupDate) .Select(x=> new{x.StartGroupDate, x.EndGroupDate, x.ClassificationGroup.GroupNo}) .OrderByDescending(x=>x.StartGroupDate) .ToListAsync(); var employeeGroupMemberData = new List<(DateTime startGroupDate, DateTime EndGroupDate, string GroupNo)>(); if (employeeGroupMember.Any()) { var lastGroup = employeeGroupMember.FirstOrDefault(); foreach (var group in employeeGroupMember) { if (group == lastGroup) { employeeGroupMemberData.Add(new ValueTuple(group.StartGroupDate.Value, contractEnd, group.GroupNo)); } else { var endOfGroup = employeeGroupMemberData.Last().startGroupDate.AddDays(-1); employeeGroupMemberData.Add(new ValueTuple(group.StartGroupDate.Value, endOfGroup, group.GroupNo)); } } } //لیست شروع بکار / ترک کار پرسنل var leftWorkList = await _context.LeftWorkList .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId).Select(x=> new LeftWorkViewModel { Id = x.id, StartWorkDateGr = x.StartWorkDate, StartWorkDate = x.StartWorkDate.ToFarsi(), LeftWorkDateGr = x.LeftWorkDate, HasLeft = x.HasLeft, }).OrderBy(x=>x.StartWorkDateGr).ToListAsync(); //اولین شروع بکار var firstStartWorkDate = leftWorkList.First().StartWorkDateGr; var firstStartWork = leftWorkList.First().StartWorkDate; //اگر شروع طرح بعد از اولین شروع بکار بود if (schemeStart > firstStartWorkDate) { var leftWorkStart = leftWorkList.FirstOrDefault(x => x.StartWorkDateGr <= schemeStart && x.LeftWorkDateGr > schemeStart); if (leftWorkStart != null) { //اگر تاریخ شروع طرح بین بازه اولین شروع بکار و ترک کار قرار گرفت if (leftWorkStart.StartWorkDateGr == firstStartWorkDate) { var changedLeftwork = new LeftWorkViewModel() { Id = leftWorkStart.Id, StartWorkDateGr = schemeStart, StartWorkDate = schemeStart.ToFarsi(), LeftWorkDateGr = leftWorkStart.LeftWorkDateGr, HasLeft = leftWorkStart.HasLeft, }; leftWorkList.Remove(leftWorkStart); leftWorkList.Add(changedLeftwork); firstStartWork = schemeStart.ToFarsi(); } else //اگر تاریخ شروع طرح در بازه شروع به ترک کارهایی بعد از اولین قرارگرفت { //لیست شروع بکار/ ترک کارهایی که باید حذف شوند var leftWorksToBeRemove = leftWorkList.Where(x => x.StartWorkDateGr < leftWorkStart.StartWorkDateGr) .ToList(); foreach (var item in leftWorksToBeRemove.ToList()) { leftWorkList.Remove(item); } var changedLeftwork = new LeftWorkViewModel() { Id = leftWorkStart.Id, StartWorkDateGr = schemeStart, StartWorkDate = schemeStart.ToFarsi(), LeftWorkDateGr = leftWorkStart.LeftWorkDateGr, HasLeft = leftWorkStart.HasLeft, }; firstStartWork = schemeStart.ToFarsi(); leftWorkList.Remove(leftWorkStart); leftWorkList.Add(changedLeftwork); } } else //اگر شروع طرح در فاصله بین شروع بکار/ترک کارها بود { //لیست شروع بکار/ ترک کارهایی که باید حذف شوند var leftWorksToBeRemove = leftWorkList.Where(x => x.StartWorkDateGr < schemeStart) .ToList(); foreach (var item in leftWorksToBeRemove.ToList()) { leftWorkList.Remove(item); } leftWorkList = leftWorkList.OrderBy(x => x.StartWorkDateGr).ToList(); firstStartWork = leftWorkList.First().StartWorkDate; } } //مرتب سازی leftWorkList = leftWorkList.OrderBy(x => x.StartWorkDateGr).ToList(); //مقادیر سالانه var salary = await _context.YearlySalaries.OrderByDescending(x => x.EndDate).Include(x => x.YearlySalaryItemsList).ToListAsync(); //مزد سنوات طبقه بندی var classifiedBaseYearList =await _context.ClassifiedSalaries.ToListAsync(); //آیا در حلقه کبیشه بودن چک شود bool checkKabiseh = true; var isKabiseh = false; var EndOfYaerDate = new DateTime(); //لیست تاریخ هایی که پایه سنوات تعلق گرفته var baseYearDateList = new List(); double baseYear = 0; //اگر تاریخ پایان طرح خالی نبود if (schemeEnd.HasValue) { //اگر تاریخ پایان طرخ از تاریخ پایان قرارداد کوچکتر بود //در نتیجه تاریخ پاینه محاسبات همان پایان طرح است if (schemeEnd.Value < contractEnd) contractEnd = schemeEnd.Value; } //اگر فقط یک شروع بکار داشت if (leftWorkList.Count < 2) { var leftWork = leftWorkList.First(); //اگر ترک کار کرده بود پایان چرخه تاریخ آخرین روز کاری اوست var endComputeDate = leftWork.HasLeft && leftWork.LeftWorkDateGr <= contractEnd ? leftWork.LeftWorkDateGr.AddDays(-1) : contractEnd; //شروع چرخه شروع بکار پرسنل var startComputeDate = leftWork.StartWorkDateGr; for (var current = startComputeDate; current <= endComputeDate; current = current.AddDays(1)) { var currentChanges = new DateTime(current.Year, current.Month, current.Day); if (checkKabiseh) { isKabiseh = ($"{current.ToFarsi()}").YearTotalDays() == 367 ? true : false; string kabise = ""; if (isKabiseh) kabise = "kabise"; var currentChangesPc = currentChanges.ToPersianDateTime(); EndOfYaerDate = isKabiseh ? ($"{currentChangesPc.AddDays(365)}").ToGeorgianDateTime() : ($"{currentChangesPc.AddDays(364)}").ToGeorgianDateTime(); Console.WriteLine($" start : {current.ToFarsi()} {kabise}"); } checkKabiseh = false; if (current == EndOfYaerDate) { var a = current.AddDays(1); if (a <= endComputeDate) { checkKabiseh = true; baseYearDateList.Add(a); Console.WriteLine($" End : {a.ToFarsi()}"); } } } } else //اگر بیش از یک شروع بکار داشت { int max365 = 0; int dayCounter = 0; bool hasCute = false; foreach (var leftWork in leftWorkList) { //اگر ترک کار کرده بود پایان چرخه تاریخ آخرین روز کاری اوست var endComputeDate = leftWork.HasLeft && leftWork.LeftWorkDateGr <= contractEnd ? leftWork.LeftWorkDateGr.AddDays(-1) : contractEnd; //شروع چرخه شروع بکار پرسنل var startComputeDate = leftWork.StartWorkDateGr; for (var current = startComputeDate; current <= endComputeDate; current = current.AddDays(1)) { if (checkKabiseh && dayCounter == 0) { isKabiseh = ($"{current.ToFarsi()}").YearTotalDays() == 367 ? true : false; string kabise = ""; if (isKabiseh) kabise = "kabise"; max365 = isKabiseh ? 366 : 365; Console.WriteLine($" start : {current.ToFarsi()} {kabise}"); } dayCounter += 1; checkKabiseh = false; if (dayCounter == max365) { var a = !hasCute ? current.AddDays(1) : current; if (a <= endComputeDate) { checkKabiseh = true; baseYearDateList.Add(a); Console.WriteLine($" End : {a.ToFarsi()}"); Console.WriteLine(dayCounter); if (hasCute) { dayCounter = 1; isKabiseh = ($"{current.ToFarsi()}").YearTotalDays() == 367 ? true : false; max365 = isKabiseh ? 366 : 365; string kabise = ""; if (isKabiseh) kabise = "kabise"; Console.WriteLine($" start : {current.ToFarsi()} {kabise}"); } else { dayCounter = 0; } hasCute = false; } else { hasCute = true; max365 += 1; } } } } } double selectBase = 0; var baseList = new List<(double baseYaer, DateTime start, DateTime end, string baseYearPay, DateTime baseYearPayGr, string year, bool hasStartWork, bool hasLeftWork, string groupNo)>(); if (baseYearDateList.Count > 0) { var firstBaseYearDate = baseYearDateList.First(); var res = MonthByMonthList(firstBaseYearDate, contractEnd); var firstbasicSalari = salary.FirstOrDefault(x => x.StartDate <= firstBaseYearDate && x.EndDate >= firstBaseYearDate); var firstClassifiedBaseYear = classifiedBaseYearList.FirstOrDefault(x => x.StartDate <= firstBaseYearDate && x.EndDate >= firstBaseYearDate); //پایه سنوات سال جاری var firstGroupData = employeeGroupMemberData.FirstOrDefault(x => x.startGroupDate <= firstBaseYearDate && x.EndGroupDate >= firstBaseYearDate); groupNo = firstGroupData.GroupNo; var firstBasicObject = Tools.GetDynamicDouble(firstClassifiedBaseYear, $"Group{groupNo}"); double firstBasic = firstBasicObject != null ? firstBasicObject.Value : 0; var firstfixFeePercentage = firstbasicSalari .YearlySalaryItemsList.Where(x => x.ItemName == "درصد مزد ثابت").Select(x => x.ItemValue).FirstOrDefault(); // پایه سنوات سال قبل ضربدر درصد مزد ثابت تقسیم بر صد //var beforePercntBaseYear = ((beforBaseStart * firstfixFeePercentage) / 100) + beforBaseStart; //firstBasic += beforePercntBaseYear; baseYear = firstBasic; res = res.Where(x => x.start != firstBaseYearDate).OrderBy(x => x.start).ToList(); //var afterSalary = salary.Where(x => x.StartDate > firstbasicSalari.EndDate).ToList(); var first = (firstBasic, firstbasicSalari.StartDate, firstbasicSalari.EndDate, firstBaseYearDate.ToFarsi(), firstBaseYearDate, firstbasicSalari.Year, false, false, $"گروه {groupNo}"); baseList.Add(first); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{1398} -> firstBasic : {firstBasic}"); var lastItem = res.Count > 1 ? res.Last() : res.FirstOrDefault(); foreach (var item in res) { var lastReecord = baseList.Last(); var year = Convert.ToInt32(item.start.ToFarsi().Substring(0, 4)); if (item.start > lastReecord.end && lastReecord.year != $"{year}") { var selectedSalary = salary.Where(x => x.Year == $"{year}").OrderBy(x => x.StartDate).ToList(); var currentSalary = selectedSalary.First(); if (selectedSalary.Count > 1) { currentSalary = selectedSalary.Last(); var firstSalery = selectedSalary.First(); if (baseYearDateList.Any(x => x >= firstSalery.StartDate && x <= firstSalery.EndDate) || lastItem.end < currentSalary.StartDate) { currentSalary = firstSalery; } } var selectedBaseYear = classifiedBaseYearList.Where(x => x.Year == year).OrderBy(x => x.StartDate).ToList(); var currentBaseYear = selectedBaseYear.First(); if (selectedBaseYear.Count > 1) { currentBaseYear = selectedBaseYear.Last(); var firstBaseYear = selectedBaseYear.First(); if (baseYearDateList.Any(x => x >= firstBaseYear.StartDate && x <= firstBaseYear.EndDate) || lastItem.end < currentBaseYear.StartDate) { currentBaseYear = firstBaseYear; } } //درصد مزد ثابت تاریخ جاری var fixFeePercentage = currentSalary .YearlySalaryItemsList.Where(x => x.ItemName == "درصد مزد ثابت").Select(x => x.ItemValue).FirstOrDefault(); // پایه سنوات سال قبل ضربدر درصد مزد ثابت تقسیم بر صد var percntBaseYear = ((lastReecord.baseYaer * fixFeePercentage) / 100) + lastReecord.baseYaer; Console.ForegroundColor = ConsoleColor.Green; var transferGroupData = employeeGroupMemberData.FirstOrDefault(x => x.startGroupDate <= currentBaseYear.EndDate && x.EndGroupDate >= currentBaseYear.StartDate); groupNo = transferGroupData.GroupNo; var currentBasicObject = Tools.GetDynamicDouble(currentBaseYear, $"Group{groupNo}"); double currentBasic = currentBasicObject != null ? currentBasicObject.Value : 0; //var currentBasic = currentSalary // .YearlySalaryItemsList.Where(x => x.ItemName == "پایه سنوات").Select(x => x.ItemValue).FirstOrDefault(); Console.WriteLine($"{year} -> [{lastReecord.baseYaer} * {fixFeePercentage} /100 + {lastReecord.baseYaer}] = {percntBaseYear} => [{currentBasic} + {percntBaseYear}] = {currentBasic + percntBaseYear} "); if (!baseYearDateList.Any(x => x >= currentBaseYear.StartDate && x <= currentBaseYear.EndDate)) currentBasic = 0; var currentBase = currentBasic + percntBaseYear; baseYear = currentBase; var baseYearPay = "-"; var baseYearPayDayGr = new DateTime(); if (baseYearDateList.Any(x => x >= currentBaseYear.StartDate && x <= currentBaseYear.EndDate)) { var existBaseYear = baseYearDateList.FirstOrDefault(x => x >= currentBaseYear.StartDate && x <= currentBaseYear.EndDate); baseYearPay = existBaseYear.ToFarsi(); baseYearPayDayGr = new DateTime(existBaseYear.Year, existBaseYear.Month, existBaseYear.Day, 17, 01, 01); } else { baseYearPayDayGr = new DateTime(item.start.Year, item.start.Month, item.start.Day, 17, 01, 01); } Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine(baseYearPay); Console.ResetColor(); // var round = GetCurrectFirstDailyFee(currentBase, $"{year}"); var record = (baseYear, currentSalary.StartDate, currentSalary.EndDate, baseYearPay, baseYearPayDayGr, currentSalary.Year, false, false, $"گروه {groupNo}"); baseList.Add(record); } } Console.ResetColor(); } selectBase = baseList.Any() ? baseList.Last().baseYaer : 0; //افزودن تاریخ های شروع بکار و ترک کار به لیست foreach (var left in leftWorkList) { var startWork = (0, new DateTime(), new DateTime(), left.StartWorkDateGr.ToFarsi(), left.StartWorkDateGr, "-", true, false, ""); baseList.Add(startWork); if (left.HasLeft) { var leftWork = (0, new DateTime(), new DateTime(), left.LeftWorkDateGr.ToFarsi(), left.LeftWorkDateGr, "-", false, true, ""); baseList.Add(leftWork); } } baseYearResult = new BaseYearDataViewModel() { WorkshopId = workshopId, EmployeeId = employeeId, BaseYearResult = selectBase, FirstWorkDayInLeftWork = firstStartWork, BaseYearDataList = baseList.Select(x => new BaseYearDataList() { BaseYear = x.baseYaer, StartDateGr = x.start, EndDateGr = x.end, BaseYearPayDay = x.baseYearPay, BaseYearPayDayGr = x.baseYearPayGr, StartDateFa = x.start.ToFarsi(), EndDateFa = x.end.ToFarsi(), Year = x.year, HasLeftWork = x.hasLeftWork, HasStartWork = x.hasStartWork, GroupNo = x.groupNo, }).OrderBy(x => x.BaseYearPayDayGr).ToList(), }; Console.WriteLine("BaseYear : " + selectBase); return baseYearResult; } public async Task DeleteClassificationScheme(long id) { var scheme = Get(id); if (scheme != null) { _context.Remove(scheme); await _context.SaveChangesAsync(); } } /// /// متد کمکی پایه سنوات /// /// /// /// private List<(DateTime start, DateTime end)> MonthByMonthList(DateTime startDate, DateTime endDate) { var start = startDate.ToFarsi(); var end = endDate.ToFarsi(); var ContractPreiodsList = new List<(DateTime start, DateTime end)>(); var syear = Convert.ToInt32(start.Substring(0, 4)); var smonth = Convert.ToInt32(start.Substring(5, 2)); var sday = Convert.ToInt32(start.Substring(8, 2)); var eyear = Convert.ToInt32(end.Substring(0, 4)); var emonth = Convert.ToInt32(end.Substring(5, 2)); var eday = Convert.ToInt32(end.Substring(8, 2)); var PersianStartDate = new PersianDateTime(syear, smonth, sday); var PersianStartDateAddingMount = new PersianDateTime(syear, smonth, 1); var PersianEndDate = new PersianDateTime(eyear, emonth, eday); var totalmonth = ((PersianEndDate.Year - PersianStartDateAddingMount.Year) * 12) + (PersianEndDate.Month - PersianStartDateAddingMount.Month) + 1; for (int i = 0; i < totalmonth; i++) { var currentEndDate = PersianStartDateAddingMount.AddMonths(1).AddDays(-1); if (currentEndDate > PersianEndDate) { currentEndDate = PersianEndDate; } DateTime startPeriod = ($"{PersianStartDate}").ToGeorgianDateTime(); DateTime endPeriod = ($"{currentEndDate}").ToGeorgianDateTime(); var record = (startPeriod, endPeriod); ContractPreiodsList.Add(record); //Console.WriteLine($"Month {i + 1} : {PersianStartDate.ToString("yyyy-MM-dd")} to {currentEndDate.ToString("yyyy-MM-dd")}"); PersianStartDate = PersianStartDate.AddMonths(1); PersianStartDate = new PersianDateTime(PersianStartDate.Year, PersianStartDate.Month, 1); } return ContractPreiodsList; } }