Files
Backend-Api/CompanyManagment.EFCore/Repository/ClassificationSchemeRepository.cs
2026-01-04 15:35:06 +03:30

609 lines
26 KiB
C#

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<long, Company.Domain.ClassificationSchemeAgg.ClassificationScheme>, IClassificationSchemeRepository
{
private readonly CompanyContext _context;
public ClassificationSchemeRepository(CompanyContext context) : base(context)
{
_context = context;
}
public async Task<ClassificationSchemeListDto> 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
};
}
/// <summary>
/// دریافت اطلاعات طرح برای ویرایش
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Task<EditClassificationSchemeDto> 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);
}
/// <summary>
/// دریافت اطلاعات طر برای محاسبات
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Task<EditClassificationScheme> 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);
}
/// <summary>
/// متد محاسبه پایه سنوات برا افراد تک گروه
/// </summary>
/// <param name="schemeStart">تاریخ شروع طرح</param>
/// <param name="schemeEnd">تاریخ پاین طرح، اجباری نیست</param>
/// <param name="contractStart">تاریخ شروع قراداد</param>
/// <param name="contractEnd">تاریخ پایان قراداد</param>
/// <param name="groupNo">شماره گروه</param>
/// <param name="employeeId">آی دی پرسنل</param>
/// <param name="workshopId">آی دی کارگاه</param>
/// <returns></returns>
public async Task<BaseYearDataViewModel> 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<DateTime, DateTime, string>(group.StartGroupDate.Value, contractEnd, group.GroupNo));
}
else
{
var endOfGroup = employeeGroupMemberData.Last().startGroupDate.AddDays(-1);
employeeGroupMemberData.Add(new ValueTuple<DateTime, DateTime, string>(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<DateTime>();
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();
}
}
/// <summary>
/// متد کمکی پایه سنوات
/// </summary>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
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;
}
}