From 27196393332a43ef1662e246ce15296b9b2e3562 Mon Sep 17 00:00:00 2001 From: Mahan Ch Date: Fri, 23 May 2025 20:30:41 +0330 Subject: [PATCH] change CWS for kebab mahdi --- .../Repository/RollCallMandatoryRepository.cs | 9237 +++++++++-------- CompanyManagment.EFCore/TestDbContext.cs | 5 + 2 files changed, 4643 insertions(+), 4599 deletions(-) diff --git a/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs b/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs index fe288890..83a3e098 100644 --- a/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs +++ b/CompanyManagment.EFCore/Repository/RollCallMandatoryRepository.cs @@ -41,4880 +41,4919 @@ namespace CompanyManagment.EFCore.Repository; public class RollCallMandatoryRepository : RepositoryBase, IRollCallMandatoryRepository { - private readonly CompanyContext _context; - private readonly IYearlySalaryRepository _yearlySalaryRepository; - private readonly ILeftWorkRepository _leftWorkRepository; - private readonly ILeaveRepository _leaveRepository; - private readonly IHolidayItemRepository _holidayItemRepository; - - - public RollCallMandatoryRepository(CompanyContext context, IYearlySalaryRepository yearlySalaryRepository, - ILeftWorkRepository leftWorkRepository, ILeaveRepository leaveRepository, IHolidayItemRepository holidayItemRepository) : base(context) - { - _context = context; - _yearlySalaryRepository = yearlySalaryRepository; - _leftWorkRepository = leftWorkRepository; - _leaveRepository = leaveRepository; - _holidayItemRepository = holidayItemRepository; - } - - #region OfficialChckout - public ComputingViewModel MandatoryCompute(long employeeId, long workshopId, DateTime contractStart, - DateTime contractEnd, - CreateWorkingHoursTemp command, bool holidayWorking,bool isStaticCheckout) - { - #region Entities - - string SumWorkeTime = string.Empty; - var weeklyTime = new TimeSpan(); - string shift1Hourse = "0"; - string overMandatoryHours = "0"; - string overMandatoryMinuts = "0"; - string shiftOver22Hours = "0"; - string shiftOver22Minuts = "0"; - double ShiftPayResult = 0; - int numberOfFridays = 0; - #endregion - - int TotalContractDays = (int)(contractEnd - contractStart).TotalDays + 1; - int fridays = 0; - int holiday = _context.HolidayItems.Count(x => x.Holidaydate >= contractStart && x.Holidaydate <= contractEnd); - ; - for (var gDate = contractStart; gDate <= contractEnd; gDate = gDate.AddDays(1)) - { - if (gDate.DayOfWeek == DayOfWeek.Friday) - { - fridays += 1; - } - } - int TotalDaysNoFriday = TotalContractDays - fridays; - int mandatorDays = TotalContractDays - (fridays + holiday); - if (command.ShiftWork != "4" && isStaticCheckout) - mandatorDays = TotalDaysNoFriday; - //if (holidayWorking) - // mandatorDays = TotalContractDays - fridays; - //***********************************// - //This Time Mandatory Hourse - double mandatoryHours = Math.Round((mandatorDays * 7.33), 2); - - //گرفتن ساعت استراحت پرسنل از تنظیمات - #region breakTime - BaseCustomizeEntity settings = _context.CustomizeWorkshopEmployeeSettings.AsSplitQuery() - .Include(x => x.CustomizeWorkshopGroupSettings).FirstOrDefault(x => - x.WorkshopId == workshopId && x.EmployeeId == employeeId); - //اگر ساعت استراحت پرسنل وجود نداشت صفر است - var breakTime = settings == null ? new BreakTime(false, new TimeOnly()) : settings.BreakTime; - - - #endregion - - List rollCallResult; - List groupedRollCall; - if (isStaticCheckout) - { - command.WorkshopId = workshopId; - command.EmployeeId = employeeId; - command.ContractStartGr = contractStart; - command.ContractEndGr = contractEnd; - rollCallResult = ConvertStaticHoursToRollCall(command, holidayWorking); - groupedRollCall = rollCallResult.GroupBy(x => x.ShiftDate.Date).Select(x => new GroupedRollCalls() - { - CreationDate = x.Key, - ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), - HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), - - SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - - }).OrderBy(x => x.CreationDate).ToList(); - } - else - { - rollCallResult = _context.RollCalls.Where(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate.Value.Date >= contractStart.Date && - x.StartDate.Value.Date <= contractEnd.Date && x.EndDate != null).Select(x => new RollCallViewModel() - { - StartDate = x.StartDate, - EndDate = x.EndDate, - ShiftSpan = (x.EndDate.Value - x.StartDate.Value), - CreationDate = x.ShiftDate, - BreakTimeSpan = x.BreakTimeSpan - }).ToList(); - - groupedRollCall = rollCallResult.GroupBy(x => x.CreationDate.Date).Select(x => new GroupedRollCalls() - { - CreationDate = x.Key, - ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), - HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), - SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - CalculateBreakTime(x.First().BreakTimeSpan, - new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), - - BreakTime = CalculateBreakTime(x.First().BreakTimeSpan, new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), - - }).OrderBy(x => x.CreationDate).ToList(); - } - - - numberOfFridays = groupedRollCall.Count(x => x.HasFriday); - - ////*****کسر ساعاعت استراحت پرسنل از ساعت کار - //List rollCallSubtractSpan = groupedRollCall.Select(x => new GroupedRollCalls() - //{ - // CreationDate = x.CreationDate, - // AfterSubtractRestSpan = AfterSubtract(command, x.SumOneDaySpan, x.CreationDate), - //}).ToList(); - - - - - TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); - TimeSpan sumSpansWhitOutleaves = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); - - - //بدست آوردن مرخصی ساعتی - LeaveSearchModel hoursleaveSearch = new LeaveSearchModel() - { - EmployeeId = employeeId, - WorkshopId = workshopId, - LeaveType = "استحقاقی", - PaidLeaveType = "ساعتی", - StartLeaveGr = contractStart, - EndLeaveGr = contractEnd, - IsAccepted = true, - }; - var hoursesleave = _leaveRepository.search(hoursleaveSearch); - var hoursesleaveTimeSpansList = hoursesleave.Count > 0 - ? hoursesleave.Select(x => TimeSpan.Parse(x.LeaveHourses)).ToList() - : new List(); - - // مجموع مرخصی ساعتی - var hoursesleaveTimeSpans = new TimeSpan(hoursesleaveTimeSpansList.Sum(x => x.Ticks)); - //کسر مرخصی ساعتی از فیش استاتیک - if (isStaticCheckout && command.ShiftWork != "4") - { - // کم کردن از مجموع ساعت کار پرسنل - sumSpans = sumSpans.Subtract(hoursesleaveTimeSpans); - - } - - - - //****افزودن مرخصی پرسنل به مجموع ساعات کار*** - #region AddEmployeeLeavs - - - LeaveSearchModel leaveSearch = new LeaveSearchModel() - { - EmployeeId = employeeId, - WorkshopId = workshopId, - LeaveType = "استحقاقی", - PaidLeaveType = "روزانه", - StartLeaveGr = contractStart, - EndLeaveGr = contractEnd, - IsAccepted = true, - }; - var leaveSearchResult = _leaveRepository.search(leaveSearch); - // {مقدار ساعت مجاز مرخصی در برای یک روز{کامل - var leaveHoursesPerDay = 190.58 / 365; - - // {مقدار ساعت مجاز مرخصی در مدت این فیش حقوقی{کامل - var starndardHoursesPerTotalDays = leaveHoursesPerDay * TotalContractDays; - // جدا کردن ساعت و دقیقه - int hours = (int)starndardHoursesPerTotalDays; - double minutesDecimal = (starndardHoursesPerTotalDays - hours) * 60; - int minutes = (int)minutesDecimal; - - - TimeSpan starndardHoursesPerTotalDaysSapn = new TimeSpan(hours, minutes, 0); - if (leaveSearchResult.Count > 0) - { - if (leaveSearchResult.Any(x => x.HasShiftDuration)) - { - var sumSpansDouble = (sumSpans.TotalMinutes) / 60; - if (sumSpansDouble < mandatoryHours) - { - starndardHoursesPerTotalDays = (sumSpansDouble * starndardHoursesPerTotalDays) / mandatoryHours; - // جدا کردن ساعت و دقیقه - hours = (int)starndardHoursesPerTotalDays; - minutesDecimal = (starndardHoursesPerTotalDays - hours) * 60; - minutes = (int)minutesDecimal; - - - starndardHoursesPerTotalDaysSapn = new TimeSpan(hours, minutes, 0); - } - - TimeSpan totalLeave = new TimeSpan(leaveSearchResult.Sum(x => x.ShiftDuration.Ticks)); - totalLeave = totalLeave.Add(hoursesleaveTimeSpans); - var totalLeaveDouble = (totalLeave.TotalMinutes) / 60; - if (totalLeaveDouble > starndardHoursesPerTotalDays) - { - - sumSpans = sumSpans.Add(starndardHoursesPerTotalDaysSapn); - } - else - { - sumSpans = sumSpans.Add(totalLeave); - } - - - - } - else - { - int leavingDayCout = 0; - //مرخصی های مابین - List beatweenCheckout = leaveSearchResult.Where(x => x.StartLeaveGr >= contractStart && x.EndLeaveGr <= contractEnd).Select(x => new LeaveViewModel() - { - DayCounter = Convert.ToInt32(x.LeaveHourses), - - }).ToList(); - leavingDayCout += beatweenCheckout.Sum(x => x.DayCounter); - // مرخصی که شروعش قبل از شروع تصفیه حساب است - List beforeCheckout = leaveSearchResult.Where(x => x.StartLeaveGr < contractStart).Select(x => new LeaveViewModel() - { - DayCounter = (int)(contractStart - x.EndLeaveGr).TotalDays + 1, - - }).ToList(); - leavingDayCout += beforeCheckout.Sum(x => x.DayCounter); - // مرخصی که پایانش بعد از پایان تصفیه حساب است - List afterCheckout = leaveSearchResult.Where(x => x.EndLeaveGr > contractEnd).Select(x => new LeaveViewModel() - { - DayCounter = (int)(x.StartLeaveGr - contractEnd).TotalDays + 1, - - }).ToList(); - leavingDayCout += afterCheckout.Sum(x => x.DayCounter); - Console.WriteLine(leavingDayCout); - - - TimeSpan workingPerDayAve = sumSpans / groupedRollCall.Count;//میانگین ساعت کار در روز - TimeSpan sumLeave = new TimeSpan(); - if (workingPerDayAve <= new TimeSpan(7, 20, 0)) - { - sumLeave = leavingDayCout * workingPerDayAve; - sumLeave = sumLeave.Add(hoursesleaveTimeSpans); - } - else - { - sumLeave = leavingDayCout * new TimeSpan(7, 20, 0); - } - - - if (sumLeave > starndardHoursesPerTotalDaysSapn) - { - sumSpans = sumSpans.Add(starndardHoursesPerTotalDaysSapn); - } - else - { - sumSpans = sumSpans.Add(sumLeave); - } - } - - - } - //اگر مرخصی روزانه نداشت و فقط مرخصی ساعتی داشت - if (leaveSearchResult.Count == 0 && hoursesleave.Count > 0) - { - if (hoursesleaveTimeSpans > starndardHoursesPerTotalDaysSapn) - { - sumSpans = sumSpans.Add(starndardHoursesPerTotalDaysSapn); - } - else - { - sumSpans = sumSpans.Add(hoursesleaveTimeSpans); - } - } - Console.WriteLine(sumSpans); - #endregion - //***********************************// - //ToTalHourse Employe eWorked - double totalHourses = (sumSpans.TotalMinutes) / 60; - int totalHolidaysAndNotH = (int)sumSpans.TotalHours; - int totalHolidaysAndNotM = (int)(sumSpans.TotalMinutes % 60); - //***********************************// - - - //********** محاسبه مدت اضافه کاری ***********// - #region ComputeMandatoryAtThisTime - - - - //***********************************// - var dailyFix = TimeSpan.Parse("07:20"); - TimeSpan mandatoryHoursTimeSpan = new TimeSpan(7, 20, 0).Multiply(mandatorDays); - TimeSpan Mandatory = sumSpansWhitOutleaves.Subtract(mandatoryHoursTimeSpan); - - double mandatoryWorkWithOutleaves = (sumSpansWhitOutleaves.TotalMinutes) / 60; - double overTimeWork = 0; - if (mandatoryWorkWithOutleaves > mandatoryHours) - { - overTimeWork = mandatoryWorkWithOutleaves - mandatoryHours; - - } - - - #endregion - - //******* دستمزد روزانه *******// - #region DailyFeeCompute - - var searchModel = new LeftWorkSearchModel() - { - EmployeeId = command.EmployeeId, - WorkshopId = command.WorkshopId, - - }; - - var leftworkList = _leftWorkRepository.search(searchModel); - var basic = "0"; - double dayliFeeComplete = 0; - var GetWorkStartDate = command.GetWorkDateHide.ToEnglishNumber(); - var styear = Convert.ToInt32(GetWorkStartDate.Substring(0, 4)); - var startDate = command.GetWorkDateHide.ToGeorgianDateTime(); - var dayliFee = "خطای تاریخ"; - double dayliFeeDouble = 0; - if (styear >= 1370) - { - - if (leftworkList == null) - leftworkList = new List(); - - var dayliFeeResult = _yearlySalaryRepository.DayliFeeComputing(startDate, contractStart, contractEnd, - command.EmployeeId, command.WorkshopId, leftworkList); - dayliFee = dayliFeeResult.DayliFee; - dayliFeeDouble = dayliFeeResult.DayliFeeDouble; - dayliFeeComplete = dayliFeeResult.DayliFee.MoneyToDouble(); - basic = dayliFeeResult.Basic; - } - - #endregion - - #region ConsumableItemsAndHousingAndFamily - - var ConsumableItems = _yearlySalaryRepository.ConsumableItems(contractEnd); - var HousingAllowance = _yearlySalaryRepository.HousingAllowance(contractEnd); - - var familyAllowance = _yearlySalaryRepository.FamilyAllowance(command.EmployeeId, contractStart, contractEnd); - var MarriedAllowance = _yearlySalaryRepository.MarriedAllowance(contractEnd, command.EmployeeId); - // حق تاهل - string MarriedAllowanceStr = MarriedAllowance > 0 ? MarriedAllowance.ToMoney() : "0"; - #endregion - - var totalWeek = (int)(TotalContractDays / 6); - - #region Fix44Compute - int TotalContractdaysUnder30 = TotalContractDays > 30 ? 30 : TotalContractDays; - if (totalHourses < mandatoryHours) - { - if (!string.IsNullOrWhiteSpace(command.ShiftWork)) - { - var workedHoursePerDay = totalHourses / mandatorDays; - var result = (dayliFeeDouble / 7.33) * workedHoursePerDay; - - - dayliFee = result.ToMoney(); - - var HousingAllowonceNumberType = HousingAllowance.MoneyToDouble(); - var HousingStep1 = HousingAllowonceNumberType / 30; - var HousingStep2 = HousingStep1 / 7.33; - var HousingStep3 = HousingStep2 * workedHoursePerDay; - var HousingStep4 = HousingStep3 * TotalContractdaysUnder30; - HousingAllowance = HousingStep4.ToMoney(); - - var ConsumableItemsNumberType = ConsumableItems.MoneyToDouble(); - var consumableItemsStep1 = ConsumableItemsNumberType / 30; - var consumableItemsStep2 = consumableItemsStep1 / 7.33; - var consumableItemsStep3 = consumableItemsStep2 * workedHoursePerDay; - var consumableItemsStep4 = consumableItemsStep3 * TotalContractdaysUnder30; - ConsumableItems = consumableItemsStep4.ToMoney(); - - - - //حق تاهل - if (MarriedAllowance > 0) - { - var MarriedStep1 = MarriedAllowance / 30; - var MarriedStep2 = MarriedStep1 / 7.33; - var MarriedStep3 = MarriedStep2 * workedHoursePerDay; - var MarriedStep4 = MarriedStep3 * TotalContractdaysUnder30; - MarriedAllowanceStr = MarriedStep4.ToMoney(); - } - - if (familyAllowance != "0") - { - - var familyAllowanceNumberType = familyAllowance.MoneyToDouble(); - var familyAllowanceStep1 = familyAllowanceNumberType / 30; - var familyAllowanceStep2 = familyAllowanceStep1 / 7.33; - var familyAllowanceStep3 = familyAllowanceStep2 * workedHoursePerDay; - var familyAllowanceStep4 = familyAllowanceStep3 * TotalContractdaysUnder30; - familyAllowance = familyAllowanceStep4.ToMoney(); - } - - if (totalWeek > 1) - { - - double weekAvrage = 0; - if (totalHourses < 44.00) - { - weekAvrage = (totalHourses * 6) / TotalContractDays; - } - else - { - weekAvrage = (totalHourses * 6) / TotalDaysNoFriday; - } - - //var oneday = weekAvrage * 6; - var totalShiftRound = Math.Round(weekAvrage, 2); - SumWorkeTime = $"{totalShiftRound}"; - - } - else if (totalWeek <= 1 && TotalDaysNoFriday <= 6) - { - var totalShiftRound = Math.Round(totalHourses, 2); - SumWorkeTime = $"{totalShiftRound}"; - } - else if (totalWeek <= 1 && TotalDaysNoFriday > 6) - - { - var perDyeWorked = totalHourses / TotalDaysNoFriday; - var weekAvrage = perDyeWorked * 6; - var totalShiftRound = Math.Round(weekAvrage, 2); - SumWorkeTime = $"{totalShiftRound}"; - } - - weeklyTime = sumSpans; - } - - } - else // اگر بیشتر از 44 بود - { - - var HousingAllowonceNumberType = HousingAllowance.MoneyToDouble(); - var ConsumableItemsNumberType = ConsumableItems.MoneyToDouble(); - var familyAllowanceNumberType = familyAllowance.MoneyToDouble(); - - var HousingStep1 = HousingAllowonceNumberType / 30; - var HousingStep4 = HousingStep1 * TotalContractdaysUnder30; - HousingAllowance = HousingStep4.ToMoney(); - - - var consumableItemsStep1 = ConsumableItemsNumberType / 30; - var consumableItemsStep4 = consumableItemsStep1 * TotalContractdaysUnder30; - ConsumableItems = consumableItemsStep4.ToMoney(); - - //حق تاهل - if (MarriedAllowance > 0) - { - var MarriedStep1 = MarriedAllowance / 30; - var MarriedStep4 = MarriedStep1 * TotalContractdaysUnder30; - MarriedAllowanceStr = MarriedStep4.ToMoney(); - } - - if (familyAllowance != "0") - { - var familyAllowanceStep1 = familyAllowanceNumberType / 30; - var familyAllowanceStep4 = familyAllowanceStep1 * TotalContractdaysUnder30; - familyAllowance = familyAllowanceStep4.ToMoney(); - } - - SumWorkeTime = $"{44}"; - - //اضافه کار - if (overTimeWork > 0) - { - - //int mandatoryH = (int)Mandatory.TotalHours; - //int mandatoryM = (int)(Mandatory.TotalMinutes % 60); - int mandatoryH = (int)overTimeWork; - int mandatoryM = (int)Math.Round((overTimeWork - mandatoryH) * 60); - overMandatoryHours = mandatoryH.ToString(); - overMandatoryMinuts = mandatoryM.ToString(); - } - - } - #endregion - - //****** نوبت کاری و شب کاری **** - #region RotatingShiftCheckAndNightWorkOver22 - - string shiftPayValue = "0"; - List rotatingResultList = RotatingShiftCheck(groupedRollCall); - - // شبکاری - TimeSpan over22 = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); - var RotatingfaName = new List(); - //if (command.ShiftWork != "1" && command.ShiftWork != "2" && command.ShiftWork != "4")//اگر چرخشی بود و منظم نبود - //{ - // if (moriningCount > 0) - // RotatingfaName.Add("صبح"); - // if (eveningCount > 0) - // RotatingfaName.Add("عصر"); - // if (nightCount > 0) - // RotatingfaName.Add("شب"); - //} - //else// اگر منظم و شیفتی بود - //{ - // var totalDays = (int)(command.ContractEndGr - command.ContractStartGr).TotalDays + 1; - // int validCount = 0; - // if (totalDays <= 7) // زیر 7 روز باید حد اقل 2 تغییر شیفت داشته باشد - // { - // validCount = 2; - // } - // else if (totalDays >= 28) // بالای 28 روز حد اقل 8 تغییر شیفت - // { - // validCount = 8; - // } - // else - // { - // // تناسب گیری - اگر برای 28 روز 8 تغییر پس برای ایکس روز چند تغییر لازم است - // validCount = (int)((totalDays * 8) / 28); - // } - - // if (moriningCount >= validCount) - // RotatingfaName.Add("صبح"); - // if (eveningCount >= validCount) - // RotatingfaName.Add("عصر"); - // if (nightCount >= validCount) - // RotatingfaName.Add("شب"); - - //} - - int moriningCount = 0; - int eveningCount = 0; - int nightCount = 0; - - int moriningWinRate = rotatingResultList.Where(x => x.IsMorningShift).Sum(x => x.WinRate); - int eveningWinRate = rotatingResultList.Where(x => x.IsEveningShift).Sum(x => x.WinRate); - int nightWinRate = rotatingResultList.Where(x => x.IsNightShift).Sum(x => x.WinRate); - - - if (moriningWinRate > eveningWinRate && moriningWinRate > nightWinRate) - { - moriningCount = rotatingResultList.Count(x => x.IsMorningShift); - eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); - nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); - } - - if (eveningWinRate > moriningWinRate && eveningWinRate > nightWinRate) - { - moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); - eveningCount = rotatingResultList.Count(x => x.IsEveningShift); - nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); - } - - if (nightWinRate > moriningWinRate && nightWinRate > eveningWinRate) - { - moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); - eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); - nightCount = rotatingResultList.Count(x => x.IsNightShift); - } - - var totalDays = (int)(command.ContractEndGr - command.ContractStartGr).TotalDays + 1; - int validCount = 0; - if (totalDays <= 7) // زیر 7 روز باید حد اقل 2 تغییر شیفت داشته باشد - { - validCount = 2; - } - else if (totalDays >= 28) // بالای 28 روز حد اقل 8 تغییر شیفت - { - validCount = 8; - } - else - { - // تناسب گیری - اگر برای 28 روز 8 تغییر پس برای ایکس روز چند تغییر لازم است - validCount = (int)((totalDays * 8) / 28); - } - - if (moriningCount >= validCount) - RotatingfaName.Add("صبح"); - if (eveningCount >= validCount) - RotatingfaName.Add("عصر"); - if (nightCount >= validCount) - RotatingfaName.Add("شب"); - var rotatingFaResult = ""; - if (RotatingfaName.Count > 1)// اگر تعداد شیفت های محاسبه شده بیش از یک بود - { - shiftOver22Hours = "0"; - shiftOver22Minuts = "0"; - for (var rotateNumber = 0; rotateNumber < RotatingfaName.Count; rotateNumber++) - { - if (rotateNumber == 0) - rotatingFaResult = $"{RotatingfaName[rotateNumber]}"; - if (rotateNumber == 1) - rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; - if (rotateNumber == 2) - rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; - } - } - else if (RotatingfaName.Count <= 1) - { - rotatingFaResult = "نوبت کاری ندارد"; - - var over22Hours = (int)over22.TotalHours; - var over22Minuts = (int)(over22.TotalMinutes % 60); - shiftOver22Hours = over22Hours.ToString(); - shiftOver22Minuts = over22Minuts.ToString(); - - } - #endregion - //******* محاسبه مبلغ نوبت کاری ************* - #region ShiftPayPercent - - if (rotatingFaResult != "نوبت کاری ندارد" || rotatingFaResult != "") - { - var TotalDays = (command.ContractEndGr - command.ContractStartGr).TotalDays + 1; - var DailyFeeNumberType = dayliFee.MoneyToDouble(); - if (rotatingFaResult == "صبح و عصر") - { - var shiftPyaPercent = DailyFeeNumberType * 10 / 100; - ShiftPayResult = shiftPyaPercent * TotalDays; - shiftPayValue = "10"; - } - else if (rotatingFaResult == "صبح و عصر و شب") - { - var shiftPyaPercent = DailyFeeNumberType * 15 / 100; - ShiftPayResult = shiftPyaPercent * TotalDays; - shiftPayValue = "15"; - } - else if (rotatingFaResult == "صبح و شب" || rotatingFaResult == "عصر و شب") - { - var shiftPyaPercent = DailyFeeNumberType * 22.5 / 100; - ShiftPayResult = shiftPyaPercent * TotalDays; - shiftPayValue = "22.5"; - } - } - - #endregion - - #region Result - - var res = new ComputingViewModel() - { - - NumberOfWorkingDays = $"{groupedRollCall.Count}", - NumberOfFriday = $"{numberOfFridays}", - TotalHoursesH = totalHolidaysAndNotH.ToString(), - TotalHoursesM = totalHolidaysAndNotM.ToString(), - OverTimeWorkH = overMandatoryHours, - OverTimeWorkM = overMandatoryMinuts, - OverNightWorkH = shiftOver22Hours, - OverNightWorkM = shiftOver22Minuts, - ComplexNumberOfWorkingDays = $"{groupedRollCall.Count}", - SalaryCompute = dayliFee, - SumTime44 = SumWorkeTime, - ConsumableItems = ConsumableItems, - HousingAllowance = HousingAllowance, - FamilyAllowance = familyAllowance, - OfficialHoliday = holiday, - weeklyTime = weeklyTime, - RotatingResultList = rotatingResultList, - RotatingStatus = rotatingFaResult, - ShiftPay = ShiftPayResult, - Basic = basic, - FridayStartToEnd = fridays, - TotalHolidayAndNotH = totalHolidaysAndNotH.ToString(), - TotalHolidayAndNotM = totalHolidaysAndNotM.ToString(), - DayliFeeComplete = dayliFeeComplete, - MarriedAllowance = MarriedAllowanceStr, - RotatingShiftValue = shiftPayValue - }; - - #endregion - return res; - } - - public async Task RotatingShiftReport(long workshopId, long employeeId, DateTime contractStart, DateTime contractEnd, string shiftwork, bool hasRollCall, CreateWorkingHoursTemp command, bool holidayWorking) - { - List rollCallResult = new List(); - List groupedRollCall = new List(); - if (hasRollCall) - { - rollCallResult = await _context.RollCalls.Where(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate.Value.Date >= contractStart.Date && - x.StartDate.Value.Date <= contractEnd.Date && x.EndDate != null).Select(x => new RollCallViewModel() - { - StartDate = x.StartDate, - EndDate = x.EndDate, - ShiftSpan = (x.EndDate.Value - x.StartDate.Value), - CreationDate = x.ShiftDate, - }).ToListAsync(); - groupedRollCall = rollCallResult.GroupBy(x => x.CreationDate.Date).Select(x => new GroupedRollCalls() - { - CreationDate = x.Key, - ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), - HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), - - - - }).OrderBy(x => x.CreationDate).ToList(); - } - else - { - command.WorkshopId = workshopId; - command.EmployeeId = employeeId; - command.ContractStartGr = contractStart; - command.ContractEndGr = contractEnd; - rollCallResult = ConvertStaticHoursToRollCall(command, holidayWorking); - groupedRollCall = rollCallResult.GroupBy(x => x.ShiftDate.Date).Select(x => new GroupedRollCalls() - { - CreationDate = x.Key, - ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), - HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), - - SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - - }).OrderBy(x => x.CreationDate).ToList(); - } - - - - //****** نوبت کاری و شب کاری **** - #region RotatingShiftCheckAndNightWorkOver22 - - string shiftPayValue = "0"; - List rotatingResultList = RotatingShiftCheck(groupedRollCall); - int moriningCount = 0; - int eveningCount = 0; - int nightCount = 0; - - int moriningWinRate = rotatingResultList.Where(x => x.IsMorningShift).Sum(x => x.WinRate); - int eveningWinRate = rotatingResultList.Where(x => x.IsEveningShift).Sum(x => x.WinRate); - int nightWinRate = rotatingResultList.Where(x => x.IsNightShift).Sum(x => x.WinRate); - - - if (moriningWinRate > eveningWinRate && moriningWinRate > nightWinRate) - { - moriningCount = rotatingResultList.Count(x => x.IsMorningShift); - eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); - nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); - } - - if (eveningWinRate > moriningWinRate && eveningWinRate > nightWinRate) - { - moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); - eveningCount = rotatingResultList.Count(x => x.IsEveningShift); - nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); - } - - if (nightWinRate > moriningWinRate && nightWinRate > eveningWinRate) - { - moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); - eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); - nightCount = rotatingResultList.Count(x => x.IsNightShift); - } - - - - - - - // شبکاری - TimeSpan over22 = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); - var RotatingfaName = new List(); - //if (shiftwork != "1" && shiftwork != "2" && shiftwork != "4")//اگر چرخشی بود و منظم نبود - //{ - // if (moriningCount > 0) - // RotatingfaName.Add("صبح"); - // if (eveningCount > 0) - // RotatingfaName.Add("عصر"); - // if (nightCount > 0) - // RotatingfaName.Add("شب"); - //} - //else// اگر منظم و شیفتی بود - //{ - - - //} - var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; - int validCount = 0; - if (totalDays <= 7) // زیر 7 روز باید حد اقل 2 تغییر شیفت داشته باشد - { - validCount = 2; - } - else if (totalDays >= 28) // بالای 28 روز حد اقل 8 تغییر شیفت - { - validCount = 6; - } - else - { - // تناسب گیری - اگر برای 28 روز 8 تغییر پس برای ایکس روز چند تغییر لازم است - validCount = (int)((totalDays * 6) / 28); - } - - Console.WriteLine(validCount); - if (moriningCount >= validCount) - RotatingfaName.Add("صبح"); - if (eveningCount >= validCount) - RotatingfaName.Add("عصر"); - if (nightCount >= validCount) - RotatingfaName.Add("شب"); - - - - var rotatingFaResult = ""; - if (RotatingfaName.Count > 1)// اگر تعداد شیفت های محاسبه شده بیش از یک بود - { - - for (var rotateNumber = 0; rotateNumber < RotatingfaName.Count; rotateNumber++) - { - if (rotateNumber == 0) - rotatingFaResult = $"{RotatingfaName[rotateNumber]}"; - if (rotateNumber == 1) - rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; - if (rotateNumber == 2) - rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; - } - } - else if (RotatingfaName.Count <= 1) - { - rotatingFaResult = "نوبت کاری ندارد"; - - - - } - - return new ComputingViewModel - { - RotatingStatus = rotatingFaResult, - RotatingResultList = rotatingResultList - - }; - - #endregion - } - - - - - //public static TimeSpan CalculateBreakTime(BreakTime breakTime, TimeSpan sumOneDaySpan) - //{ - // if (breakTime.BreakTimeType != BreakTimeType.WithTime) - // return new TimeSpan(); - - // var breakTimeSpan = breakTime.BreakTimeValue.ToTimeSpan(); - - // if (breakTimeSpan * 2 >= sumOneDaySpan) - // return new TimeSpan(); - - // return breakTimeSpan; ; - - //} - public static TimeSpan CalculateBreakTime(TimeSpan breakTimeSpan, TimeSpan sumOneDaySpan) - { - if (breakTimeSpan * 2 >= sumOneDaySpan) - return new TimeSpan(); - return breakTimeSpan; ; - } - - public TimeSpan AfterSubtract(CreateWorkingHoursTemp command, TimeSpan sumOneDaySpan, DateTime creationDate) - { - #region RestTimes - - var rest0 = new TimeSpan(); - var rest1 = new TimeSpan(); - var rest2 = new TimeSpan(); - var rest3 = new TimeSpan(); - var rest4 = new TimeSpan(); - var rest5 = new TimeSpan(); - var rest6 = new TimeSpan(); - switch (command.ShiftWork) - { - case "1": - case "2": - command.RestTime = command.RestTime == "0" ? "00" : command.RestTime; - command.RestTimeYekshanbeh = command.RestTimeYekshanbeh == "0" ? "00" : command.RestTimeYekshanbeh; - command.RestTimeDoshanbeh = command.RestTimeDoshanbeh == "0" ? "00" : command.RestTimeDoshanbeh; - command.RestTimeSeshanbeh = command.RestTimeSeshanbeh == "0" ? "00" : command.RestTimeSeshanbeh; - command.RestTimeCheharshanbeh = - command.RestTimeCheharshanbeh == "0" ? "00" : command.RestTimeCheharshanbeh; - command.RestTimePanjshanbeh = command.RestTimePanjshanbeh == "0" ? "00" : command.RestTimePanjshanbeh; - command.RestTimeJomeh = command.RestTimeJomeh == "0" ? "00" : command.RestTimeJomeh; - command.RestTimeMin = command.RestTimeMin == "0" ? "00" : command.RestTimeMin; - command.RestTimeYekshanbehMin = - command.RestTimeYekshanbehMin == "0" ? "00" : command.RestTimeYekshanbehMin; - command.RestTimeDoshanbehMin = - command.RestTimeDoshanbehMin == "0" ? "00" : command.RestTimeDoshanbehMin; - command.RestTimeSeshanbehMin = - command.RestTimeSeshanbehMin == "0" ? "00" : command.RestTimeSeshanbehMin; - command.RestTimeCheharshanbehMin = - command.RestTimeCheharshanbehMin == "0" ? "00" : command.RestTimeCheharshanbehMin; - command.RestTimePanjshanbehMin = - command.RestTimePanjshanbehMin == "0" ? "00" : command.RestTimePanjshanbehMin; - command.RestTimeJomehMin = command.RestTimeJomehMin == "0" ? "00" : command.RestTimeJomehMin; - - rest0 = TimeSpan.Parse($"{command.RestTime}:{command.RestTimeMin}"); - rest1 = TimeSpan.Parse($"{command.RestTimeYekshanbeh}:{command.RestTimeYekshanbehMin}"); - rest2 = TimeSpan.Parse($"{command.RestTimeDoshanbeh}:{command.RestTimeDoshanbehMin}"); - rest3 = TimeSpan.Parse($"{command.RestTimeSeshanbeh}:{command.RestTimeSeshanbehMin}"); - rest4 = TimeSpan.Parse($"{command.RestTimeCheharshanbeh}:{command.RestTimeCheharshanbehMin}"); - rest5 = TimeSpan.Parse($"{command.RestTimePanjshanbeh}:{command.RestTimePanjshanbehMin}"); - rest6 = TimeSpan.Parse($"{command.RestTimeJomeh}:{command.RestTimeJomehMin}"); - break; - case "4": - command.RestTimeShanbe1 = command.RestTimeShanbe1 == "0" ? "00" : command.RestTimeShanbe1; - command.RestTimeShanbe1Min = command.RestTimeShanbe1Min == "0" ? "00" : command.RestTimeShanbe1Min; - command.RestTimeYekShanbe1 = command.RestTimeYekShanbe1 == "0" ? "00" : command.RestTimeYekShanbe1; - command.RestTimeYekShanbe1Min = - command.RestTimeYekShanbe1Min == "0" ? "00" : command.RestTimeYekShanbe1Min; - command.RestTimeDoShanbe1 = command.RestTimeDoShanbe1 == "0" ? "00" : command.RestTimeDoShanbe1; - command.RestTimeDoShanbe1Min = - command.RestTimeDoShanbe1Min == "0" ? "00" : command.RestTimeDoShanbe1Min; - command.RestTimeSeShanbe1 = command.RestTimeSeShanbe1 == "0" ? "00" : command.RestTimeSeShanbe1; - command.RestTimeSeShanbe1Min = - command.RestTimeSeShanbe1Min == "0" ? "00" : command.RestTimeSeShanbe1Min; - command.RestTimeCheharShanbe1 = - command.RestTimeCheharShanbe1 == "0" ? "00" : command.RestTimeCheharShanbe1; - command.RestTimeCheharShanbe1Min = - command.RestTimeCheharShanbe1Min == "0" ? "00" : command.RestTimeCheharShanbe1Min; - command.RestTimePanjShanbe1 = command.RestTimePanjShanbe1 == "0" ? "00" : command.RestTimePanjShanbe1; - command.RestTimePanjShanbe1Min = - command.RestTimePanjShanbe1Min == "0" ? "00" : command.RestTimePanjShanbe1Min; - command.RestTimeJome1 = command.RestTimeJome1 == "0" ? "00" : command.RestTimeJome1; - command.RestTimeJome1Min = command.RestTimeJome1Min == "0" ? "00" : command.RestTimeJome1Min; - - // sumrest week1 - rest0 = TimeSpan.Parse($"{command.RestTimeShanbe1}:{command.RestTimeShanbe1Min}"); - rest1 = TimeSpan.Parse($"{command.RestTimeYekShanbe1}:{command.RestTimeYekShanbe1Min}"); - rest2 = TimeSpan.Parse($"{command.RestTimeDoShanbe1}:{command.RestTimeDoShanbe1Min}"); - rest3 = TimeSpan.Parse($"{command.RestTimeSeShanbe1}:{command.RestTimeSeShanbe1Min}"); - rest4 = TimeSpan.Parse($"{command.RestTimeCheharShanbe1}:{command.RestTimeCheharShanbe1Min}"); - rest5 = TimeSpan.Parse($"{command.RestTimePanjShanbe1}:{command.RestTimePanjShanbe1Min}"); - rest6 = TimeSpan.Parse($"{command.RestTimeJome1}:{command.RestTimeJome1Min}"); - break; - } - //week1 - - - #endregion - - var result = new TimeSpan(); - switch (creationDate.DayOfWeek) - { - case DayOfWeek.Saturday: - if (sumOneDaySpan >= rest0) - result = sumOneDaySpan.Subtract(rest0); - break; - case DayOfWeek.Sunday: - if (sumOneDaySpan >= rest1) - result = sumOneDaySpan.Subtract(rest1); - break; - case DayOfWeek.Monday: - if (sumOneDaySpan >= rest2) - result = sumOneDaySpan.Subtract(rest2); - break; - case DayOfWeek.Tuesday: - if (sumOneDaySpan >= rest3) - result = sumOneDaySpan.Subtract(rest3); - break; - case DayOfWeek.Wednesday: - if (sumOneDaySpan >= rest4) - result = sumOneDaySpan.Subtract(rest4); - break; - case DayOfWeek.Thursday: - if (sumOneDaySpan >= rest5) - result = sumOneDaySpan.Subtract(rest5); - break; - case DayOfWeek.Friday: - if (sumOneDaySpan >= rest6) - result = sumOneDaySpan.Subtract(rest6); - break; - } - - return result; - } - - public List RotatingShiftCheck(List rollCallList) - { - List finalResult = new List(); - var nullDateTme = new DateTime(0001, 01, 01); - foreach (var item in rollCallList) - { - #region Entityes - - var morningWorkingTime = new TimeSpan(); - var eveningWorkingTime = new TimeSpan(); - var nightWorkingTime = new TimeSpan(); - - #endregion - - foreach (var shift in item.ShiftList) - { - #region DatePeriod - - var shiftDate = item.CreationDate; - if (shift.Start.Date < shiftDate.Date) - shiftDate = shiftDate.AddDays(-1); - - DateTime midNight24 = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 0, 0, 0); - DateTime morningStart = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 6, 0, 0); - DateTime morningEnd = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 14, 0, 0); - DateTime eveningStart = morningEnd; - DateTime eveningEnd = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 22, 0, 0); - DateTime nightStart = eveningEnd; - DateTime nightEnd = morningStart; - DateTime nightEndNextday = nightEnd.AddDays(1); - DateTime morningEndNextday = morningEnd.AddDays(1); - DateTime eveningEndNextday = eveningEnd.AddDays(1); - - #endregion - - #region MidNight Enter 00:00 ---> 6 - - if (shift.Start >= midNight24 // 00:00 >---> 6 - && shift.End <= morningStart) - { - nightWorkingTime = nightWorkingTime.Add(shift.End - shift.Start); - } - else if (shift.Start >= midNight24 && shift.Start < morningStart // 00:00---6--->14 - && shift.End > morningStart && shift.End <= morningEnd) - { - nightWorkingTime = nightWorkingTime.Add(morningStart - shift.Start); - morningWorkingTime = morningWorkingTime.Add(shift.End - morningStart); - } - else if (shift.Start >= midNight24 && shift.Start < morningStart// 00:00---6---14--->22 - && shift.End > morningEnd && shift.End <= eveningEnd) - { - nightWorkingTime = nightWorkingTime.Add(morningStart - shift.Start); - morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); - eveningWorkingTime = eveningWorkingTime.Add(shift.End - eveningStart); - - } - else if (shift.Start >= midNight24 // 00:00---6---14----22---->6 - && shift.Start < morningStart - && shift.End > eveningEnd && shift.End <= nightEndNextday) - { - nightWorkingTime = nightWorkingTime.Add(morningStart - shift.Start); - morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); - eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); - nightWorkingTime = nightWorkingTime.Add(shift.End - eveningEnd); - - } - - #endregion - - #region morning enter 14 <- 6 - if (shift.Start >= morningStart // 14<---<6 - && shift.End <= morningEnd) - { - morningWorkingTime = morningWorkingTime.Add(shift.End - shift.Start); - } - else if (shift.Start >= morningStart && shift.Start < morningEnd // 22<---14---6 - && shift.End > eveningStart && shift.End <= eveningEnd) - { - morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); - eveningWorkingTime = eveningWorkingTime.Add(shift.End - eveningStart); - - } - else if (shift.Start >= morningStart && shift.Start < morningEnd// // 6<---22---14---6 - && shift.End > eveningEnd && shift.End <= nightEndNextday) - { - morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); - eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); - nightWorkingTime = nightWorkingTime.Add(shift.End - eveningEnd); - } - else if (shift.Start >= morningStart // 14<---6<---22---14---6 - && shift.Start < morningEnd - && shift.End > nightEndNextday && shift.End <= morningEndNextday) - { - morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); - eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); - nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); - TimeSpan nextDayMorningSpan = (shift.End - nightEndNextday); - morningWorkingTime = morningWorkingTime.Add(nextDayMorningSpan); - } - else if (shift.Start >= morningStart // 22<---14<---6<---22---14---6 - && shift.Start < morningEnd - && shift.End > morningEndNextday && shift.End <= eveningEndNextday) - { - morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); - eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); - nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); - morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); - TimeSpan nextDayEveningSpan = (shift.End - morningEndNextday); - eveningWorkingTime = eveningWorkingTime.Add(nextDayEveningSpan); - - } - - - #endregion - - #region evening enter 22 <- 14 - - if (shift.Start >= eveningStart // 22<---<14 - && shift.End <= eveningEnd) - { - eveningWorkingTime = eveningWorkingTime.Add(shift.End - shift.Start); - } - else if (shift.Start >= eveningStart && shift.Start < eveningEnd // 6<---22---14 - && shift.End > nightStart && shift.End <= nightEndNextday) - { - eveningWorkingTime = eveningWorkingTime.Add(eveningEnd - shift.Start); - nightWorkingTime = nightWorkingTime.Add(shift.End - eveningEnd); - - } - else if (shift.Start >= eveningStart && shift.Start < eveningEnd// // 14<---6---22---14 - && shift.End > nightEndNextday && shift.End <= morningEndNextday) - { - eveningWorkingTime = eveningWorkingTime.Add(eveningEnd - shift.Start); - nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); - morningWorkingTime = morningWorkingTime.Add(shift.End - nightEndNextday); - } - else if (shift.Start >= eveningStart // 22<---14<---6---22---14 - && shift.Start < eveningEnd - && shift.End > morningEndNextday && shift.End <= eveningEndNextday) - { - eveningWorkingTime = eveningWorkingTime.Add(morningEnd - shift.Start); - nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); - morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); - TimeSpan nextDayEveningSpan = (shift.End - morningEndNextday); - eveningWorkingTime = eveningWorkingTime.Add(nextDayEveningSpan); - } - - #endregion - - #region night enter 6 <- 22 - if (shift.Start >= nightStart // 6<---<22 - && shift.End <= nightEndNextday) - { - nightWorkingTime = nightWorkingTime.Add(shift.End - shift.Start); - } - else if (shift.Start >= nightStart && shift.Start < nightEndNextday // 14<---6---22 - && shift.End > nightEndNextday && shift.End <= morningEndNextday) - { - nightWorkingTime = nightWorkingTime.Add(nightEndNextday - shift.Start); - morningWorkingTime = morningWorkingTime.Add(shift.End - nightEndNextday); - - } - else if (shift.Start >= nightStart && shift.Start < nightEndNextday// // 22<---14---6---22 - && shift.End > morningEndNextday && shift.End <= eveningEndNextday) - { - nightWorkingTime = nightWorkingTime.Add(nightEndNextday - shift.Start); ; - morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); - eveningWorkingTime = eveningWorkingTime.Add(shift.End - morningEndNextday); - } - else if (shift.Start >= nightStart // 6<---22<---14---6---22 - && shift.Start < nightEndNextday - && shift.End > eveningEndNextday) - { - - nightWorkingTime = nightWorkingTime.Add(nightEndNextday - shift.Start); - morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); - eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); - TimeSpan nextDayNightSpan = (shift.End - eveningEndNextday); - nightWorkingTime = nightWorkingTime.Add(nextDayNightSpan); - } - #endregion - - - - } - #region Result - - var result = new RotatingShiftViewModel(); - result.RotatingDate = item.CreationDate.ToFarsi(); - result.MorningWorkSpan = morningWorkingTime; - result.EveningWorkSpan = eveningWorkingTime; - result.NightWorkSpan = nightWorkingTime; - var nullWorkspan = new TimeSpan(0, 0, 0); - - var totalTime = result.TotalWorkingTime.Add(result.MorningWorkSpan); - totalTime = totalTime.Add(result.EveningWorkSpan); - totalTime = totalTime.Add(result.NightWorkSpan); - - result.TotalWorkingTime = totalTime; - - var morningH = (int)result.MorningWorkSpan.TotalHours; - var morningM = result.MorningWorkSpan.Minutes % 60; - var morningMS = "00"; - if (morningM < 10 && morningM > 0) - morningMS = $"0{morningM}"; - if (morningM > 10) - morningMS = $"{morningM}"; - result.MorningString = $"0{morningH}:{morningMS}"; - - var eveningH = (int)result.EveningWorkSpan.TotalHours; - var eveningM = result.EveningWorkSpan.Minutes % 60; - var eveningMS = "00"; - if (eveningM < 10 && eveningM > 0) - eveningMS = $"0{eveningM}"; - if (eveningM > 10) - eveningMS = $"{eveningM}"; - result.EveningString = $"0{eveningH}:{eveningMS}"; - - var nightH = (int)result.NightWorkSpan.TotalHours; - var nightM = result.NightWorkSpan.Minutes % 60; - var nightMS = "00"; - if (nightM < 10 && nightM > 0) - nightMS = $"0{nightM}"; - if (nightM > 10) - nightMS = $"{nightM}"; - result.NightString = $"0{nightH}:{nightMS}"; - - if (result.MorningWorkSpan > result.EveningWorkSpan - || result.MorningWorkSpan == result.EveningWorkSpan) // if morning bigerThan evening or equal - { - - if (result.MorningWorkSpan != nullWorkspan) - { - var sumSpan = result.MorningWorkSpan.Add(result.EveningWorkSpan); - var sumSpanDouble = sumSpan.TotalMinutes; - var winRate = (result.MorningWorkSpan.TotalMinutes * 100) / sumSpanDouble; - result.WinRate = Convert.ToInt32(winRate); - result.IsMorningShift = true; - result.IsNightShift = false; - result.IsEveningShift = false; - result.RotatingShiftStatus = "صبح"; - - } - - if (result.MorningWorkSpan < result.NightWorkSpan - || result.MorningWorkSpan == result.NightWorkSpan) // if night bigerThan morning or equal - if (result.NightWorkSpan != nullWorkspan) - { - var sumSpan = result.MorningWorkSpan.Add(result.NightWorkSpan); - var sumSpanDouble = sumSpan.TotalMinutes; - var winRate = (result.NightWorkSpan.TotalMinutes * 100) / sumSpanDouble; - result.WinRate = Convert.ToInt32(winRate); - result.IsMorningShift = false; - result.IsNightShift = true; - result.IsEveningShift = false; - result.RotatingShiftStatus = "شب"; - } - } - else if (result.MorningWorkSpan < result.EveningWorkSpan) // if evening bigerThan morning - { - if (result.EveningWorkSpan != nullWorkspan) - { - var sumSpan = result.MorningWorkSpan.Add(result.EveningWorkSpan); - var sumSpanDouble = sumSpan.TotalMinutes; - var winRate = (result.EveningWorkSpan.TotalMinutes * 100) / sumSpanDouble; - result.WinRate = Convert.ToInt32(winRate); - result.IsEveningShift = true; - result.IsMorningShift = false; - result.IsNightShift = false; - result.RotatingShiftStatus = "عصر"; - } - - if (result.EveningWorkSpan < result.NightWorkSpan - || result.EveningWorkSpan == result.NightWorkSpan) // if night bigerThan evening or equal - if (result.NightWorkSpan != nullWorkspan) - { - var sumSpan = result.EveningWorkSpan.Add(result.NightWorkSpan); - var sumSpanDouble = sumSpan.TotalMinutes; - var winRate = (result.NightWorkSpan.TotalMinutes * 100) / sumSpanDouble; - result.WinRate = Convert.ToInt32(winRate); - result.IsMorningShift = false; - result.IsEveningShift = false; - result.IsNightShift = true; - result.RotatingShiftStatus = "شب"; - } - } - - finalResult.Add(result); - #endregion - } - - return finalResult; - - } - - - public List ConvertStaticHoursToRollCall(CreateWorkingHoursTemp command, bool workshopHolidyWorking) - { - var rollCallList = new List(); - #region Entities - - var sdate = command.ContarctStart.ToEnglishNumber(); - var edate = command.ContractEnd.ToEnglishNumber(); - var syear = Convert.ToInt32(sdate.Substring(0, 4)); - var smonth = Convert.ToInt32(sdate.Substring(5, 2)); - var sday = Convert.ToInt32(sdate.Substring(8, 2)); - - var eyear = Convert.ToInt32(edate.Substring(0, 4)); - var emonth = Convert.ToInt32(edate.Substring(5, 2)); - var eday = Convert.ToInt32(edate.Substring(8, 2)); - - var d1 = new PersianDateTime(syear, smonth, sday); - var d2 = new PersianDateTime(eyear, emonth, eday); - - //بدست آوردن مرخصی - LeaveSearchModel leaveSearch = new LeaveSearchModel() - { - EmployeeId = command.EmployeeId, - WorkshopId = command.WorkshopId, - - StartLeaveGr = command.ContractStartGr, - EndLeaveGr = command.ContractEndGr, - IsAccepted = true, - }; - var leaveSearchResult = _leaveRepository.search(leaveSearch); - //بدس آوردن تعطیلات رسمی - var holidayList = _holidayItemRepository.GetHolidayItem(sdate.Substring(0, 4)); - bool isHoliday = false; - - #endregion - - - - #region SumRestTimesOneShift - - var rest0 = new TimeSpan(); - var rest1 = new TimeSpan(); - var rest2 = new TimeSpan(); - var rest3 = new TimeSpan(); - var rest4 = new TimeSpan(); - var rest5 = new TimeSpan(); - var rest6 = new TimeSpan(); - - var rest0w1 = new TimeSpan(); - var rest1w1 = new TimeSpan(); - var rest2w1 = new TimeSpan(); - var rest3w1 = new TimeSpan(); - var rest4w1 = new TimeSpan(); - var rest5w1 = new TimeSpan(); - var rest6w1 = new TimeSpan(); - - var rest0w2 = new TimeSpan(); - var rest1w2 = new TimeSpan(); - var rest2w2 = new TimeSpan(); - var rest3w2 = new TimeSpan(); - var rest4w2 = new TimeSpan(); - var rest5w2 = new TimeSpan(); - var rest6w2 = new TimeSpan(); - - var rest0w3 = new TimeSpan(); - var rest1w3 = new TimeSpan(); - var rest2w3 = new TimeSpan(); - var rest3w3 = new TimeSpan(); - var rest4w3 = new TimeSpan(); - var rest5w3 = new TimeSpan(); - var rest6w3 = new TimeSpan(); - - var rest0w4 = new TimeSpan(); - var rest1w4 = new TimeSpan(); - var rest2w4 = new TimeSpan(); - var rest3w4 = new TimeSpan(); - var rest4w4 = new TimeSpan(); - var rest5w4 = new TimeSpan(); - var rest6w4 = new TimeSpan(); - if (command.ShiftWork == "4") - { - - //week1 - command.RestTimeShanbe1 = command.RestTimeShanbe1 == "0" ? "00" : command.RestTimeShanbe1; - command.RestTimeShanbe1Min = command.RestTimeShanbe1Min == "0" ? "00" : command.RestTimeShanbe1Min; - command.RestTimeYekShanbe1 = command.RestTimeYekShanbe1 == "0" ? "00" : command.RestTimeYekShanbe1; - command.RestTimeYekShanbe1Min = - command.RestTimeYekShanbe1Min == "0" ? "00" : command.RestTimeYekShanbe1Min; - command.RestTimeDoShanbe1 = command.RestTimeDoShanbe1 == "0" ? "00" : command.RestTimeDoShanbe1; - command.RestTimeDoShanbe1Min = - command.RestTimeDoShanbe1Min == "0" ? "00" : command.RestTimeDoShanbe1Min; - command.RestTimeSeShanbe1 = command.RestTimeSeShanbe1 == "0" ? "00" : command.RestTimeSeShanbe1; - command.RestTimeSeShanbe1Min = - command.RestTimeSeShanbe1Min == "0" ? "00" : command.RestTimeSeShanbe1Min; - command.RestTimeCheharShanbe1 = - command.RestTimeCheharShanbe1 == "0" ? "00" : command.RestTimeCheharShanbe1; - command.RestTimeCheharShanbe1Min = - command.RestTimeCheharShanbe1Min == "0" ? "00" : command.RestTimeCheharShanbe1Min; - command.RestTimePanjShanbe1 = command.RestTimePanjShanbe1 == "0" ? "00" : command.RestTimePanjShanbe1; - command.RestTimePanjShanbe1Min = - command.RestTimePanjShanbe1Min == "0" ? "00" : command.RestTimePanjShanbe1Min; - command.RestTimeJome1 = command.RestTimeJome1 == "0" ? "00" : command.RestTimeJome1; - command.RestTimeJome1Min = command.RestTimeJome1Min == "0" ? "00" : command.RestTimeJome1Min; - - //week2 - command.RestTimeShanbe2 = command.RestTimeShanbe2 == "0" ? "00" : command.RestTimeShanbe2; - command.RestTimeShanbe2Min = command.RestTimeShanbe2Min == "0" ? "00" : command.RestTimeShanbe2Min; - command.RestTimeYekShanbe2 = command.RestTimeYekShanbe2 == "0" ? "00" : command.RestTimeYekShanbe2; - command.RestTimeYekShanbe2Min = - command.RestTimeYekShanbe2Min == "0" ? "00" : command.RestTimeYekShanbe2Min; - command.RestTimeDoShanbe2 = command.RestTimeDoShanbe2 == "0" ? "00" : command.RestTimeDoShanbe2; - command.RestTimeDoShanbe2Min = - command.RestTimeDoShanbe2Min == "0" ? "00" : command.RestTimeDoShanbe2Min; - command.RestTimeSeShanbe2 = command.RestTimeSeShanbe2 == "0" ? "00" : command.RestTimeSeShanbe2; - command.RestTimeSeShanbe2Min = - command.RestTimeSeShanbe2Min == "0" ? "00" : command.RestTimeSeShanbe2Min; - command.RestTimeCheharShanbe2 = - command.RestTimeCheharShanbe2 == "0" ? "00" : command.RestTimeCheharShanbe2; - command.RestTimeCheharShanbe2Min = - command.RestTimeCheharShanbe2Min == "0" ? "00" : command.RestTimeCheharShanbe2Min; - command.RestTimePanjShanbe2 = command.RestTimePanjShanbe2 == "0" ? "00" : command.RestTimePanjShanbe2; - command.RestTimePanjShanbe2Min = - command.RestTimePanjShanbe2Min == "0" ? "00" : command.RestTimePanjShanbe2Min; - command.RestTimeJome2 = command.RestTimeJome2 == "0" ? "00" : command.RestTimeJome2; - command.RestTimeJome2Min = command.RestTimeJome2Min == "0" ? "00" : command.RestTimeJome2Min; - - //week3 - command.RestTimeShanbe3 = command.RestTimeShanbe3 == "0" ? "00" : command.RestTimeShanbe3; - command.RestTimeShanbe3Min = command.RestTimeShanbe3Min == "0" ? "00" : command.RestTimeShanbe3Min; - command.RestTimeYekShanbe3 = command.RestTimeYekShanbe3 == "0" ? "00" : command.RestTimeYekShanbe3; - command.RestTimeYekShanbe3Min = - command.RestTimeYekShanbe3Min == "0" ? "00" : command.RestTimeYekShanbe3Min; - command.RestTimeDoShanbe3 = command.RestTimeDoShanbe3 == "0" ? "00" : command.RestTimeDoShanbe3; - command.RestTimeDoShanbe3Min = - command.RestTimeDoShanbe3Min == "0" ? "00" : command.RestTimeDoShanbe3Min; - command.RestTimeSeShanbe3 = command.RestTimeSeShanbe3 == "0" ? "00" : command.RestTimeSeShanbe3; - command.RestTimeSeShanbe3Min = - command.RestTimeSeShanbe3Min == "0" ? "00" : command.RestTimeSeShanbe3Min; - command.RestTimeCheharShanbe3 = - command.RestTimeCheharShanbe3 == "0" ? "00" : command.RestTimeCheharShanbe3; - command.RestTimeCheharShanbe3Min = - command.RestTimeCheharShanbe3Min == "0" ? "00" : command.RestTimeCheharShanbe3Min; - command.RestTimePanjShanbe3 = command.RestTimePanjShanbe3 == "0" ? "00" : command.RestTimePanjShanbe3; - command.RestTimePanjShanbe3Min = - command.RestTimePanjShanbe3Min == "0" ? "00" : command.RestTimePanjShanbe3Min; - command.RestTimeJome3 = command.RestTimeJome3 == "0" ? "00" : command.RestTimeJome3; - command.RestTimeJome3Min = command.RestTimeJome3Min == "0" ? "00" : command.RestTimeJome3Min; - - //week4 - command.RestTimeShanbe4 = command.RestTimeShanbe4 == "0" ? "00" : command.RestTimeShanbe4; - command.RestTimeShanbe4Min = command.RestTimeShanbe4Min == "0" ? "00" : command.RestTimeShanbe4Min; - command.RestTimeYekShanbe4 = command.RestTimeYekShanbe4 == "0" ? "00" : command.RestTimeYekShanbe4; - command.RestTimeYekShanbe4Min = - command.RestTimeYekShanbe4Min == "0" ? "00" : command.RestTimeYekShanbe4Min; - command.RestTimeDoShanbe4 = command.RestTimeDoShanbe4 == "0" ? "00" : command.RestTimeDoShanbe4; - command.RestTimeDoShanbe4Min = - command.RestTimeDoShanbe4Min == "0" ? "00" : command.RestTimeDoShanbe4Min; - command.RestTimeSeShanbe4 = command.RestTimeSeShanbe4 == "0" ? "00" : command.RestTimeSeShanbe4; - command.RestTimeSeShanbe4Min = - command.RestTimeSeShanbe4Min == "0" ? "00" : command.RestTimeSeShanbe4Min; - command.RestTimeCheharShanbe4 = - command.RestTimeCheharShanbe4 == "0" ? "00" : command.RestTimeCheharShanbe4; - command.RestTimeCheharShanbe4Min = - command.RestTimeCheharShanbe4Min == "0" ? "00" : command.RestTimeCheharShanbe4Min; - command.RestTimePanjShanbe4 = command.RestTimePanjShanbe4 == "0" ? "00" : command.RestTimePanjShanbe4; - command.RestTimePanjShanbe4Min = - command.RestTimePanjShanbe4Min == "0" ? "00" : command.RestTimePanjShanbe4Min; - command.RestTimeJome4 = command.RestTimeJome4 == "0" ? "00" : command.RestTimeJome4; - command.RestTimeJome4Min = command.RestTimeJome4Min == "0" ? "00" : command.RestTimeJome4Min; - - // sumrest week1 - rest0w1 = TimeSpan.Parse($"{command.RestTimeShanbe1}:{command.RestTimeShanbe1Min}"); - rest1w1 = TimeSpan.Parse($"{command.RestTimeYekShanbe1}:{command.RestTimeYekShanbe1Min}"); - rest2w1 = TimeSpan.Parse($"{command.RestTimeDoShanbe1}:{command.RestTimeDoShanbe1Min}"); - rest3w1 = TimeSpan.Parse($"{command.RestTimeSeShanbe1}:{command.RestTimeSeShanbe1Min}"); - rest4w1 = TimeSpan.Parse($"{command.RestTimeCheharShanbe1}:{command.RestTimeCheharShanbe1Min}"); - rest5w1 = TimeSpan.Parse($"{command.RestTimePanjShanbe1}:{command.RestTimePanjShanbe1Min}"); - rest6w1 = TimeSpan.Parse($"{command.RestTimeJome1}:{command.RestTimeJome1Min}"); - - // sumrest week2 - rest0w2 = TimeSpan.Parse($"{command.RestTimeShanbe2}:{command.RestTimeShanbe2Min}"); - rest1w2 = TimeSpan.Parse($"{command.RestTimeYekShanbe2}:{command.RestTimeYekShanbe2Min}"); - rest2w2 = TimeSpan.Parse($"{command.RestTimeDoShanbe2}:{command.RestTimeDoShanbe2Min}"); - rest3w2 = TimeSpan.Parse($"{command.RestTimeSeShanbe2}:{command.RestTimeSeShanbe2Min}"); - rest4w2 = TimeSpan.Parse($"{command.RestTimeCheharShanbe2}:{command.RestTimeCheharShanbe2Min}"); - rest5w2 = TimeSpan.Parse($"{command.RestTimePanjShanbe2}:{command.RestTimePanjShanbe2Min}"); - rest6w2 = TimeSpan.Parse($"{command.RestTimeJome2}:{command.RestTimeJome2Min}"); - - // sumrest week3 - rest0w3 = TimeSpan.Parse($"{command.RestTimeShanbe3}:{command.RestTimeShanbe3Min}"); - rest1w3 = TimeSpan.Parse($"{command.RestTimeYekShanbe3}:{command.RestTimeYekShanbe3Min}"); - rest2w3 = TimeSpan.Parse($"{command.RestTimeDoShanbe3}:{command.RestTimeDoShanbe3Min}"); - rest3w3 = TimeSpan.Parse($"{command.RestTimeSeShanbe3}:{command.RestTimeSeShanbe3Min}"); - rest4w3 = TimeSpan.Parse($"{command.RestTimeCheharShanbe3}:{command.RestTimeCheharShanbe3Min}"); - rest5w3 = TimeSpan.Parse($"{command.RestTimePanjShanbe3}:{command.RestTimePanjShanbe3Min}"); - rest6w3 = TimeSpan.Parse($"{command.RestTimeJome3}:{command.RestTimeJome3Min}"); - - // sumrest week4 - rest0w4 = TimeSpan.Parse($"{command.RestTimeShanbe4}:{command.RestTimeShanbe4Min}"); - rest1w4 = TimeSpan.Parse($"{command.RestTimeYekShanbe4}:{command.RestTimeYekShanbe4Min}"); - rest2w4 = TimeSpan.Parse($"{command.RestTimeDoShanbe4}:{command.RestTimeDoShanbe4Min}"); - rest3w4 = TimeSpan.Parse($"{command.RestTimeSeShanbe4}:{command.RestTimeSeShanbe4Min}"); - rest4w4 = TimeSpan.Parse($"{command.RestTimeCheharShanbe4}:{command.RestTimeCheharShanbe4Min}"); - rest5w4 = TimeSpan.Parse($"{command.RestTimePanjShanbe4}:{command.RestTimePanjShanbe4Min}"); - rest6w4 = TimeSpan.Parse($"{command.RestTimeJome4}:{command.RestTimeJome4Min}"); - - } - - - #endregion - - #region Complex - //[12-24 : 5] [24-24 : 6] [12-36 : 7] [24-48 : 8] - if (command.ShiftWork is "5" or "6" or "7" or "8") - { - int addHours = command.ShiftWork switch - { - "5" => 36, - "6" => 48, - "7" => 48, - "8" => 72, - _ => 0 - }; - var start = Convert.ToDateTime(command.StartComplex); - var end = Convert.ToDateTime(command.EndComplex); - - var startDateAndTime = new PersianDateTime(syear, smonth, sday, start.Hour, start.Minute); - var startContract = new PersianDateTime(syear, smonth, sday, start.Hour, start.Minute); - var endContract = new PersianDateTime(eyear, emonth, eday, 23, 59); - for (var da = startDateAndTime; da <= endContract; da = da.AddHours(addHours)) - { - - - var currentDateFa = $"{da}"; - var currentDateGr = da.ToGregorianDateTime(); - if (da == startContract) - { - start = new DateTime(currentDateGr.Year, currentDateGr.Month, currentDateGr.Day, start.Hour, start.Minute, 0); - end = new DateTime(currentDateGr.Year, currentDateGr.Month, currentDateGr.Day, end.Hour, end.Minute, 0); - if (start.Date == end.Date && start.TimeOfDay > end.TimeOfDay) - end = end.AddDays(1); - if ((command.ShiftWork is "6" or "8") && start == end) - end = end.AddDays(1); - - } - - var startComplex = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, - start.Second); - var endComplex = new DateTime(end.Year, end.Month, end.Day, end.Hour, end.Minute, - end.Second); - Console.WriteLine($"{currentDateFa} - {currentDateGr.Date} - start : {startComplex} end : {endComplex}"); - - rollCallList.Add(new RollCallViewModel() - { - StartDate = startComplex, - EndDate = endComplex, - ShiftSpan = (endComplex - startComplex), - ShiftDate = currentDateGr, - }); - - - var endCal = end - start; - start = startComplex.AddHours(addHours); - end = start.Add(endCal); - - } - - var countLeves = leaveSearchResult.Where(x => x.PaidLeaveType == "روزانه").ToList(); - if (countLeves.Count > 0) - { - int totalDays = countLeves.Sum(x => int.Parse(x.LeaveHourses)); - - - int countRollCall = rollCallList.Count(); - int takRollCall = totalDays < countRollCall ? (countRollCall - totalDays) : 0; - rollCallList = rollCallList.Take(takRollCall).ToList(); - } - - } - - #endregion - - - - #region ShiftWork4Compute - - if (command.ShiftWork == "4") - { - //DateTime currentDay = ($"{da}").ToGeorgianDateTime(); - var hasSickLeave = false; - for (var da = d1; da <= d2; da.AddDays(1)) - { - var FirstDayOfMonth = new PersianDateTime(da.Year, da.Month, 1); - var w1 = 0; - var w2 = 0; - var w3 = 0; - var w4 = 0; - var w5 = 0; - var w6 = 0; - var currentDateFa = $"{da}"; - DateTime currntDateGr = currentDateFa.ToGeorgianDateTime(); - if (!workshopHolidyWorking) - { - isHoliday = holidayList.Any(x => x == currentDateFa); - } - switch (FirstDayOfMonth.DayOfWeek) - { - case "شنبه": - w1 = 7; - w2 = 14; - w3 = 28; - w4 = 31; - break; - case "یکشنبه": - w1 = 6; - w2 = 13; - w3 = 20; - w4 = 27; - w5 = 31; - break; - case "دوشنبه": - w1 = 5; - w2 = 12; - w3 = 19; - w4 = 26; - w5 = 31; - break; - case "سه شنبه": - w1 = 4; - w2 = 11; - w3 = 18; - w4 = 25; - w5 = 31; - break; - case "چهارشنبه": - w1 = 3; - w2 = 10; - w3 = 17; - w4 = 24; - w5 = 31; - break; - case "پنج شنبه": - w1 = 2; - w2 = 9; - w3 = 16; - w4 = 23; - w5 = 30; - w6 = 31; - break; - case "جمعه": - w1 = 1; - w2 = 8; - w3 = 15; - w4 = 22; - w5 = 29; - w6 = 31; - break; - } - - switch (da.DayOfWeek) - { - case "شنبه": - - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.Shanbe1 && isHoliday == false) - { - - var res = FindStaticShiftsStatus( - command.SingleShift1Shanbe1, - command.SingleShift2Shanbe1, - command.TowShifts1Shanbe1, - command.TowShifts2Shanbe1, currntDateGr, rest0w1,leaveSearchResult); - if (res.Count> 0) - rollCallList.AddRange(res); - - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.Shanbe2 && isHoliday == false) - { - - var res = FindStaticShiftsStatus( - command.SingleShift1Shanbe2, - command.SingleShift2Shanbe2, - command.TowShifts1Shanbe2, - command.TowShifts2Shanbe2, currntDateGr, rest0w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - - } - else if (da.Day > w2 && da.Day <= w3 && command.Shanbe3 && isHoliday == false) - { - - var res = FindStaticShiftsStatus( - command.SingleShift1Shanbe3, - command.SingleShift2Shanbe3, - command.TowShifts1Shanbe3, - command.TowShifts2Shanbe3, currntDateGr, rest0w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - - } - else if (da.Day > w3 && da.Day <= w4 && command.Shanbe4 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1Shanbe4, - command.SingleShift2Shanbe4, - command.TowShifts1Shanbe4, - command.TowShifts2Shanbe4, currntDateGr, rest0w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - - } - break; - case "یکشنبه": - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.YekShanbe1 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1YekShanbe1, - command.SingleShift2YekShanbe1, - command.TowShifts1YekShanbe1, - command.TowShifts2YekShanbe1, currntDateGr, rest1w1, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.YekShanbe2 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1YekShanbe2, - command.SingleShift2YekShanbe2, - command.TowShifts1YekShanbe2, - command.TowShifts2YekShanbe2, currntDateGr, rest1w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w2 && da.Day <= w3 && command.YekShanbe3 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1YekShanbe3, - command.SingleShift2YekShanbe3, - command.TowShifts1YekShanbe3, - command.TowShifts2YekShanbe3, currntDateGr, rest1w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w3 && da.Day <= w4 && command.YekShanbe4 && isHoliday == false) - { - - var res = FindStaticShiftsStatus( - command.SingleShift1YekShanbe4, - command.SingleShift2YekShanbe4, - command.TowShifts1YekShanbe4, - command.TowShifts2YekShanbe4, currntDateGr, rest1w4, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - break; - case "دوشنبه": - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.DoShanbe1 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1DoShanbe1, - command.SingleShift2DoShanbe1, - command.TowShifts1DoShanbe1, - command.TowShifts2DoShanbe1, currntDateGr, rest2w1, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.DoShanbe2 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1DoShanbe2, - command.SingleShift2DoShanbe2, - command.TowShifts1DoShanbe2, - command.TowShifts2DoShanbe2, currntDateGr, rest2w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w2 && da.Day <= w3 && command.DoShanbe3 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1DoShanbe3, - command.SingleShift2DoShanbe3, - command.TowShifts1DoShanbe3, - command.TowShifts2DoShanbe3, currntDateGr, rest2w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - - } - else if (da.Day > w3 && da.Day <= w4 && command.DoShanbe4 && isHoliday == false) - { - - var res = FindStaticShiftsStatus( - command.SingleShift1DoShanbe4, - command.SingleShift2DoShanbe4, - command.TowShifts1DoShanbe4, - command.TowShifts2DoShanbe4, currntDateGr, rest2w4, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - - - break; - case "سه شنبه": - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.SeShanbe1 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1SeShanbe1, - command.SingleShift2SeShanbe1, - command.TowShifts1SeShanbe1, - command.TowShifts2SeShanbe1, currntDateGr, rest3w1, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.SeShanbe2 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1SeShanbe2, - command.SingleShift2SeShanbe2, - command.TowShifts1SeShanbe2, - command.TowShifts2SeShanbe2, currntDateGr, rest3w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w2 && da.Day <= w3 && command.SeShanbe3 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1SeShanbe3, - command.SingleShift2SeShanbe3, - command.TowShifts1SeShanbe3, - command.TowShifts2SeShanbe3, currntDateGr, rest3w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w3 && da.Day <= w4 && command.SeShanbe4 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1SeShanbe4, - command.SingleShift2SeShanbe4, - command.TowShifts1SeShanbe4, - command.TowShifts2SeShanbe4, currntDateGr, rest3w4, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - break; - case "چهارشنبه": - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.CheharShanbe1 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1CheharShanbe1, - command.SingleShift2CheharShanbe1, - command.TowShifts1CheharShanbe1, - command.TowShifts2CheharShanbe1, currntDateGr, rest4w1, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.CheharShanbe2 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1CheharShanbe2, - command.SingleShift2CheharShanbe2, - command.TowShifts1CheharShanbe2, - command.TowShifts2CheharShanbe2, currntDateGr, rest4w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w2 && da.Day <= w3 && command.CheharShanbe3 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1CheharShanbe3, - command.SingleShift2CheharShanbe3, - command.TowShifts1CheharShanbe3, - command.TowShifts2CheharShanbe3, currntDateGr, rest4w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w3 && da.Day <= w4 && command.CheharShanbe4 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1CheharShanbe4, - command.SingleShift2CheharShanbe4, - command.TowShifts1CheharShanbe4, - command.TowShifts2CheharShanbe4, currntDateGr, rest4w4, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - break; - case "پنج شنبه": - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.PanjShanbe2 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1PanjShanbe1, - command.SingleShift2PanjShanbe1, - command.TowShifts1PanjShanbe1, - command.TowShifts2PanjShanbe1, currntDateGr, rest5w1, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.PanjShanbe2 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1PanjShanbe2, - command.SingleShift2PanjShanbe2, - command.TowShifts1PanjShanbe2, - command.TowShifts2PanjShanbe2, currntDateGr, rest5w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w2 && da.Day <= w3 && command.PanjShanbe3 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1PanjShanbe3, - command.SingleShift2PanjShanbe3, - command.TowShifts1PanjShanbe3, - command.TowShifts2PanjShanbe3, currntDateGr, rest5w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w3 && da.Day <= w4 && command.PanjShanbe4 && isHoliday == false) - { - var res = FindStaticShiftsStatus( - command.SingleShift1PanjShanbe4, - command.SingleShift2PanjShanbe4, - command.TowShifts1PanjShanbe4, - command.TowShifts2PanjShanbe4, currntDateGr, rest5w4, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - break; - case "جمعه": - if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.Jome1) - { - var res = FindStaticShiftsStatus( - command.SingleShift1Jome1, - command.SingleShift2Jome1, - command.TowShifts1Jome1, - command.TowShifts2Jome1, currntDateGr, rest6w1, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.Jome2) - { - var res = FindStaticShiftsStatus( - command.SingleShift1Jome2, - command.SingleShift2Jome2, - command.TowShifts1Jome2, - command.TowShifts2Jome2, currntDateGr, rest6w2, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w2 && da.Day <= w3 && command.Jome3) - { - var res = FindStaticShiftsStatus( - command.SingleShift1Jome3, - command.SingleShift2Jome3, - command.TowShifts1Jome3, - command.TowShifts2Jome3, currntDateGr, rest6w3, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - else if (da.Day > w3 && da.Day <= w4 && command.Jome4) - { - var res = FindStaticShiftsStatus( - command.SingleShift1Jome4, - command.SingleShift2Jome4, - command.TowShifts1Jome4, - command.TowShifts2Jome4, currntDateGr, rest6w4, leaveSearchResult); - if (res.Count > 0) - rollCallList.AddRange(res); - } - break; - } - - } - } - - #endregion - - return rollCallList; - } - - /// - /// جاگذاری شیفت های استاتیک در بازه تاریخ - /// - /// - private List FindStaticShiftsStatus(string shift1Start, string shift1End, string shift2Start, - string shift2End, DateTime cuurentDate, TimeSpan restTime, List leaveSearchResult) - { - var result = new List(); - - var shift1StartGr = new DateTime(); - var shift1EndGr = new DateTime(); - - var shift2StartGr = new DateTime(); - var shift2EndGr = new DateTime(); - if (leaveSearchResult.Count > 0) - { - - leaveSearchResult = leaveSearchResult.Select(x => new LeaveViewModel() - { - LeaveHourses = x.LeaveHourses, - LeaveType = x.LeaveType, - PaidLeaveType = x.PaidLeaveType, - StartLeaveGr = x.StartLeaveGr, - EndLeaveGr = x.PaidLeaveType == "روزانه" ? new DateTime(x.EndLeaveGr.Year, x.EndLeaveGr.Month, x.EndLeaveGr.Day, 23,59,59) : x.EndLeaveGr, - }).ToList(); - } - - - #region Shift1 - - - - - - if (!string.IsNullOrWhiteSpace(shift1Start) && !string.IsNullOrWhiteSpace(shift1End)) - { - try - { - var starTimeSingel1 = Convert.ToDateTime(shift1Start); - var endTimeSingel2 = Convert.ToDateTime(shift1End); - - - - shift1StartGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, starTimeSingel1.Hour, starTimeSingel1.Minute,0); - shift1EndGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, endTimeSingel2.Hour, endTimeSingel2.Minute, 0); - - if (shift1EndGr.TimeOfDay < shift1StartGr.TimeOfDay) - shift1EndGr = shift1EndGr.AddDays(1); - - var shiftSpan = (shift1EndGr - shift1StartGr); - if (restTime > TimeSpan.Zero && shiftSpan >= restTime) - { - shift1EndGr = shift1EndGr.Subtract(restTime); - shiftSpan = (shift1EndGr - shift1StartGr); - } - - if (!leaveSearchResult.Any(x => x.StartLeaveGr < shift1EndGr && x.EndLeaveGr > shift1StartGr && x.PaidLeaveType =="روزانه")) - { - var hourseLeaveTypeResult = leaveSearchResult.FirstOrDefault(x => - x.StartLeaveGr < shift1EndGr && x.EndLeaveGr > shift1StartGr && x.PaidLeaveType == "ساعتی"); - if (hourseLeaveTypeResult == null) - { - result.Add(new RollCallViewModel() - { - StartDate = shift1StartGr, - EndDate = shift1EndGr, - ShiftSpan = shiftSpan, - ShiftDate = shift1StartGr, - }); - } - else - { - - if (hourseLeaveTypeResult.StartLeaveGr <= shift1StartGr && hourseLeaveTypeResult.EndLeaveGr < shift1EndGr) - { - //leave <--------------------> - //shift <----------------------------------> - result.Add(new RollCallViewModel() - { - StartDate = hourseLeaveTypeResult.EndLeaveGr, - EndDate = shift1EndGr, - ShiftSpan = (shift1EndGr - hourseLeaveTypeResult.EndLeaveGr), - ShiftDate = shift1StartGr, - }); - } - else if (hourseLeaveTypeResult.StartLeaveGr > shift1StartGr && hourseLeaveTypeResult.EndLeaveGr < shift1EndGr) - { - //leave <--------------------> - //shift <----------------------------------> - result.Add(new RollCallViewModel() - { - StartDate = shift1StartGr, - EndDate = hourseLeaveTypeResult.StartLeaveGr, - ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift1StartGr), - ShiftDate = shift1StartGr, - }); - - result.Add(new RollCallViewModel() - { - StartDate = hourseLeaveTypeResult.EndLeaveGr, - EndDate = shift1EndGr, - ShiftSpan = (shift1EndGr - hourseLeaveTypeResult.EndLeaveGr), - ShiftDate = shift1StartGr, - }); - } - else if (hourseLeaveTypeResult.StartLeaveGr > shift1StartGr && hourseLeaveTypeResult.EndLeaveGr >= shift1EndGr) - { - //leave <--------------------> - //shift <----------------------------------> - - result.Add(new RollCallViewModel() - { - StartDate = shift1StartGr, - EndDate = hourseLeaveTypeResult.StartLeaveGr, - ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift1StartGr), - ShiftDate = shift1StartGr, - }); - - } - - - } - - } - - } - catch (Exception e) - { - // ignored - } - } - - #endregion - - #region Shift2 - - if (!string.IsNullOrWhiteSpace(shift2Start) && !string.IsNullOrWhiteSpace(shift2End)) - { - try - { - - - var startTimeTowSh1 = Convert.ToDateTime(shift2Start); - var endTimeTowSh2 = Convert.ToDateTime(shift2End); - - //اگر شیفت 1 وجود داشت تاریخ جاری را از شیف 1 میگیریم - //زیرا ممکن پایان شیف 1 در روز بعد باشد - var shift1 = result.MaxBy(x=>x.EndDate); - if (shift1 != null) - if (shift1.EndDate != null) - cuurentDate = shift1.EndDate.Value; - - - shift2StartGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, startTimeTowSh1.Hour, startTimeTowSh1.Minute,0); - shift2EndGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, endTimeTowSh2.Hour, endTimeTowSh2.Minute,0); - - if (shift2EndGr.TimeOfDay < shift2StartGr.TimeOfDay) - shift2EndGr = shift2EndGr.AddDays(1); - - if (!leaveSearchResult.Any(x => x.StartLeaveGr < shift2EndGr && x.EndLeaveGr > shift2StartGr && x.PaidLeaveType == "روزانه")) - { - var hourseLeaveTypeResult = leaveSearchResult.FirstOrDefault(x => - x.StartLeaveGr < shift2EndGr && x.EndLeaveGr > shift2StartGr && x.PaidLeaveType == "ساعتی"); - if (hourseLeaveTypeResult == null) - { - - - result.Add(new RollCallViewModel() - { - StartDate = shift2StartGr, - EndDate = shift2EndGr, - ShiftSpan = (shift2EndGr - shift2StartGr), - ShiftDate = shift1?.ShiftDate ?? shift2EndGr, - }); - } - else - { - - if (hourseLeaveTypeResult.StartLeaveGr <= shift2StartGr && hourseLeaveTypeResult.EndLeaveGr < shift2EndGr) - { - //leave <--------------------> - //shift <----------------------------------> - result.Add(new RollCallViewModel() - { - StartDate = hourseLeaveTypeResult.EndLeaveGr, - EndDate = shift2EndGr, - ShiftSpan = (shift2EndGr - hourseLeaveTypeResult.EndLeaveGr), - ShiftDate = shift1?.EndDate ?? shift2EndGr, - }); - } - else if (hourseLeaveTypeResult.StartLeaveGr > shift2StartGr && hourseLeaveTypeResult.EndLeaveGr < shift2EndGr) - { - //leave <--------------------> - //shift <----------------------------------> - result.Add(new RollCallViewModel() - { - StartDate = shift2StartGr, - EndDate = hourseLeaveTypeResult.StartLeaveGr, - ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift2StartGr), - ShiftDate = shift1?.EndDate ?? shift2EndGr, - }); - - result.Add(new RollCallViewModel() - { - StartDate = hourseLeaveTypeResult.EndLeaveGr, - EndDate = shift2EndGr, - ShiftSpan = (shift2EndGr - hourseLeaveTypeResult.EndLeaveGr), - ShiftDate = shift1?.EndDate ?? shift2EndGr, - }); - } - else if (hourseLeaveTypeResult.StartLeaveGr > shift2StartGr && hourseLeaveTypeResult.EndLeaveGr >= shift2EndGr) - { - //leave <--------------------> - //shift <----------------------------------> - - result.Add(new RollCallViewModel() - { - StartDate = shift2StartGr, - EndDate = hourseLeaveTypeResult.StartLeaveGr, - ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift2StartGr), - ShiftDate = shift1?.EndDate ?? shift2EndGr, - }); - - } - - - } - - } - - } - catch (Exception e) - { - // ignored - } - } - - #endregion - - - return result; - - } - - - #endregion - - #region CustomizeCheckout - - /// - /// متد محاسبه فیش حقوقی دلخواه - /// - /// - /// - /// - /// - /// - public CustomizeCheckoutMandatoryViewModel CustomizeCheckoutMandatoryCompute(long employeeId, long workshopId, DateTime contractStart, - DateTime contractEnd) - { - var checkoutEnd = contractEnd; - var checkoutStart = contractStart; - if (workshopId == 170) - return CustomizeCheckoutMandatoryComputeForKebabMahdi(employeeId, workshopId, contractStart, contractEnd); - - var firstDayOfMonth = $"{(contractStart.ToFarsi())[..8]}/01".ToGeorgianDateTime(); - - #region LeftWork - - var leftWork = _leftWorkRepository.GetByWorkshopIdEmployeeIdInDates(workshopId, employeeId, contractStart, contractEnd); - - if (leftWork.StartWorkDateGr > contractStart) - { - contractStart = leftWork.StartWorkDateGr; - } - - if (leftWork.LeftWorkDateGr.AddDays(-1) < contractEnd) - { - contractEnd = leftWork.LeftWorkDateGr.AddDays(-1); - } - - TimeSpan leftWorkDurationTimeSpan = leftWork.HasLeft ? leftWork.LeftWorkDateGr.AddDays(-1) - leftWork.StartWorkDateGr : contractEnd - leftWork.StartWorkDateGr; - - - #endregion - - - #region Entities - - int numberOfFridays = 0; - double monthySalary = 0; - int monthDays = 0; - double dailyWage = 0; - int numberOfWorkingDay = 0; - string endPersianDate = contractEnd.ToFarsi(); - int monthOfCheckout = Convert.ToInt32(endPersianDate.Substring(5, 2)); - int yearOfCheckout = Convert.ToInt32(endPersianDate.Substring(0, 4)); - //روز هایی که پرسنل موظف بوده کار کند - var mandatoryDays = 0; + private readonly CompanyContext _context; + private readonly IYearlySalaryRepository _yearlySalaryRepository; + private readonly ILeftWorkRepository _leftWorkRepository; + private readonly ILeaveRepository _leaveRepository; + private readonly IHolidayItemRepository _holidayItemRepository; + private readonly TestDbContext _testDbContext; + + + public RollCallMandatoryRepository(CompanyContext context, IYearlySalaryRepository yearlySalaryRepository, + ILeftWorkRepository leftWorkRepository, ILeaveRepository leaveRepository, IHolidayItemRepository holidayItemRepository, TestDbContext testDbContext) : base(context) + { + _context = context; + _yearlySalaryRepository = yearlySalaryRepository; + _leftWorkRepository = leftWorkRepository; + _leaveRepository = leaveRepository; + _holidayItemRepository = holidayItemRepository; + _testDbContext = testDbContext; + } + + #region OfficialChckout + public ComputingViewModel MandatoryCompute(long employeeId, long workshopId, DateTime contractStart, + DateTime contractEnd, + CreateWorkingHoursTemp command, bool holidayWorking, bool isStaticCheckout) + { + #region Entities + + string SumWorkeTime = string.Empty; + var weeklyTime = new TimeSpan(); + string shift1Hourse = "0"; + string overMandatoryHours = "0"; + string overMandatoryMinuts = "0"; + string shiftOver22Hours = "0"; + string shiftOver22Minuts = "0"; + double ShiftPayResult = 0; + int numberOfFridays = 0; + #endregion + + int TotalContractDays = (int)(contractEnd - contractStart).TotalDays + 1; + int fridays = 0; + int holiday = _context.HolidayItems.Count(x => x.Holidaydate >= contractStart && x.Holidaydate <= contractEnd); + ; + for (var gDate = contractStart; gDate <= contractEnd; gDate = gDate.AddDays(1)) + { + if (gDate.DayOfWeek == DayOfWeek.Friday) + { + fridays += 1; + } + } + int TotalDaysNoFriday = TotalContractDays - fridays; + int mandatorDays = TotalContractDays - (fridays + holiday); + if (command.ShiftWork != "4" && isStaticCheckout) + mandatorDays = TotalDaysNoFriday; + //if (holidayWorking) + // mandatorDays = TotalContractDays - fridays; + //***********************************// + //This Time Mandatory Hourse + double mandatoryHours = Math.Round((mandatorDays * 7.33), 2); + + //گرفتن ساعت استراحت پرسنل از تنظیمات + #region breakTime + BaseCustomizeEntity settings = _context.CustomizeWorkshopEmployeeSettings.AsSplitQuery() + .Include(x => x.CustomizeWorkshopGroupSettings).FirstOrDefault(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId); + //اگر ساعت استراحت پرسنل وجود نداشت صفر است + var breakTime = settings == null ? new BreakTime(false, new TimeOnly()) : settings.BreakTime; + + + #endregion + + List rollCallResult; + List groupedRollCall; + if (isStaticCheckout) + { + command.WorkshopId = workshopId; + command.EmployeeId = employeeId; + command.ContractStartGr = contractStart; + command.ContractEndGr = contractEnd; + rollCallResult = ConvertStaticHoursToRollCall(command, holidayWorking); + groupedRollCall = rollCallResult.GroupBy(x => x.ShiftDate.Date).Select(x => new GroupedRollCalls() + { + CreationDate = x.Key, + ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), + HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), + + SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) + + }).OrderBy(x => x.CreationDate).ToList(); + } + else + { + rollCallResult = _context.RollCalls.Where(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate.Value.Date >= contractStart.Date && + x.StartDate.Value.Date <= contractEnd.Date && x.EndDate != null).Select(x => new RollCallViewModel() + { + StartDate = x.StartDate, + EndDate = x.EndDate, + ShiftSpan = (x.EndDate.Value - x.StartDate.Value), + CreationDate = x.ShiftDate, + BreakTimeSpan = x.BreakTimeSpan + }).ToList(); + + groupedRollCall = rollCallResult.GroupBy(x => x.CreationDate.Date).Select(x => new GroupedRollCalls() + { + CreationDate = x.Key, + ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), + HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), + SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - CalculateBreakTime(x.First().BreakTimeSpan, + new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), + + BreakTime = CalculateBreakTime(x.First().BreakTimeSpan, new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), + + }).OrderBy(x => x.CreationDate).ToList(); + } + + + numberOfFridays = groupedRollCall.Count(x => x.HasFriday); + + ////*****کسر ساعاعت استراحت پرسنل از ساعت کار + //List rollCallSubtractSpan = groupedRollCall.Select(x => new GroupedRollCalls() + //{ + // CreationDate = x.CreationDate, + // AfterSubtractRestSpan = AfterSubtract(command, x.SumOneDaySpan, x.CreationDate), + //}).ToList(); + + + + + TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); + TimeSpan sumSpansWhitOutleaves = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); + + + //بدست آوردن مرخصی ساعتی + LeaveSearchModel hoursleaveSearch = new LeaveSearchModel() + { + EmployeeId = employeeId, + WorkshopId = workshopId, + LeaveType = "استحقاقی", + PaidLeaveType = "ساعتی", + StartLeaveGr = contractStart, + EndLeaveGr = contractEnd, + IsAccepted = true, + }; + var hoursesleave = _leaveRepository.search(hoursleaveSearch); + var hoursesleaveTimeSpansList = hoursesleave.Count > 0 + ? hoursesleave.Select(x => TimeSpan.Parse(x.LeaveHourses)).ToList() + : new List(); + + // مجموع مرخصی ساعتی + var hoursesleaveTimeSpans = new TimeSpan(hoursesleaveTimeSpansList.Sum(x => x.Ticks)); + //کسر مرخصی ساعتی از فیش استاتیک + if (isStaticCheckout && command.ShiftWork != "4") + { + // کم کردن از مجموع ساعت کار پرسنل + sumSpans = sumSpans.Subtract(hoursesleaveTimeSpans); + + } + + + + //****افزودن مرخصی پرسنل به مجموع ساعات کار*** + #region AddEmployeeLeavs + + + LeaveSearchModel leaveSearch = new LeaveSearchModel() + { + EmployeeId = employeeId, + WorkshopId = workshopId, + LeaveType = "استحقاقی", + PaidLeaveType = "روزانه", + StartLeaveGr = contractStart, + EndLeaveGr = contractEnd, + IsAccepted = true, + }; + var leaveSearchResult = _leaveRepository.search(leaveSearch); + // {مقدار ساعت مجاز مرخصی در برای یک روز{کامل + var leaveHoursesPerDay = 190.58 / 365; + + // {مقدار ساعت مجاز مرخصی در مدت این فیش حقوقی{کامل + var starndardHoursesPerTotalDays = leaveHoursesPerDay * TotalContractDays; + // جدا کردن ساعت و دقیقه + int hours = (int)starndardHoursesPerTotalDays; + double minutesDecimal = (starndardHoursesPerTotalDays - hours) * 60; + int minutes = (int)minutesDecimal; + + + TimeSpan starndardHoursesPerTotalDaysSapn = new TimeSpan(hours, minutes, 0); + if (leaveSearchResult.Count > 0) + { + if (leaveSearchResult.Any(x => x.HasShiftDuration)) + { + var sumSpansDouble = (sumSpans.TotalMinutes) / 60; + if (sumSpansDouble < mandatoryHours) + { + starndardHoursesPerTotalDays = (sumSpansDouble * starndardHoursesPerTotalDays) / mandatoryHours; + // جدا کردن ساعت و دقیقه + hours = (int)starndardHoursesPerTotalDays; + minutesDecimal = (starndardHoursesPerTotalDays - hours) * 60; + minutes = (int)minutesDecimal; + + + starndardHoursesPerTotalDaysSapn = new TimeSpan(hours, minutes, 0); + } + + TimeSpan totalLeave = new TimeSpan(leaveSearchResult.Sum(x => x.ShiftDuration.Ticks)); + totalLeave = totalLeave.Add(hoursesleaveTimeSpans); + var totalLeaveDouble = (totalLeave.TotalMinutes) / 60; + if (totalLeaveDouble > starndardHoursesPerTotalDays) + { + + sumSpans = sumSpans.Add(starndardHoursesPerTotalDaysSapn); + } + else + { + sumSpans = sumSpans.Add(totalLeave); + } + + + + } + else + { + int leavingDayCout = 0; + //مرخصی های مابین + List beatweenCheckout = leaveSearchResult.Where(x => x.StartLeaveGr >= contractStart && x.EndLeaveGr <= contractEnd).Select(x => new LeaveViewModel() + { + DayCounter = Convert.ToInt32(x.LeaveHourses), + + }).ToList(); + leavingDayCout += beatweenCheckout.Sum(x => x.DayCounter); + // مرخصی که شروعش قبل از شروع تصفیه حساب است + List beforeCheckout = leaveSearchResult.Where(x => x.StartLeaveGr < contractStart).Select(x => new LeaveViewModel() + { + DayCounter = (int)(contractStart - x.EndLeaveGr).TotalDays + 1, + + }).ToList(); + leavingDayCout += beforeCheckout.Sum(x => x.DayCounter); + // مرخصی که پایانش بعد از پایان تصفیه حساب است + List afterCheckout = leaveSearchResult.Where(x => x.EndLeaveGr > contractEnd).Select(x => new LeaveViewModel() + { + DayCounter = (int)(x.StartLeaveGr - contractEnd).TotalDays + 1, + + }).ToList(); + leavingDayCout += afterCheckout.Sum(x => x.DayCounter); + Console.WriteLine(leavingDayCout); + + + TimeSpan workingPerDayAve = sumSpans / groupedRollCall.Count;//میانگین ساعت کار در روز + TimeSpan sumLeave = new TimeSpan(); + if (workingPerDayAve <= new TimeSpan(7, 20, 0)) + { + sumLeave = leavingDayCout * workingPerDayAve; + sumLeave = sumLeave.Add(hoursesleaveTimeSpans); + } + else + { + sumLeave = leavingDayCout * new TimeSpan(7, 20, 0); + } + + + if (sumLeave > starndardHoursesPerTotalDaysSapn) + { + sumSpans = sumSpans.Add(starndardHoursesPerTotalDaysSapn); + } + else + { + sumSpans = sumSpans.Add(sumLeave); + } + } + + + } + //اگر مرخصی روزانه نداشت و فقط مرخصی ساعتی داشت + if (leaveSearchResult.Count == 0 && hoursesleave.Count > 0) + { + if (hoursesleaveTimeSpans > starndardHoursesPerTotalDaysSapn) + { + sumSpans = sumSpans.Add(starndardHoursesPerTotalDaysSapn); + } + else + { + sumSpans = sumSpans.Add(hoursesleaveTimeSpans); + } + } + Console.WriteLine(sumSpans); + #endregion + //***********************************// + //ToTalHourse Employe eWorked + double totalHourses = (sumSpans.TotalMinutes) / 60; + int totalHolidaysAndNotH = (int)sumSpans.TotalHours; + int totalHolidaysAndNotM = (int)(sumSpans.TotalMinutes % 60); + //***********************************// + + + //********** محاسبه مدت اضافه کاری ***********// + #region ComputeMandatoryAtThisTime + + + + //***********************************// + var dailyFix = TimeSpan.Parse("07:20"); + TimeSpan mandatoryHoursTimeSpan = new TimeSpan(7, 20, 0).Multiply(mandatorDays); + TimeSpan Mandatory = sumSpansWhitOutleaves.Subtract(mandatoryHoursTimeSpan); + + double mandatoryWorkWithOutleaves = (sumSpansWhitOutleaves.TotalMinutes) / 60; + double overTimeWork = 0; + if (mandatoryWorkWithOutleaves > mandatoryHours) + { + overTimeWork = mandatoryWorkWithOutleaves - mandatoryHours; + + } + + + #endregion + + //******* دستمزد روزانه *******// + #region DailyFeeCompute + + var searchModel = new LeftWorkSearchModel() + { + EmployeeId = command.EmployeeId, + WorkshopId = command.WorkshopId, + + }; + + var leftworkList = _leftWorkRepository.search(searchModel); + var basic = "0"; + double dayliFeeComplete = 0; + var GetWorkStartDate = command.GetWorkDateHide.ToEnglishNumber(); + var styear = Convert.ToInt32(GetWorkStartDate.Substring(0, 4)); + var startDate = command.GetWorkDateHide.ToGeorgianDateTime(); + var dayliFee = "خطای تاریخ"; + double dayliFeeDouble = 0; + if (styear >= 1370) + { + + if (leftworkList == null) + leftworkList = new List(); + + var dayliFeeResult = _yearlySalaryRepository.DayliFeeComputing(startDate, contractStart, contractEnd, + command.EmployeeId, command.WorkshopId, leftworkList); + dayliFee = dayliFeeResult.DayliFee; + dayliFeeDouble = dayliFeeResult.DayliFeeDouble; + dayliFeeComplete = dayliFeeResult.DayliFee.MoneyToDouble(); + basic = dayliFeeResult.Basic; + } + + #endregion + + #region ConsumableItemsAndHousingAndFamily + + var ConsumableItems = _yearlySalaryRepository.ConsumableItems(contractEnd); + var HousingAllowance = _yearlySalaryRepository.HousingAllowance(contractEnd); + + var familyAllowance = _yearlySalaryRepository.FamilyAllowance(command.EmployeeId, contractStart, contractEnd); + var MarriedAllowance = _yearlySalaryRepository.MarriedAllowance(contractEnd, command.EmployeeId); + // حق تاهل + string MarriedAllowanceStr = MarriedAllowance > 0 ? MarriedAllowance.ToMoney() : "0"; + #endregion + + var totalWeek = (int)(TotalContractDays / 6); + + #region Fix44Compute + int TotalContractdaysUnder30 = TotalContractDays > 30 ? 30 : TotalContractDays; + if (totalHourses < mandatoryHours) + { + if (!string.IsNullOrWhiteSpace(command.ShiftWork)) + { + var workedHoursePerDay = totalHourses / mandatorDays; + var result = (dayliFeeDouble / 7.33) * workedHoursePerDay; + + + dayliFee = result.ToMoney(); + + var HousingAllowonceNumberType = HousingAllowance.MoneyToDouble(); + var HousingStep1 = HousingAllowonceNumberType / 30; + var HousingStep2 = HousingStep1 / 7.33; + var HousingStep3 = HousingStep2 * workedHoursePerDay; + var HousingStep4 = HousingStep3 * TotalContractdaysUnder30; + HousingAllowance = HousingStep4.ToMoney(); + + var ConsumableItemsNumberType = ConsumableItems.MoneyToDouble(); + var consumableItemsStep1 = ConsumableItemsNumberType / 30; + var consumableItemsStep2 = consumableItemsStep1 / 7.33; + var consumableItemsStep3 = consumableItemsStep2 * workedHoursePerDay; + var consumableItemsStep4 = consumableItemsStep3 * TotalContractdaysUnder30; + ConsumableItems = consumableItemsStep4.ToMoney(); + + + + //حق تاهل + if (MarriedAllowance > 0) + { + var MarriedStep1 = MarriedAllowance / 30; + var MarriedStep2 = MarriedStep1 / 7.33; + var MarriedStep3 = MarriedStep2 * workedHoursePerDay; + var MarriedStep4 = MarriedStep3 * TotalContractdaysUnder30; + MarriedAllowanceStr = MarriedStep4.ToMoney(); + } + + if (familyAllowance != "0") + { + + var familyAllowanceNumberType = familyAllowance.MoneyToDouble(); + var familyAllowanceStep1 = familyAllowanceNumberType / 30; + var familyAllowanceStep2 = familyAllowanceStep1 / 7.33; + var familyAllowanceStep3 = familyAllowanceStep2 * workedHoursePerDay; + var familyAllowanceStep4 = familyAllowanceStep3 * TotalContractdaysUnder30; + familyAllowance = familyAllowanceStep4.ToMoney(); + } + + if (totalWeek > 1) + { + + double weekAvrage = 0; + if (totalHourses < 44.00) + { + weekAvrage = (totalHourses * 6) / TotalContractDays; + } + else + { + weekAvrage = (totalHourses * 6) / TotalDaysNoFriday; + } + + //var oneday = weekAvrage * 6; + var totalShiftRound = Math.Round(weekAvrage, 2); + SumWorkeTime = $"{totalShiftRound}"; + + } + else if (totalWeek <= 1 && TotalDaysNoFriday <= 6) + { + var totalShiftRound = Math.Round(totalHourses, 2); + SumWorkeTime = $"{totalShiftRound}"; + } + else if (totalWeek <= 1 && TotalDaysNoFriday > 6) + + { + var perDyeWorked = totalHourses / TotalDaysNoFriday; + var weekAvrage = perDyeWorked * 6; + var totalShiftRound = Math.Round(weekAvrage, 2); + SumWorkeTime = $"{totalShiftRound}"; + } + + weeklyTime = sumSpans; + } + + } + else // اگر بیشتر از 44 بود + { + + var HousingAllowonceNumberType = HousingAllowance.MoneyToDouble(); + var ConsumableItemsNumberType = ConsumableItems.MoneyToDouble(); + var familyAllowanceNumberType = familyAllowance.MoneyToDouble(); + + var HousingStep1 = HousingAllowonceNumberType / 30; + var HousingStep4 = HousingStep1 * TotalContractdaysUnder30; + HousingAllowance = HousingStep4.ToMoney(); + + + var consumableItemsStep1 = ConsumableItemsNumberType / 30; + var consumableItemsStep4 = consumableItemsStep1 * TotalContractdaysUnder30; + ConsumableItems = consumableItemsStep4.ToMoney(); + + //حق تاهل + if (MarriedAllowance > 0) + { + var MarriedStep1 = MarriedAllowance / 30; + var MarriedStep4 = MarriedStep1 * TotalContractdaysUnder30; + MarriedAllowanceStr = MarriedStep4.ToMoney(); + } + + if (familyAllowance != "0") + { + var familyAllowanceStep1 = familyAllowanceNumberType / 30; + var familyAllowanceStep4 = familyAllowanceStep1 * TotalContractdaysUnder30; + familyAllowance = familyAllowanceStep4.ToMoney(); + } + + SumWorkeTime = $"{44}"; + + //اضافه کار + if (overTimeWork > 0) + { + + //int mandatoryH = (int)Mandatory.TotalHours; + //int mandatoryM = (int)(Mandatory.TotalMinutes % 60); + int mandatoryH = (int)overTimeWork; + int mandatoryM = (int)Math.Round((overTimeWork - mandatoryH) * 60); + overMandatoryHours = mandatoryH.ToString(); + overMandatoryMinuts = mandatoryM.ToString(); + } + + } + #endregion + + //****** نوبت کاری و شب کاری **** + #region RotatingShiftCheckAndNightWorkOver22 + + string shiftPayValue = "0"; + List rotatingResultList = RotatingShiftCheck(groupedRollCall); + + // شبکاری + TimeSpan over22 = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); + var RotatingfaName = new List(); + //if (command.ShiftWork != "1" && command.ShiftWork != "2" && command.ShiftWork != "4")//اگر چرخشی بود و منظم نبود + //{ + // if (moriningCount > 0) + // RotatingfaName.Add("صبح"); + // if (eveningCount > 0) + // RotatingfaName.Add("عصر"); + // if (nightCount > 0) + // RotatingfaName.Add("شب"); + //} + //else// اگر منظم و شیفتی بود + //{ + // var totalDays = (int)(command.ContractEndGr - command.ContractStartGr).TotalDays + 1; + // int validCount = 0; + // if (totalDays <= 7) // زیر 7 روز باید حد اقل 2 تغییر شیفت داشته باشد + // { + // validCount = 2; + // } + // else if (totalDays >= 28) // بالای 28 روز حد اقل 8 تغییر شیفت + // { + // validCount = 8; + // } + // else + // { + // // تناسب گیری - اگر برای 28 روز 8 تغییر پس برای ایکس روز چند تغییر لازم است + // validCount = (int)((totalDays * 8) / 28); + // } + + // if (moriningCount >= validCount) + // RotatingfaName.Add("صبح"); + // if (eveningCount >= validCount) + // RotatingfaName.Add("عصر"); + // if (nightCount >= validCount) + // RotatingfaName.Add("شب"); + + //} + + int moriningCount = 0; + int eveningCount = 0; + int nightCount = 0; + + int moriningWinRate = rotatingResultList.Where(x => x.IsMorningShift).Sum(x => x.WinRate); + int eveningWinRate = rotatingResultList.Where(x => x.IsEveningShift).Sum(x => x.WinRate); + int nightWinRate = rotatingResultList.Where(x => x.IsNightShift).Sum(x => x.WinRate); + + + if (moriningWinRate > eveningWinRate && moriningWinRate > nightWinRate) + { + moriningCount = rotatingResultList.Count(x => x.IsMorningShift); + eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); + nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); + } + + if (eveningWinRate > moriningWinRate && eveningWinRate > nightWinRate) + { + moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); + eveningCount = rotatingResultList.Count(x => x.IsEveningShift); + nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); + } + + if (nightWinRate > moriningWinRate && nightWinRate > eveningWinRate) + { + moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); + eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); + nightCount = rotatingResultList.Count(x => x.IsNightShift); + } + + var totalDays = (int)(command.ContractEndGr - command.ContractStartGr).TotalDays + 1; + int validCount = 0; + if (totalDays <= 7) // زیر 7 روز باید حد اقل 2 تغییر شیفت داشته باشد + { + validCount = 2; + } + else if (totalDays >= 28) // بالای 28 روز حد اقل 8 تغییر شیفت + { + validCount = 8; + } + else + { + // تناسب گیری - اگر برای 28 روز 8 تغییر پس برای ایکس روز چند تغییر لازم است + validCount = (int)((totalDays * 8) / 28); + } + + if (moriningCount >= validCount) + RotatingfaName.Add("صبح"); + if (eveningCount >= validCount) + RotatingfaName.Add("عصر"); + if (nightCount >= validCount) + RotatingfaName.Add("شب"); + var rotatingFaResult = ""; + if (RotatingfaName.Count > 1)// اگر تعداد شیفت های محاسبه شده بیش از یک بود + { + shiftOver22Hours = "0"; + shiftOver22Minuts = "0"; + for (var rotateNumber = 0; rotateNumber < RotatingfaName.Count; rotateNumber++) + { + if (rotateNumber == 0) + rotatingFaResult = $"{RotatingfaName[rotateNumber]}"; + if (rotateNumber == 1) + rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; + if (rotateNumber == 2) + rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; + } + } + else if (RotatingfaName.Count <= 1) + { + rotatingFaResult = "نوبت کاری ندارد"; + + var over22Hours = (int)over22.TotalHours; + var over22Minuts = (int)(over22.TotalMinutes % 60); + shiftOver22Hours = over22Hours.ToString(); + shiftOver22Minuts = over22Minuts.ToString(); + + } + #endregion + //******* محاسبه مبلغ نوبت کاری ************* + #region ShiftPayPercent + + if (rotatingFaResult != "نوبت کاری ندارد" || rotatingFaResult != "") + { + var TotalDays = (command.ContractEndGr - command.ContractStartGr).TotalDays + 1; + var DailyFeeNumberType = dayliFee.MoneyToDouble(); + if (rotatingFaResult == "صبح و عصر") + { + var shiftPyaPercent = DailyFeeNumberType * 10 / 100; + ShiftPayResult = shiftPyaPercent * TotalDays; + shiftPayValue = "10"; + } + else if (rotatingFaResult == "صبح و عصر و شب") + { + var shiftPyaPercent = DailyFeeNumberType * 15 / 100; + ShiftPayResult = shiftPyaPercent * TotalDays; + shiftPayValue = "15"; + } + else if (rotatingFaResult == "صبح و شب" || rotatingFaResult == "عصر و شب") + { + var shiftPyaPercent = DailyFeeNumberType * 22.5 / 100; + ShiftPayResult = shiftPyaPercent * TotalDays; + shiftPayValue = "22.5"; + } + } + + #endregion + + #region Result + + var res = new ComputingViewModel() + { + + NumberOfWorkingDays = $"{groupedRollCall.Count}", + NumberOfFriday = $"{numberOfFridays}", + TotalHoursesH = totalHolidaysAndNotH.ToString(), + TotalHoursesM = totalHolidaysAndNotM.ToString(), + OverTimeWorkH = overMandatoryHours, + OverTimeWorkM = overMandatoryMinuts, + OverNightWorkH = shiftOver22Hours, + OverNightWorkM = shiftOver22Minuts, + ComplexNumberOfWorkingDays = $"{groupedRollCall.Count}", + SalaryCompute = dayliFee, + SumTime44 = SumWorkeTime, + ConsumableItems = ConsumableItems, + HousingAllowance = HousingAllowance, + FamilyAllowance = familyAllowance, + OfficialHoliday = holiday, + weeklyTime = weeklyTime, + RotatingResultList = rotatingResultList, + RotatingStatus = rotatingFaResult, + ShiftPay = ShiftPayResult, + Basic = basic, + FridayStartToEnd = fridays, + TotalHolidayAndNotH = totalHolidaysAndNotH.ToString(), + TotalHolidayAndNotM = totalHolidaysAndNotM.ToString(), + DayliFeeComplete = dayliFeeComplete, + MarriedAllowance = MarriedAllowanceStr, + RotatingShiftValue = shiftPayValue + }; + + #endregion + return res; + } + + public async Task RotatingShiftReport(long workshopId, long employeeId, DateTime contractStart, DateTime contractEnd, string shiftwork, bool hasRollCall, CreateWorkingHoursTemp command, bool holidayWorking) + { + List rollCallResult = new List(); + List groupedRollCall = new List(); + if (hasRollCall) + { + rollCallResult = await _context.RollCalls.Where(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate.Value.Date >= contractStart.Date && + x.StartDate.Value.Date <= contractEnd.Date && x.EndDate != null).Select(x => new RollCallViewModel() + { + StartDate = x.StartDate, + EndDate = x.EndDate, + ShiftSpan = (x.EndDate.Value - x.StartDate.Value), + CreationDate = x.ShiftDate, + }).ToListAsync(); + groupedRollCall = rollCallResult.GroupBy(x => x.CreationDate.Date).Select(x => new GroupedRollCalls() + { + CreationDate = x.Key, + ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), + HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), + + + + }).OrderBy(x => x.CreationDate).ToList(); + } + else + { + command.WorkshopId = workshopId; + command.EmployeeId = employeeId; + command.ContractStartGr = contractStart; + command.ContractEndGr = contractEnd; + rollCallResult = ConvertStaticHoursToRollCall(command, holidayWorking); + groupedRollCall = rollCallResult.GroupBy(x => x.ShiftDate.Date).Select(x => new GroupedRollCalls() + { + CreationDate = x.Key, + ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), + HasFriday = x.Any(s => s.StartDate != null && s.EndDate != null && (s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value!.DayOfWeek == DayOfWeek.Friday)), + + SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) + + }).OrderBy(x => x.CreationDate).ToList(); + } + + + + //****** نوبت کاری و شب کاری **** + #region RotatingShiftCheckAndNightWorkOver22 + + string shiftPayValue = "0"; + List rotatingResultList = RotatingShiftCheck(groupedRollCall); + int moriningCount = 0; + int eveningCount = 0; + int nightCount = 0; + + int moriningWinRate = rotatingResultList.Where(x => x.IsMorningShift).Sum(x => x.WinRate); + int eveningWinRate = rotatingResultList.Where(x => x.IsEveningShift).Sum(x => x.WinRate); + int nightWinRate = rotatingResultList.Where(x => x.IsNightShift).Sum(x => x.WinRate); + + + if (moriningWinRate > eveningWinRate && moriningWinRate > nightWinRate) + { + moriningCount = rotatingResultList.Count(x => x.IsMorningShift); + eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); + nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); + } + + if (eveningWinRate > moriningWinRate && eveningWinRate > nightWinRate) + { + moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); + eveningCount = rotatingResultList.Count(x => x.IsEveningShift); + nightCount = rotatingResultList.Count(x => x.IsNightShift && x.WinRate > 55); + } + + if (nightWinRate > moriningWinRate && nightWinRate > eveningWinRate) + { + moriningCount = rotatingResultList.Count(x => x.IsMorningShift && x.WinRate > 55); + eveningCount = rotatingResultList.Count(x => x.IsEveningShift && x.WinRate > 55); + nightCount = rotatingResultList.Count(x => x.IsNightShift); + } + + + + + + + // شبکاری + TimeSpan over22 = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); + var RotatingfaName = new List(); + //if (shiftwork != "1" && shiftwork != "2" && shiftwork != "4")//اگر چرخشی بود و منظم نبود + //{ + // if (moriningCount > 0) + // RotatingfaName.Add("صبح"); + // if (eveningCount > 0) + // RotatingfaName.Add("عصر"); + // if (nightCount > 0) + // RotatingfaName.Add("شب"); + //} + //else// اگر منظم و شیفتی بود + //{ + + + //} + var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; + int validCount = 0; + if (totalDays <= 7) // زیر 7 روز باید حد اقل 2 تغییر شیفت داشته باشد + { + validCount = 2; + } + else if (totalDays >= 28) // بالای 28 روز حد اقل 8 تغییر شیفت + { + validCount = 6; + } + else + { + // تناسب گیری - اگر برای 28 روز 8 تغییر پس برای ایکس روز چند تغییر لازم است + validCount = (int)((totalDays * 6) / 28); + } + + Console.WriteLine(validCount); + if (moriningCount >= validCount) + RotatingfaName.Add("صبح"); + if (eveningCount >= validCount) + RotatingfaName.Add("عصر"); + if (nightCount >= validCount) + RotatingfaName.Add("شب"); + + + + var rotatingFaResult = ""; + if (RotatingfaName.Count > 1)// اگر تعداد شیفت های محاسبه شده بیش از یک بود + { + + for (var rotateNumber = 0; rotateNumber < RotatingfaName.Count; rotateNumber++) + { + if (rotateNumber == 0) + rotatingFaResult = $"{RotatingfaName[rotateNumber]}"; + if (rotateNumber == 1) + rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; + if (rotateNumber == 2) + rotatingFaResult += $" و {RotatingfaName[rotateNumber]}"; + } + } + else if (RotatingfaName.Count <= 1) + { + rotatingFaResult = "نوبت کاری ندارد"; + + + + } + + return new ComputingViewModel + { + RotatingStatus = rotatingFaResult, + RotatingResultList = rotatingResultList + + }; + + #endregion + } + + + + + //public static TimeSpan CalculateBreakTime(BreakTime breakTime, TimeSpan sumOneDaySpan) + //{ + // if (breakTime.BreakTimeType != BreakTimeType.WithTime) + // return new TimeSpan(); + + // var breakTimeSpan = breakTime.BreakTimeValue.ToTimeSpan(); + + // if (breakTimeSpan * 2 >= sumOneDaySpan) + // return new TimeSpan(); + + // return breakTimeSpan; ; + + //} + public static TimeSpan CalculateBreakTime(TimeSpan breakTimeSpan, TimeSpan sumOneDaySpan) + { + if (breakTimeSpan * 2 >= sumOneDaySpan) + return new TimeSpan(); + return breakTimeSpan; ; + } + + public TimeSpan AfterSubtract(CreateWorkingHoursTemp command, TimeSpan sumOneDaySpan, DateTime creationDate) + { + #region RestTimes + + var rest0 = new TimeSpan(); + var rest1 = new TimeSpan(); + var rest2 = new TimeSpan(); + var rest3 = new TimeSpan(); + var rest4 = new TimeSpan(); + var rest5 = new TimeSpan(); + var rest6 = new TimeSpan(); + switch (command.ShiftWork) + { + case "1": + case "2": + command.RestTime = command.RestTime == "0" ? "00" : command.RestTime; + command.RestTimeYekshanbeh = command.RestTimeYekshanbeh == "0" ? "00" : command.RestTimeYekshanbeh; + command.RestTimeDoshanbeh = command.RestTimeDoshanbeh == "0" ? "00" : command.RestTimeDoshanbeh; + command.RestTimeSeshanbeh = command.RestTimeSeshanbeh == "0" ? "00" : command.RestTimeSeshanbeh; + command.RestTimeCheharshanbeh = + command.RestTimeCheharshanbeh == "0" ? "00" : command.RestTimeCheharshanbeh; + command.RestTimePanjshanbeh = command.RestTimePanjshanbeh == "0" ? "00" : command.RestTimePanjshanbeh; + command.RestTimeJomeh = command.RestTimeJomeh == "0" ? "00" : command.RestTimeJomeh; + command.RestTimeMin = command.RestTimeMin == "0" ? "00" : command.RestTimeMin; + command.RestTimeYekshanbehMin = + command.RestTimeYekshanbehMin == "0" ? "00" : command.RestTimeYekshanbehMin; + command.RestTimeDoshanbehMin = + command.RestTimeDoshanbehMin == "0" ? "00" : command.RestTimeDoshanbehMin; + command.RestTimeSeshanbehMin = + command.RestTimeSeshanbehMin == "0" ? "00" : command.RestTimeSeshanbehMin; + command.RestTimeCheharshanbehMin = + command.RestTimeCheharshanbehMin == "0" ? "00" : command.RestTimeCheharshanbehMin; + command.RestTimePanjshanbehMin = + command.RestTimePanjshanbehMin == "0" ? "00" : command.RestTimePanjshanbehMin; + command.RestTimeJomehMin = command.RestTimeJomehMin == "0" ? "00" : command.RestTimeJomehMin; + + rest0 = TimeSpan.Parse($"{command.RestTime}:{command.RestTimeMin}"); + rest1 = TimeSpan.Parse($"{command.RestTimeYekshanbeh}:{command.RestTimeYekshanbehMin}"); + rest2 = TimeSpan.Parse($"{command.RestTimeDoshanbeh}:{command.RestTimeDoshanbehMin}"); + rest3 = TimeSpan.Parse($"{command.RestTimeSeshanbeh}:{command.RestTimeSeshanbehMin}"); + rest4 = TimeSpan.Parse($"{command.RestTimeCheharshanbeh}:{command.RestTimeCheharshanbehMin}"); + rest5 = TimeSpan.Parse($"{command.RestTimePanjshanbeh}:{command.RestTimePanjshanbehMin}"); + rest6 = TimeSpan.Parse($"{command.RestTimeJomeh}:{command.RestTimeJomehMin}"); + break; + case "4": + command.RestTimeShanbe1 = command.RestTimeShanbe1 == "0" ? "00" : command.RestTimeShanbe1; + command.RestTimeShanbe1Min = command.RestTimeShanbe1Min == "0" ? "00" : command.RestTimeShanbe1Min; + command.RestTimeYekShanbe1 = command.RestTimeYekShanbe1 == "0" ? "00" : command.RestTimeYekShanbe1; + command.RestTimeYekShanbe1Min = + command.RestTimeYekShanbe1Min == "0" ? "00" : command.RestTimeYekShanbe1Min; + command.RestTimeDoShanbe1 = command.RestTimeDoShanbe1 == "0" ? "00" : command.RestTimeDoShanbe1; + command.RestTimeDoShanbe1Min = + command.RestTimeDoShanbe1Min == "0" ? "00" : command.RestTimeDoShanbe1Min; + command.RestTimeSeShanbe1 = command.RestTimeSeShanbe1 == "0" ? "00" : command.RestTimeSeShanbe1; + command.RestTimeSeShanbe1Min = + command.RestTimeSeShanbe1Min == "0" ? "00" : command.RestTimeSeShanbe1Min; + command.RestTimeCheharShanbe1 = + command.RestTimeCheharShanbe1 == "0" ? "00" : command.RestTimeCheharShanbe1; + command.RestTimeCheharShanbe1Min = + command.RestTimeCheharShanbe1Min == "0" ? "00" : command.RestTimeCheharShanbe1Min; + command.RestTimePanjShanbe1 = command.RestTimePanjShanbe1 == "0" ? "00" : command.RestTimePanjShanbe1; + command.RestTimePanjShanbe1Min = + command.RestTimePanjShanbe1Min == "0" ? "00" : command.RestTimePanjShanbe1Min; + command.RestTimeJome1 = command.RestTimeJome1 == "0" ? "00" : command.RestTimeJome1; + command.RestTimeJome1Min = command.RestTimeJome1Min == "0" ? "00" : command.RestTimeJome1Min; + + // sumrest week1 + rest0 = TimeSpan.Parse($"{command.RestTimeShanbe1}:{command.RestTimeShanbe1Min}"); + rest1 = TimeSpan.Parse($"{command.RestTimeYekShanbe1}:{command.RestTimeYekShanbe1Min}"); + rest2 = TimeSpan.Parse($"{command.RestTimeDoShanbe1}:{command.RestTimeDoShanbe1Min}"); + rest3 = TimeSpan.Parse($"{command.RestTimeSeShanbe1}:{command.RestTimeSeShanbe1Min}"); + rest4 = TimeSpan.Parse($"{command.RestTimeCheharShanbe1}:{command.RestTimeCheharShanbe1Min}"); + rest5 = TimeSpan.Parse($"{command.RestTimePanjShanbe1}:{command.RestTimePanjShanbe1Min}"); + rest6 = TimeSpan.Parse($"{command.RestTimeJome1}:{command.RestTimeJome1Min}"); + break; + } + //week1 + + + #endregion + + var result = new TimeSpan(); + switch (creationDate.DayOfWeek) + { + case DayOfWeek.Saturday: + if (sumOneDaySpan >= rest0) + result = sumOneDaySpan.Subtract(rest0); + break; + case DayOfWeek.Sunday: + if (sumOneDaySpan >= rest1) + result = sumOneDaySpan.Subtract(rest1); + break; + case DayOfWeek.Monday: + if (sumOneDaySpan >= rest2) + result = sumOneDaySpan.Subtract(rest2); + break; + case DayOfWeek.Tuesday: + if (sumOneDaySpan >= rest3) + result = sumOneDaySpan.Subtract(rest3); + break; + case DayOfWeek.Wednesday: + if (sumOneDaySpan >= rest4) + result = sumOneDaySpan.Subtract(rest4); + break; + case DayOfWeek.Thursday: + if (sumOneDaySpan >= rest5) + result = sumOneDaySpan.Subtract(rest5); + break; + case DayOfWeek.Friday: + if (sumOneDaySpan >= rest6) + result = sumOneDaySpan.Subtract(rest6); + break; + } + + return result; + } + + public List RotatingShiftCheck(List rollCallList) + { + List finalResult = new List(); + var nullDateTme = new DateTime(0001, 01, 01); + foreach (var item in rollCallList) + { + #region Entityes + + var morningWorkingTime = new TimeSpan(); + var eveningWorkingTime = new TimeSpan(); + var nightWorkingTime = new TimeSpan(); + + #endregion + + foreach (var shift in item.ShiftList) + { + #region DatePeriod + + var shiftDate = item.CreationDate; + if (shift.Start.Date < shiftDate.Date) + shiftDate = shiftDate.AddDays(-1); + + DateTime midNight24 = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 0, 0, 0); + DateTime morningStart = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 6, 0, 0); + DateTime morningEnd = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 14, 0, 0); + DateTime eveningStart = morningEnd; + DateTime eveningEnd = new DateTime(shiftDate.Year, shiftDate.Month, shiftDate.Day, 22, 0, 0); + DateTime nightStart = eveningEnd; + DateTime nightEnd = morningStart; + DateTime nightEndNextday = nightEnd.AddDays(1); + DateTime morningEndNextday = morningEnd.AddDays(1); + DateTime eveningEndNextday = eveningEnd.AddDays(1); + + #endregion + + #region MidNight Enter 00:00 ---> 6 + + if (shift.Start >= midNight24 // 00:00 >---> 6 + && shift.End <= morningStart) + { + nightWorkingTime = nightWorkingTime.Add(shift.End - shift.Start); + } + else if (shift.Start >= midNight24 && shift.Start < morningStart // 00:00---6--->14 + && shift.End > morningStart && shift.End <= morningEnd) + { + nightWorkingTime = nightWorkingTime.Add(morningStart - shift.Start); + morningWorkingTime = morningWorkingTime.Add(shift.End - morningStart); + } + else if (shift.Start >= midNight24 && shift.Start < morningStart// 00:00---6---14--->22 + && shift.End > morningEnd && shift.End <= eveningEnd) + { + nightWorkingTime = nightWorkingTime.Add(morningStart - shift.Start); + morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); + eveningWorkingTime = eveningWorkingTime.Add(shift.End - eveningStart); + + } + else if (shift.Start >= midNight24 // 00:00---6---14----22---->6 + && shift.Start < morningStart + && shift.End > eveningEnd && shift.End <= nightEndNextday) + { + nightWorkingTime = nightWorkingTime.Add(morningStart - shift.Start); + morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); + eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); + nightWorkingTime = nightWorkingTime.Add(shift.End - eveningEnd); + + } + + #endregion + + #region morning enter 14 <- 6 + if (shift.Start >= morningStart // 14<---<6 + && shift.End <= morningEnd) + { + morningWorkingTime = morningWorkingTime.Add(shift.End - shift.Start); + } + else if (shift.Start >= morningStart && shift.Start < morningEnd // 22<---14---6 + && shift.End > eveningStart && shift.End <= eveningEnd) + { + morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); + eveningWorkingTime = eveningWorkingTime.Add(shift.End - eveningStart); + + } + else if (shift.Start >= morningStart && shift.Start < morningEnd// // 6<---22---14---6 + && shift.End > eveningEnd && shift.End <= nightEndNextday) + { + morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); + eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); + nightWorkingTime = nightWorkingTime.Add(shift.End - eveningEnd); + } + else if (shift.Start >= morningStart // 14<---6<---22---14---6 + && shift.Start < morningEnd + && shift.End > nightEndNextday && shift.End <= morningEndNextday) + { + morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); + eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); + nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); + TimeSpan nextDayMorningSpan = (shift.End - nightEndNextday); + morningWorkingTime = morningWorkingTime.Add(nextDayMorningSpan); + } + else if (shift.Start >= morningStart // 22<---14<---6<---22---14---6 + && shift.Start < morningEnd + && shift.End > morningEndNextday && shift.End <= eveningEndNextday) + { + morningWorkingTime = morningWorkingTime.Add(morningEnd - shift.Start); + eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); + nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); + morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); + TimeSpan nextDayEveningSpan = (shift.End - morningEndNextday); + eveningWorkingTime = eveningWorkingTime.Add(nextDayEveningSpan); + + } + + + #endregion + + #region evening enter 22 <- 14 + + if (shift.Start >= eveningStart // 22<---<14 + && shift.End <= eveningEnd) + { + eveningWorkingTime = eveningWorkingTime.Add(shift.End - shift.Start); + } + else if (shift.Start >= eveningStart && shift.Start < eveningEnd // 6<---22---14 + && shift.End > nightStart && shift.End <= nightEndNextday) + { + eveningWorkingTime = eveningWorkingTime.Add(eveningEnd - shift.Start); + nightWorkingTime = nightWorkingTime.Add(shift.End - eveningEnd); + + } + else if (shift.Start >= eveningStart && shift.Start < eveningEnd// // 14<---6---22---14 + && shift.End > nightEndNextday && shift.End <= morningEndNextday) + { + eveningWorkingTime = eveningWorkingTime.Add(eveningEnd - shift.Start); + nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); + morningWorkingTime = morningWorkingTime.Add(shift.End - nightEndNextday); + } + else if (shift.Start >= eveningStart // 22<---14<---6---22---14 + && shift.Start < eveningEnd + && shift.End > morningEndNextday && shift.End <= eveningEndNextday) + { + eveningWorkingTime = eveningWorkingTime.Add(morningEnd - shift.Start); + nightWorkingTime = nightWorkingTime.Add(new TimeSpan(8, 0, 0)); + morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); + TimeSpan nextDayEveningSpan = (shift.End - morningEndNextday); + eveningWorkingTime = eveningWorkingTime.Add(nextDayEveningSpan); + } + + #endregion + + #region night enter 6 <- 22 + if (shift.Start >= nightStart // 6<---<22 + && shift.End <= nightEndNextday) + { + nightWorkingTime = nightWorkingTime.Add(shift.End - shift.Start); + } + else if (shift.Start >= nightStart && shift.Start < nightEndNextday // 14<---6---22 + && shift.End > nightEndNextday && shift.End <= morningEndNextday) + { + nightWorkingTime = nightWorkingTime.Add(nightEndNextday - shift.Start); + morningWorkingTime = morningWorkingTime.Add(shift.End - nightEndNextday); + + } + else if (shift.Start >= nightStart && shift.Start < nightEndNextday// // 22<---14---6---22 + && shift.End > morningEndNextday && shift.End <= eveningEndNextday) + { + nightWorkingTime = nightWorkingTime.Add(nightEndNextday - shift.Start); ; + morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); + eveningWorkingTime = eveningWorkingTime.Add(shift.End - morningEndNextday); + } + else if (shift.Start >= nightStart // 6<---22<---14---6---22 + && shift.Start < nightEndNextday + && shift.End > eveningEndNextday) + { + + nightWorkingTime = nightWorkingTime.Add(nightEndNextday - shift.Start); + morningWorkingTime = morningWorkingTime.Add(new TimeSpan(8, 0, 0)); + eveningWorkingTime = eveningWorkingTime.Add(new TimeSpan(8, 0, 0)); + TimeSpan nextDayNightSpan = (shift.End - eveningEndNextday); + nightWorkingTime = nightWorkingTime.Add(nextDayNightSpan); + } + #endregion + + + + } + #region Result + + var result = new RotatingShiftViewModel(); + result.RotatingDate = item.CreationDate.ToFarsi(); + result.MorningWorkSpan = morningWorkingTime; + result.EveningWorkSpan = eveningWorkingTime; + result.NightWorkSpan = nightWorkingTime; + var nullWorkspan = new TimeSpan(0, 0, 0); + + var totalTime = result.TotalWorkingTime.Add(result.MorningWorkSpan); + totalTime = totalTime.Add(result.EveningWorkSpan); + totalTime = totalTime.Add(result.NightWorkSpan); + + result.TotalWorkingTime = totalTime; + + var morningH = (int)result.MorningWorkSpan.TotalHours; + var morningM = result.MorningWorkSpan.Minutes % 60; + var morningMS = "00"; + if (morningM < 10 && morningM > 0) + morningMS = $"0{morningM}"; + if (morningM > 10) + morningMS = $"{morningM}"; + result.MorningString = $"0{morningH}:{morningMS}"; + + var eveningH = (int)result.EveningWorkSpan.TotalHours; + var eveningM = result.EveningWorkSpan.Minutes % 60; + var eveningMS = "00"; + if (eveningM < 10 && eveningM > 0) + eveningMS = $"0{eveningM}"; + if (eveningM > 10) + eveningMS = $"{eveningM}"; + result.EveningString = $"0{eveningH}:{eveningMS}"; + + var nightH = (int)result.NightWorkSpan.TotalHours; + var nightM = result.NightWorkSpan.Minutes % 60; + var nightMS = "00"; + if (nightM < 10 && nightM > 0) + nightMS = $"0{nightM}"; + if (nightM > 10) + nightMS = $"{nightM}"; + result.NightString = $"0{nightH}:{nightMS}"; + + if (result.MorningWorkSpan > result.EveningWorkSpan + || result.MorningWorkSpan == result.EveningWorkSpan) // if morning bigerThan evening or equal + { + + if (result.MorningWorkSpan != nullWorkspan) + { + var sumSpan = result.MorningWorkSpan.Add(result.EveningWorkSpan); + var sumSpanDouble = sumSpan.TotalMinutes; + var winRate = (result.MorningWorkSpan.TotalMinutes * 100) / sumSpanDouble; + result.WinRate = Convert.ToInt32(winRate); + result.IsMorningShift = true; + result.IsNightShift = false; + result.IsEveningShift = false; + result.RotatingShiftStatus = "صبح"; + + } + + if (result.MorningWorkSpan < result.NightWorkSpan + || result.MorningWorkSpan == result.NightWorkSpan) // if night bigerThan morning or equal + if (result.NightWorkSpan != nullWorkspan) + { + var sumSpan = result.MorningWorkSpan.Add(result.NightWorkSpan); + var sumSpanDouble = sumSpan.TotalMinutes; + var winRate = (result.NightWorkSpan.TotalMinutes * 100) / sumSpanDouble; + result.WinRate = Convert.ToInt32(winRate); + result.IsMorningShift = false; + result.IsNightShift = true; + result.IsEveningShift = false; + result.RotatingShiftStatus = "شب"; + } + } + else if (result.MorningWorkSpan < result.EveningWorkSpan) // if evening bigerThan morning + { + if (result.EveningWorkSpan != nullWorkspan) + { + var sumSpan = result.MorningWorkSpan.Add(result.EveningWorkSpan); + var sumSpanDouble = sumSpan.TotalMinutes; + var winRate = (result.EveningWorkSpan.TotalMinutes * 100) / sumSpanDouble; + result.WinRate = Convert.ToInt32(winRate); + result.IsEveningShift = true; + result.IsMorningShift = false; + result.IsNightShift = false; + result.RotatingShiftStatus = "عصر"; + } + + if (result.EveningWorkSpan < result.NightWorkSpan + || result.EveningWorkSpan == result.NightWorkSpan) // if night bigerThan evening or equal + if (result.NightWorkSpan != nullWorkspan) + { + var sumSpan = result.EveningWorkSpan.Add(result.NightWorkSpan); + var sumSpanDouble = sumSpan.TotalMinutes; + var winRate = (result.NightWorkSpan.TotalMinutes * 100) / sumSpanDouble; + result.WinRate = Convert.ToInt32(winRate); + result.IsMorningShift = false; + result.IsEveningShift = false; + result.IsNightShift = true; + result.RotatingShiftStatus = "شب"; + } + } + + finalResult.Add(result); + #endregion + } + + return finalResult; + + } + + + public List ConvertStaticHoursToRollCall(CreateWorkingHoursTemp command, bool workshopHolidyWorking) + { + var rollCallList = new List(); + #region Entities + + var sdate = command.ContarctStart.ToEnglishNumber(); + var edate = command.ContractEnd.ToEnglishNumber(); + var syear = Convert.ToInt32(sdate.Substring(0, 4)); + var smonth = Convert.ToInt32(sdate.Substring(5, 2)); + var sday = Convert.ToInt32(sdate.Substring(8, 2)); + + var eyear = Convert.ToInt32(edate.Substring(0, 4)); + var emonth = Convert.ToInt32(edate.Substring(5, 2)); + var eday = Convert.ToInt32(edate.Substring(8, 2)); + + var d1 = new PersianDateTime(syear, smonth, sday); + var d2 = new PersianDateTime(eyear, emonth, eday); + + //بدست آوردن مرخصی + LeaveSearchModel leaveSearch = new LeaveSearchModel() + { + EmployeeId = command.EmployeeId, + WorkshopId = command.WorkshopId, + + StartLeaveGr = command.ContractStartGr, + EndLeaveGr = command.ContractEndGr, + IsAccepted = true, + }; + var leaveSearchResult = _leaveRepository.search(leaveSearch); + //بدس آوردن تعطیلات رسمی + var holidayList = _holidayItemRepository.GetHolidayItem(sdate.Substring(0, 4)); + bool isHoliday = false; + + #endregion + + + + #region SumRestTimesOneShift + + var rest0 = new TimeSpan(); + var rest1 = new TimeSpan(); + var rest2 = new TimeSpan(); + var rest3 = new TimeSpan(); + var rest4 = new TimeSpan(); + var rest5 = new TimeSpan(); + var rest6 = new TimeSpan(); + + var rest0w1 = new TimeSpan(); + var rest1w1 = new TimeSpan(); + var rest2w1 = new TimeSpan(); + var rest3w1 = new TimeSpan(); + var rest4w1 = new TimeSpan(); + var rest5w1 = new TimeSpan(); + var rest6w1 = new TimeSpan(); + + var rest0w2 = new TimeSpan(); + var rest1w2 = new TimeSpan(); + var rest2w2 = new TimeSpan(); + var rest3w2 = new TimeSpan(); + var rest4w2 = new TimeSpan(); + var rest5w2 = new TimeSpan(); + var rest6w2 = new TimeSpan(); + + var rest0w3 = new TimeSpan(); + var rest1w3 = new TimeSpan(); + var rest2w3 = new TimeSpan(); + var rest3w3 = new TimeSpan(); + var rest4w3 = new TimeSpan(); + var rest5w3 = new TimeSpan(); + var rest6w3 = new TimeSpan(); + + var rest0w4 = new TimeSpan(); + var rest1w4 = new TimeSpan(); + var rest2w4 = new TimeSpan(); + var rest3w4 = new TimeSpan(); + var rest4w4 = new TimeSpan(); + var rest5w4 = new TimeSpan(); + var rest6w4 = new TimeSpan(); + if (command.ShiftWork == "4") + { + + //week1 + command.RestTimeShanbe1 = command.RestTimeShanbe1 == "0" ? "00" : command.RestTimeShanbe1; + command.RestTimeShanbe1Min = command.RestTimeShanbe1Min == "0" ? "00" : command.RestTimeShanbe1Min; + command.RestTimeYekShanbe1 = command.RestTimeYekShanbe1 == "0" ? "00" : command.RestTimeYekShanbe1; + command.RestTimeYekShanbe1Min = + command.RestTimeYekShanbe1Min == "0" ? "00" : command.RestTimeYekShanbe1Min; + command.RestTimeDoShanbe1 = command.RestTimeDoShanbe1 == "0" ? "00" : command.RestTimeDoShanbe1; + command.RestTimeDoShanbe1Min = + command.RestTimeDoShanbe1Min == "0" ? "00" : command.RestTimeDoShanbe1Min; + command.RestTimeSeShanbe1 = command.RestTimeSeShanbe1 == "0" ? "00" : command.RestTimeSeShanbe1; + command.RestTimeSeShanbe1Min = + command.RestTimeSeShanbe1Min == "0" ? "00" : command.RestTimeSeShanbe1Min; + command.RestTimeCheharShanbe1 = + command.RestTimeCheharShanbe1 == "0" ? "00" : command.RestTimeCheharShanbe1; + command.RestTimeCheharShanbe1Min = + command.RestTimeCheharShanbe1Min == "0" ? "00" : command.RestTimeCheharShanbe1Min; + command.RestTimePanjShanbe1 = command.RestTimePanjShanbe1 == "0" ? "00" : command.RestTimePanjShanbe1; + command.RestTimePanjShanbe1Min = + command.RestTimePanjShanbe1Min == "0" ? "00" : command.RestTimePanjShanbe1Min; + command.RestTimeJome1 = command.RestTimeJome1 == "0" ? "00" : command.RestTimeJome1; + command.RestTimeJome1Min = command.RestTimeJome1Min == "0" ? "00" : command.RestTimeJome1Min; + + //week2 + command.RestTimeShanbe2 = command.RestTimeShanbe2 == "0" ? "00" : command.RestTimeShanbe2; + command.RestTimeShanbe2Min = command.RestTimeShanbe2Min == "0" ? "00" : command.RestTimeShanbe2Min; + command.RestTimeYekShanbe2 = command.RestTimeYekShanbe2 == "0" ? "00" : command.RestTimeYekShanbe2; + command.RestTimeYekShanbe2Min = + command.RestTimeYekShanbe2Min == "0" ? "00" : command.RestTimeYekShanbe2Min; + command.RestTimeDoShanbe2 = command.RestTimeDoShanbe2 == "0" ? "00" : command.RestTimeDoShanbe2; + command.RestTimeDoShanbe2Min = + command.RestTimeDoShanbe2Min == "0" ? "00" : command.RestTimeDoShanbe2Min; + command.RestTimeSeShanbe2 = command.RestTimeSeShanbe2 == "0" ? "00" : command.RestTimeSeShanbe2; + command.RestTimeSeShanbe2Min = + command.RestTimeSeShanbe2Min == "0" ? "00" : command.RestTimeSeShanbe2Min; + command.RestTimeCheharShanbe2 = + command.RestTimeCheharShanbe2 == "0" ? "00" : command.RestTimeCheharShanbe2; + command.RestTimeCheharShanbe2Min = + command.RestTimeCheharShanbe2Min == "0" ? "00" : command.RestTimeCheharShanbe2Min; + command.RestTimePanjShanbe2 = command.RestTimePanjShanbe2 == "0" ? "00" : command.RestTimePanjShanbe2; + command.RestTimePanjShanbe2Min = + command.RestTimePanjShanbe2Min == "0" ? "00" : command.RestTimePanjShanbe2Min; + command.RestTimeJome2 = command.RestTimeJome2 == "0" ? "00" : command.RestTimeJome2; + command.RestTimeJome2Min = command.RestTimeJome2Min == "0" ? "00" : command.RestTimeJome2Min; + + //week3 + command.RestTimeShanbe3 = command.RestTimeShanbe3 == "0" ? "00" : command.RestTimeShanbe3; + command.RestTimeShanbe3Min = command.RestTimeShanbe3Min == "0" ? "00" : command.RestTimeShanbe3Min; + command.RestTimeYekShanbe3 = command.RestTimeYekShanbe3 == "0" ? "00" : command.RestTimeYekShanbe3; + command.RestTimeYekShanbe3Min = + command.RestTimeYekShanbe3Min == "0" ? "00" : command.RestTimeYekShanbe3Min; + command.RestTimeDoShanbe3 = command.RestTimeDoShanbe3 == "0" ? "00" : command.RestTimeDoShanbe3; + command.RestTimeDoShanbe3Min = + command.RestTimeDoShanbe3Min == "0" ? "00" : command.RestTimeDoShanbe3Min; + command.RestTimeSeShanbe3 = command.RestTimeSeShanbe3 == "0" ? "00" : command.RestTimeSeShanbe3; + command.RestTimeSeShanbe3Min = + command.RestTimeSeShanbe3Min == "0" ? "00" : command.RestTimeSeShanbe3Min; + command.RestTimeCheharShanbe3 = + command.RestTimeCheharShanbe3 == "0" ? "00" : command.RestTimeCheharShanbe3; + command.RestTimeCheharShanbe3Min = + command.RestTimeCheharShanbe3Min == "0" ? "00" : command.RestTimeCheharShanbe3Min; + command.RestTimePanjShanbe3 = command.RestTimePanjShanbe3 == "0" ? "00" : command.RestTimePanjShanbe3; + command.RestTimePanjShanbe3Min = + command.RestTimePanjShanbe3Min == "0" ? "00" : command.RestTimePanjShanbe3Min; + command.RestTimeJome3 = command.RestTimeJome3 == "0" ? "00" : command.RestTimeJome3; + command.RestTimeJome3Min = command.RestTimeJome3Min == "0" ? "00" : command.RestTimeJome3Min; + + //week4 + command.RestTimeShanbe4 = command.RestTimeShanbe4 == "0" ? "00" : command.RestTimeShanbe4; + command.RestTimeShanbe4Min = command.RestTimeShanbe4Min == "0" ? "00" : command.RestTimeShanbe4Min; + command.RestTimeYekShanbe4 = command.RestTimeYekShanbe4 == "0" ? "00" : command.RestTimeYekShanbe4; + command.RestTimeYekShanbe4Min = + command.RestTimeYekShanbe4Min == "0" ? "00" : command.RestTimeYekShanbe4Min; + command.RestTimeDoShanbe4 = command.RestTimeDoShanbe4 == "0" ? "00" : command.RestTimeDoShanbe4; + command.RestTimeDoShanbe4Min = + command.RestTimeDoShanbe4Min == "0" ? "00" : command.RestTimeDoShanbe4Min; + command.RestTimeSeShanbe4 = command.RestTimeSeShanbe4 == "0" ? "00" : command.RestTimeSeShanbe4; + command.RestTimeSeShanbe4Min = + command.RestTimeSeShanbe4Min == "0" ? "00" : command.RestTimeSeShanbe4Min; + command.RestTimeCheharShanbe4 = + command.RestTimeCheharShanbe4 == "0" ? "00" : command.RestTimeCheharShanbe4; + command.RestTimeCheharShanbe4Min = + command.RestTimeCheharShanbe4Min == "0" ? "00" : command.RestTimeCheharShanbe4Min; + command.RestTimePanjShanbe4 = command.RestTimePanjShanbe4 == "0" ? "00" : command.RestTimePanjShanbe4; + command.RestTimePanjShanbe4Min = + command.RestTimePanjShanbe4Min == "0" ? "00" : command.RestTimePanjShanbe4Min; + command.RestTimeJome4 = command.RestTimeJome4 == "0" ? "00" : command.RestTimeJome4; + command.RestTimeJome4Min = command.RestTimeJome4Min == "0" ? "00" : command.RestTimeJome4Min; + + // sumrest week1 + rest0w1 = TimeSpan.Parse($"{command.RestTimeShanbe1}:{command.RestTimeShanbe1Min}"); + rest1w1 = TimeSpan.Parse($"{command.RestTimeYekShanbe1}:{command.RestTimeYekShanbe1Min}"); + rest2w1 = TimeSpan.Parse($"{command.RestTimeDoShanbe1}:{command.RestTimeDoShanbe1Min}"); + rest3w1 = TimeSpan.Parse($"{command.RestTimeSeShanbe1}:{command.RestTimeSeShanbe1Min}"); + rest4w1 = TimeSpan.Parse($"{command.RestTimeCheharShanbe1}:{command.RestTimeCheharShanbe1Min}"); + rest5w1 = TimeSpan.Parse($"{command.RestTimePanjShanbe1}:{command.RestTimePanjShanbe1Min}"); + rest6w1 = TimeSpan.Parse($"{command.RestTimeJome1}:{command.RestTimeJome1Min}"); + + // sumrest week2 + rest0w2 = TimeSpan.Parse($"{command.RestTimeShanbe2}:{command.RestTimeShanbe2Min}"); + rest1w2 = TimeSpan.Parse($"{command.RestTimeYekShanbe2}:{command.RestTimeYekShanbe2Min}"); + rest2w2 = TimeSpan.Parse($"{command.RestTimeDoShanbe2}:{command.RestTimeDoShanbe2Min}"); + rest3w2 = TimeSpan.Parse($"{command.RestTimeSeShanbe2}:{command.RestTimeSeShanbe2Min}"); + rest4w2 = TimeSpan.Parse($"{command.RestTimeCheharShanbe2}:{command.RestTimeCheharShanbe2Min}"); + rest5w2 = TimeSpan.Parse($"{command.RestTimePanjShanbe2}:{command.RestTimePanjShanbe2Min}"); + rest6w2 = TimeSpan.Parse($"{command.RestTimeJome2}:{command.RestTimeJome2Min}"); + + // sumrest week3 + rest0w3 = TimeSpan.Parse($"{command.RestTimeShanbe3}:{command.RestTimeShanbe3Min}"); + rest1w3 = TimeSpan.Parse($"{command.RestTimeYekShanbe3}:{command.RestTimeYekShanbe3Min}"); + rest2w3 = TimeSpan.Parse($"{command.RestTimeDoShanbe3}:{command.RestTimeDoShanbe3Min}"); + rest3w3 = TimeSpan.Parse($"{command.RestTimeSeShanbe3}:{command.RestTimeSeShanbe3Min}"); + rest4w3 = TimeSpan.Parse($"{command.RestTimeCheharShanbe3}:{command.RestTimeCheharShanbe3Min}"); + rest5w3 = TimeSpan.Parse($"{command.RestTimePanjShanbe3}:{command.RestTimePanjShanbe3Min}"); + rest6w3 = TimeSpan.Parse($"{command.RestTimeJome3}:{command.RestTimeJome3Min}"); + + // sumrest week4 + rest0w4 = TimeSpan.Parse($"{command.RestTimeShanbe4}:{command.RestTimeShanbe4Min}"); + rest1w4 = TimeSpan.Parse($"{command.RestTimeYekShanbe4}:{command.RestTimeYekShanbe4Min}"); + rest2w4 = TimeSpan.Parse($"{command.RestTimeDoShanbe4}:{command.RestTimeDoShanbe4Min}"); + rest3w4 = TimeSpan.Parse($"{command.RestTimeSeShanbe4}:{command.RestTimeSeShanbe4Min}"); + rest4w4 = TimeSpan.Parse($"{command.RestTimeCheharShanbe4}:{command.RestTimeCheharShanbe4Min}"); + rest5w4 = TimeSpan.Parse($"{command.RestTimePanjShanbe4}:{command.RestTimePanjShanbe4Min}"); + rest6w4 = TimeSpan.Parse($"{command.RestTimeJome4}:{command.RestTimeJome4Min}"); + + } + + + #endregion + + #region Complex + //[12-24 : 5] [24-24 : 6] [12-36 : 7] [24-48 : 8] + if (command.ShiftWork is "5" or "6" or "7" or "8") + { + int addHours = command.ShiftWork switch + { + "5" => 36, + "6" => 48, + "7" => 48, + "8" => 72, + _ => 0 + }; + var start = Convert.ToDateTime(command.StartComplex); + var end = Convert.ToDateTime(command.EndComplex); + + var startDateAndTime = new PersianDateTime(syear, smonth, sday, start.Hour, start.Minute); + var startContract = new PersianDateTime(syear, smonth, sday, start.Hour, start.Minute); + var endContract = new PersianDateTime(eyear, emonth, eday, 23, 59); + for (var da = startDateAndTime; da <= endContract; da = da.AddHours(addHours)) + { + + + var currentDateFa = $"{da}"; + var currentDateGr = da.ToGregorianDateTime(); + if (da == startContract) + { + start = new DateTime(currentDateGr.Year, currentDateGr.Month, currentDateGr.Day, start.Hour, start.Minute, 0); + end = new DateTime(currentDateGr.Year, currentDateGr.Month, currentDateGr.Day, end.Hour, end.Minute, 0); + if (start.Date == end.Date && start.TimeOfDay > end.TimeOfDay) + end = end.AddDays(1); + if ((command.ShiftWork is "6" or "8") && start == end) + end = end.AddDays(1); + + } + + var startComplex = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, + start.Second); + var endComplex = new DateTime(end.Year, end.Month, end.Day, end.Hour, end.Minute, + end.Second); + Console.WriteLine($"{currentDateFa} - {currentDateGr.Date} - start : {startComplex} end : {endComplex}"); + + rollCallList.Add(new RollCallViewModel() + { + StartDate = startComplex, + EndDate = endComplex, + ShiftSpan = (endComplex - startComplex), + ShiftDate = currentDateGr, + }); + + + var endCal = end - start; + start = startComplex.AddHours(addHours); + end = start.Add(endCal); + + } + + var countLeves = leaveSearchResult.Where(x => x.PaidLeaveType == "روزانه").ToList(); + if (countLeves.Count > 0) + { + int totalDays = countLeves.Sum(x => int.Parse(x.LeaveHourses)); + + + int countRollCall = rollCallList.Count(); + int takRollCall = totalDays < countRollCall ? (countRollCall - totalDays) : 0; + rollCallList = rollCallList.Take(takRollCall).ToList(); + } + + } + + #endregion + + + + #region ShiftWork4Compute + + if (command.ShiftWork == "4") + { + //DateTime currentDay = ($"{da}").ToGeorgianDateTime(); + var hasSickLeave = false; + for (var da = d1; da <= d2; da.AddDays(1)) + { + var FirstDayOfMonth = new PersianDateTime(da.Year, da.Month, 1); + var w1 = 0; + var w2 = 0; + var w3 = 0; + var w4 = 0; + var w5 = 0; + var w6 = 0; + var currentDateFa = $"{da}"; + DateTime currntDateGr = currentDateFa.ToGeorgianDateTime(); + if (!workshopHolidyWorking) + { + isHoliday = holidayList.Any(x => x == currentDateFa); + } + switch (FirstDayOfMonth.DayOfWeek) + { + case "شنبه": + w1 = 7; + w2 = 14; + w3 = 28; + w4 = 31; + break; + case "یکشنبه": + w1 = 6; + w2 = 13; + w3 = 20; + w4 = 27; + w5 = 31; + break; + case "دوشنبه": + w1 = 5; + w2 = 12; + w3 = 19; + w4 = 26; + w5 = 31; + break; + case "سه شنبه": + w1 = 4; + w2 = 11; + w3 = 18; + w4 = 25; + w5 = 31; + break; + case "چهارشنبه": + w1 = 3; + w2 = 10; + w3 = 17; + w4 = 24; + w5 = 31; + break; + case "پنج شنبه": + w1 = 2; + w2 = 9; + w3 = 16; + w4 = 23; + w5 = 30; + w6 = 31; + break; + case "جمعه": + w1 = 1; + w2 = 8; + w3 = 15; + w4 = 22; + w5 = 29; + w6 = 31; + break; + } + + switch (da.DayOfWeek) + { + case "شنبه": + + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.Shanbe1 && isHoliday == false) + { + + var res = FindStaticShiftsStatus( + command.SingleShift1Shanbe1, + command.SingleShift2Shanbe1, + command.TowShifts1Shanbe1, + command.TowShifts2Shanbe1, currntDateGr, rest0w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.Shanbe2 && isHoliday == false) + { + + var res = FindStaticShiftsStatus( + command.SingleShift1Shanbe2, + command.SingleShift2Shanbe2, + command.TowShifts1Shanbe2, + command.TowShifts2Shanbe2, currntDateGr, rest0w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + + } + else if (da.Day > w2 && da.Day <= w3 && command.Shanbe3 && isHoliday == false) + { + + var res = FindStaticShiftsStatus( + command.SingleShift1Shanbe3, + command.SingleShift2Shanbe3, + command.TowShifts1Shanbe3, + command.TowShifts2Shanbe3, currntDateGr, rest0w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + + } + else if (da.Day > w3 && da.Day <= w4 && command.Shanbe4 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1Shanbe4, + command.SingleShift2Shanbe4, + command.TowShifts1Shanbe4, + command.TowShifts2Shanbe4, currntDateGr, rest0w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + + } + break; + case "یکشنبه": + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.YekShanbe1 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1YekShanbe1, + command.SingleShift2YekShanbe1, + command.TowShifts1YekShanbe1, + command.TowShifts2YekShanbe1, currntDateGr, rest1w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.YekShanbe2 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1YekShanbe2, + command.SingleShift2YekShanbe2, + command.TowShifts1YekShanbe2, + command.TowShifts2YekShanbe2, currntDateGr, rest1w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w2 && da.Day <= w3 && command.YekShanbe3 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1YekShanbe3, + command.SingleShift2YekShanbe3, + command.TowShifts1YekShanbe3, + command.TowShifts2YekShanbe3, currntDateGr, rest1w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w3 && da.Day <= w4 && command.YekShanbe4 && isHoliday == false) + { + + var res = FindStaticShiftsStatus( + command.SingleShift1YekShanbe4, + command.SingleShift2YekShanbe4, + command.TowShifts1YekShanbe4, + command.TowShifts2YekShanbe4, currntDateGr, rest1w4, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + break; + case "دوشنبه": + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.DoShanbe1 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1DoShanbe1, + command.SingleShift2DoShanbe1, + command.TowShifts1DoShanbe1, + command.TowShifts2DoShanbe1, currntDateGr, rest2w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.DoShanbe2 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1DoShanbe2, + command.SingleShift2DoShanbe2, + command.TowShifts1DoShanbe2, + command.TowShifts2DoShanbe2, currntDateGr, rest2w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w2 && da.Day <= w3 && command.DoShanbe3 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1DoShanbe3, + command.SingleShift2DoShanbe3, + command.TowShifts1DoShanbe3, + command.TowShifts2DoShanbe3, currntDateGr, rest2w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + + } + else if (da.Day > w3 && da.Day <= w4 && command.DoShanbe4 && isHoliday == false) + { + + var res = FindStaticShiftsStatus( + command.SingleShift1DoShanbe4, + command.SingleShift2DoShanbe4, + command.TowShifts1DoShanbe4, + command.TowShifts2DoShanbe4, currntDateGr, rest2w4, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + + + break; + case "سه شنبه": + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.SeShanbe1 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1SeShanbe1, + command.SingleShift2SeShanbe1, + command.TowShifts1SeShanbe1, + command.TowShifts2SeShanbe1, currntDateGr, rest3w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.SeShanbe2 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1SeShanbe2, + command.SingleShift2SeShanbe2, + command.TowShifts1SeShanbe2, + command.TowShifts2SeShanbe2, currntDateGr, rest3w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w2 && da.Day <= w3 && command.SeShanbe3 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1SeShanbe3, + command.SingleShift2SeShanbe3, + command.TowShifts1SeShanbe3, + command.TowShifts2SeShanbe3, currntDateGr, rest3w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w3 && da.Day <= w4 && command.SeShanbe4 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1SeShanbe4, + command.SingleShift2SeShanbe4, + command.TowShifts1SeShanbe4, + command.TowShifts2SeShanbe4, currntDateGr, rest3w4, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + break; + case "چهارشنبه": + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.CheharShanbe1 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1CheharShanbe1, + command.SingleShift2CheharShanbe1, + command.TowShifts1CheharShanbe1, + command.TowShifts2CheharShanbe1, currntDateGr, rest4w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.CheharShanbe2 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1CheharShanbe2, + command.SingleShift2CheharShanbe2, + command.TowShifts1CheharShanbe2, + command.TowShifts2CheharShanbe2, currntDateGr, rest4w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w2 && da.Day <= w3 && command.CheharShanbe3 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1CheharShanbe3, + command.SingleShift2CheharShanbe3, + command.TowShifts1CheharShanbe3, + command.TowShifts2CheharShanbe3, currntDateGr, rest4w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w3 && da.Day <= w4 && command.CheharShanbe4 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1CheharShanbe4, + command.SingleShift2CheharShanbe4, + command.TowShifts1CheharShanbe4, + command.TowShifts2CheharShanbe4, currntDateGr, rest4w4, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + break; + case "پنج شنبه": + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.PanjShanbe2 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1PanjShanbe1, + command.SingleShift2PanjShanbe1, + command.TowShifts1PanjShanbe1, + command.TowShifts2PanjShanbe1, currntDateGr, rest5w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.PanjShanbe2 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1PanjShanbe2, + command.SingleShift2PanjShanbe2, + command.TowShifts1PanjShanbe2, + command.TowShifts2PanjShanbe2, currntDateGr, rest5w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w2 && da.Day <= w3 && command.PanjShanbe3 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1PanjShanbe3, + command.SingleShift2PanjShanbe3, + command.TowShifts1PanjShanbe3, + command.TowShifts2PanjShanbe3, currntDateGr, rest5w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w3 && da.Day <= w4 && command.PanjShanbe4 && isHoliday == false) + { + var res = FindStaticShiftsStatus( + command.SingleShift1PanjShanbe4, + command.SingleShift2PanjShanbe4, + command.TowShifts1PanjShanbe4, + command.TowShifts2PanjShanbe4, currntDateGr, rest5w4, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + break; + case "جمعه": + if (((da.Day <= w1) || (da.Day > w4 && da.Day <= w5)) && command.Jome1) + { + var res = FindStaticShiftsStatus( + command.SingleShift1Jome1, + command.SingleShift2Jome1, + command.TowShifts1Jome1, + command.TowShifts2Jome1, currntDateGr, rest6w1, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (((da.Day > w1 && da.Day <= w2) || (da.Day > w5 && da.Day <= w6)) && command.Jome2) + { + var res = FindStaticShiftsStatus( + command.SingleShift1Jome2, + command.SingleShift2Jome2, + command.TowShifts1Jome2, + command.TowShifts2Jome2, currntDateGr, rest6w2, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w2 && da.Day <= w3 && command.Jome3) + { + var res = FindStaticShiftsStatus( + command.SingleShift1Jome3, + command.SingleShift2Jome3, + command.TowShifts1Jome3, + command.TowShifts2Jome3, currntDateGr, rest6w3, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + else if (da.Day > w3 && da.Day <= w4 && command.Jome4) + { + var res = FindStaticShiftsStatus( + command.SingleShift1Jome4, + command.SingleShift2Jome4, + command.TowShifts1Jome4, + command.TowShifts2Jome4, currntDateGr, rest6w4, leaveSearchResult); + if (res.Count > 0) + rollCallList.AddRange(res); + } + break; + } + + } + } + + #endregion + + return rollCallList; + } + + /// + /// جاگذاری شیفت های استاتیک در بازه تاریخ + /// + /// + private List FindStaticShiftsStatus(string shift1Start, string shift1End, string shift2Start, + string shift2End, DateTime cuurentDate, TimeSpan restTime, List leaveSearchResult) + { + var result = new List(); + + var shift1StartGr = new DateTime(); + var shift1EndGr = new DateTime(); + + var shift2StartGr = new DateTime(); + var shift2EndGr = new DateTime(); + if (leaveSearchResult.Count > 0) + { + + leaveSearchResult = leaveSearchResult.Select(x => new LeaveViewModel() + { + LeaveHourses = x.LeaveHourses, + LeaveType = x.LeaveType, + PaidLeaveType = x.PaidLeaveType, + StartLeaveGr = x.StartLeaveGr, + EndLeaveGr = x.PaidLeaveType == "روزانه" ? new DateTime(x.EndLeaveGr.Year, x.EndLeaveGr.Month, x.EndLeaveGr.Day, 23, 59, 59) : x.EndLeaveGr, + }).ToList(); + } + + + #region Shift1 + + + + + + if (!string.IsNullOrWhiteSpace(shift1Start) && !string.IsNullOrWhiteSpace(shift1End)) + { + try + { + var starTimeSingel1 = Convert.ToDateTime(shift1Start); + var endTimeSingel2 = Convert.ToDateTime(shift1End); + + + + shift1StartGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, starTimeSingel1.Hour, starTimeSingel1.Minute, 0); + shift1EndGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, endTimeSingel2.Hour, endTimeSingel2.Minute, 0); + + if (shift1EndGr.TimeOfDay < shift1StartGr.TimeOfDay) + shift1EndGr = shift1EndGr.AddDays(1); + + var shiftSpan = (shift1EndGr - shift1StartGr); + if (restTime > TimeSpan.Zero && shiftSpan >= restTime) + { + shift1EndGr = shift1EndGr.Subtract(restTime); + shiftSpan = (shift1EndGr - shift1StartGr); + } + + if (!leaveSearchResult.Any(x => x.StartLeaveGr < shift1EndGr && x.EndLeaveGr > shift1StartGr && x.PaidLeaveType == "روزانه")) + { + var hourseLeaveTypeResult = leaveSearchResult.FirstOrDefault(x => + x.StartLeaveGr < shift1EndGr && x.EndLeaveGr > shift1StartGr && x.PaidLeaveType == "ساعتی"); + if (hourseLeaveTypeResult == null) + { + result.Add(new RollCallViewModel() + { + StartDate = shift1StartGr, + EndDate = shift1EndGr, + ShiftSpan = shiftSpan, + ShiftDate = shift1StartGr, + }); + } + else + { + + if (hourseLeaveTypeResult.StartLeaveGr <= shift1StartGr && hourseLeaveTypeResult.EndLeaveGr < shift1EndGr) + { + //leave <--------------------> + //shift <----------------------------------> + result.Add(new RollCallViewModel() + { + StartDate = hourseLeaveTypeResult.EndLeaveGr, + EndDate = shift1EndGr, + ShiftSpan = (shift1EndGr - hourseLeaveTypeResult.EndLeaveGr), + ShiftDate = shift1StartGr, + }); + } + else if (hourseLeaveTypeResult.StartLeaveGr > shift1StartGr && hourseLeaveTypeResult.EndLeaveGr < shift1EndGr) + { + //leave <--------------------> + //shift <----------------------------------> + result.Add(new RollCallViewModel() + { + StartDate = shift1StartGr, + EndDate = hourseLeaveTypeResult.StartLeaveGr, + ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift1StartGr), + ShiftDate = shift1StartGr, + }); + + result.Add(new RollCallViewModel() + { + StartDate = hourseLeaveTypeResult.EndLeaveGr, + EndDate = shift1EndGr, + ShiftSpan = (shift1EndGr - hourseLeaveTypeResult.EndLeaveGr), + ShiftDate = shift1StartGr, + }); + } + else if (hourseLeaveTypeResult.StartLeaveGr > shift1StartGr && hourseLeaveTypeResult.EndLeaveGr >= shift1EndGr) + { + //leave <--------------------> + //shift <----------------------------------> + + result.Add(new RollCallViewModel() + { + StartDate = shift1StartGr, + EndDate = hourseLeaveTypeResult.StartLeaveGr, + ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift1StartGr), + ShiftDate = shift1StartGr, + }); + + } + + + } + + } + + } + catch (Exception e) + { + // ignored + } + } + + #endregion + + #region Shift2 + + if (!string.IsNullOrWhiteSpace(shift2Start) && !string.IsNullOrWhiteSpace(shift2End)) + { + try + { + + + var startTimeTowSh1 = Convert.ToDateTime(shift2Start); + var endTimeTowSh2 = Convert.ToDateTime(shift2End); + + //اگر شیفت 1 وجود داشت تاریخ جاری را از شیف 1 میگیریم + //زیرا ممکن پایان شیف 1 در روز بعد باشد + var shift1 = result.MaxBy(x => x.EndDate); + if (shift1 != null) + if (shift1.EndDate != null) + cuurentDate = shift1.EndDate.Value; + + + shift2StartGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, startTimeTowSh1.Hour, startTimeTowSh1.Minute, 0); + shift2EndGr = new DateTime(cuurentDate.Year, cuurentDate.Month, cuurentDate.Day, endTimeTowSh2.Hour, endTimeTowSh2.Minute, 0); + + if (shift2EndGr.TimeOfDay < shift2StartGr.TimeOfDay) + shift2EndGr = shift2EndGr.AddDays(1); + + if (!leaveSearchResult.Any(x => x.StartLeaveGr < shift2EndGr && x.EndLeaveGr > shift2StartGr && x.PaidLeaveType == "روزانه")) + { + var hourseLeaveTypeResult = leaveSearchResult.FirstOrDefault(x => + x.StartLeaveGr < shift2EndGr && x.EndLeaveGr > shift2StartGr && x.PaidLeaveType == "ساعتی"); + if (hourseLeaveTypeResult == null) + { + + + result.Add(new RollCallViewModel() + { + StartDate = shift2StartGr, + EndDate = shift2EndGr, + ShiftSpan = (shift2EndGr - shift2StartGr), + ShiftDate = shift1?.ShiftDate ?? shift2EndGr, + }); + } + else + { + + if (hourseLeaveTypeResult.StartLeaveGr <= shift2StartGr && hourseLeaveTypeResult.EndLeaveGr < shift2EndGr) + { + //leave <--------------------> + //shift <----------------------------------> + result.Add(new RollCallViewModel() + { + StartDate = hourseLeaveTypeResult.EndLeaveGr, + EndDate = shift2EndGr, + ShiftSpan = (shift2EndGr - hourseLeaveTypeResult.EndLeaveGr), + ShiftDate = shift1?.EndDate ?? shift2EndGr, + }); + } + else if (hourseLeaveTypeResult.StartLeaveGr > shift2StartGr && hourseLeaveTypeResult.EndLeaveGr < shift2EndGr) + { + //leave <--------------------> + //shift <----------------------------------> + result.Add(new RollCallViewModel() + { + StartDate = shift2StartGr, + EndDate = hourseLeaveTypeResult.StartLeaveGr, + ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift2StartGr), + ShiftDate = shift1?.EndDate ?? shift2EndGr, + }); + + result.Add(new RollCallViewModel() + { + StartDate = hourseLeaveTypeResult.EndLeaveGr, + EndDate = shift2EndGr, + ShiftSpan = (shift2EndGr - hourseLeaveTypeResult.EndLeaveGr), + ShiftDate = shift1?.EndDate ?? shift2EndGr, + }); + } + else if (hourseLeaveTypeResult.StartLeaveGr > shift2StartGr && hourseLeaveTypeResult.EndLeaveGr >= shift2EndGr) + { + //leave <--------------------> + //shift <----------------------------------> + + result.Add(new RollCallViewModel() + { + StartDate = shift2StartGr, + EndDate = hourseLeaveTypeResult.StartLeaveGr, + ShiftSpan = (hourseLeaveTypeResult.StartLeaveGr - shift2StartGr), + ShiftDate = shift1?.EndDate ?? shift2EndGr, + }); + + } + + + } + + } + + } + catch (Exception e) + { + // ignored + } + } + + #endregion + + + return result; + + } + + + #endregion + + #region CustomizeCheckout + + /// + /// متد محاسبه فیش حقوقی دلخواه + /// + /// + /// + /// + /// + /// + public CustomizeCheckoutMandatoryViewModel CustomizeCheckoutMandatoryCompute(long employeeId, long workshopId, DateTime contractStart, + DateTime contractEnd) + { + var checkoutEnd = contractEnd; + var checkoutStart = contractStart; + if (workshopId == 170) + return CustomizeCheckoutMandatoryComputeForKebabMahdi(employeeId, workshopId, contractStart, contractEnd); + + var firstDayOfMonth = $"{(contractStart.ToFarsi())[..8]}/01".ToGeorgianDateTime(); + + #region LeftWork + + var leftWork = _leftWorkRepository.GetByWorkshopIdEmployeeIdInDates(workshopId, employeeId, contractStart, contractEnd); + + if (leftWork.StartWorkDateGr > contractStart) + { + contractStart = leftWork.StartWorkDateGr; + } + + if (leftWork.LeftWorkDateGr.AddDays(-1) < contractEnd) + { + contractEnd = leftWork.LeftWorkDateGr.AddDays(-1); + } + + TimeSpan leftWorkDurationTimeSpan = leftWork.HasLeft ? leftWork.LeftWorkDateGr.AddDays(-1) - leftWork.StartWorkDateGr : contractEnd - leftWork.StartWorkDateGr; + + + #endregion + + + #region Entities - TimeSpan contractDuration = contractEnd - contractStart; - var employee = _context.Employees.FirstOrDefault(x => x.id == employeeId); - var personnelCode = - _context.PersonnelCodeSet.FirstOrDefault(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId)?.PersonnelCode ?? 0; - var contract = _context.Contracts.Where(x => x.WorkshopIds == workshopId && x.EmployeeId == employeeId && - x.ContractEnd.Date >= contractStart.Date && - x.ContarctStart.Date <= contractEnd.Date).ToList()?.MaxBy(x => x.ContarctStart); - var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; - mandatoryDays = totalDays; - #endregion + int numberOfFridays = 0; + double monthySalary = 0; + int monthDays = 0; + double dailyWage = 0; + int numberOfWorkingDay = 0; + string endPersianDate = contractEnd.ToFarsi(); + int monthOfCheckout = Convert.ToInt32(endPersianDate.Substring(5, 2)); + int yearOfCheckout = Convert.ToInt32(endPersianDate.Substring(0, 4)); + //روز هایی که پرسنل موظف بوده کار کند + var mandatoryDays = 0; + TimeSpan contractDuration = contractEnd - contractStart; + var employee = _context.Employees.FirstOrDefault(x => x.id == employeeId); + var personnelCode = + _context.PersonnelCodeSet.FirstOrDefault(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId)?.PersonnelCode ?? 0; + var contract = _context.Contracts.Where(x => x.WorkshopIds == workshopId && x.EmployeeId == employeeId && + x.ContractEnd.Date >= contractStart.Date && + x.ContarctStart.Date <= contractEnd.Date).ToList()?.MaxBy(x => x.ContarctStart); + var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; + mandatoryDays = totalDays; + #endregion - #region CustomizeSettings - CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings = _context.CustomizeWorkshopEmployeeSettings.AsSplitQuery().FirstOrDefault(x => - x.WorkshopId == workshopId && x.EmployeeId == employeeId); - CustomizeWorkshopSettings customizeWorkshopSettings = - _context.CustomizeWorkshopSettings.FirstOrDefault(x => x.WorkshopId == workshopId); - //ToDo handel exception if is null - monthySalary = customizeWorkshopEmployeeSettings?.Salary ?? 0; - monthDays = customizeWorkshopSettings.MaxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth - ? 30 - : firstDayOfMonth.CountMonthDays(); + #region CustomizeSettings + CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings = _context.CustomizeWorkshopEmployeeSettings.AsSplitQuery().FirstOrDefault(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId); + CustomizeWorkshopSettings customizeWorkshopSettings = + _context.CustomizeWorkshopSettings.FirstOrDefault(x => x.WorkshopId == workshopId); + //ToDo handel exception if is null + monthySalary = customizeWorkshopEmployeeSettings?.Salary ?? 0; + monthDays = customizeWorkshopSettings.MaxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth + ? 30 + : firstDayOfMonth.CountMonthDays(); - var shiftSettings = customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts; - var employeeShiftsSpans = shiftSettings.Select(x => - { - var start = new DateTime(new DateOnly(), x.StartTime); - var end = new DateTime(new DateOnly(), x.EndTime); - if (x.EndTime < x.StartTime) - end = end.AddDays(1); - var span = end - start; - return new EmployeeShiftResult - { - Placement = x.Placement, - ShiftSpan = span - }; + var shiftSettings = customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts; - }); + var employeeShiftsSpans = shiftSettings.Select(x => + { + var start = new DateTime(new DateOnly(), x.StartTime); + var end = new DateTime(new DateOnly(), x.EndTime); + if (x.EndTime < x.StartTime) + end = end.AddDays(1); + var span = end - start; + return new EmployeeShiftResult + { + Placement = x.Placement, + ShiftSpan = span + }; - var sumOfEmployeeShiftSpan = new TimeSpan(employeeShiftsSpans.Sum(x => x.ShiftSpan.Ticks)); + }); - if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Irregular) - { - sumOfEmployeeShiftSpan = CalculateIrregularShift(customizeWorkshopEmployeeSettings.IrregularShift); - } + var sumOfEmployeeShiftSpan = new TimeSpan(employeeShiftsSpans.Sum(x => x.ShiftSpan.Ticks)); - if (customizeWorkshopEmployeeSettings.BreakTime.BreakTimeType == BreakTimeType.WithTime) - { - sumOfEmployeeShiftSpan -= customizeWorkshopEmployeeSettings.BreakTime.BreakTimeValue.ToTimeSpan(); - } - #endregion + if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Irregular) + { + sumOfEmployeeShiftSpan = CalculateIrregularShift(customizeWorkshopEmployeeSettings.IrregularShift); + } - List rollCallResult = _context.RollCalls.Where(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate.Value.Date >= contractStart.Date && - x.StartDate.Value.Date <= contractEnd.Date && x.EndDate != null) - .Select(x => new RollCallViewModel() - { - StartDate = x.StartDate, - EndDate = x.EndDate, - ShiftSpan = (x.EndDate.Value - x.StartDate.Value), - CreationDate = x.CreationDate, - BreakTimeSpan = x.BreakTimeSpan - }).ToList(); + if (customizeWorkshopEmployeeSettings.BreakTime.BreakTimeType == BreakTimeType.WithTime) + { + sumOfEmployeeShiftSpan -= customizeWorkshopEmployeeSettings.BreakTime.BreakTimeValue.ToTimeSpan(); + } + #endregion + List rollCallResult = _context.RollCalls.Where(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate.Value.Date >= contractStart.Date && + x.StartDate.Value.Date <= contractEnd.Date && x.EndDate != null) + .Select(x => new RollCallViewModel() + { + StartDate = x.StartDate, + EndDate = x.EndDate, + ShiftSpan = (x.EndDate.Value - x.StartDate.Value), + CreationDate = x.CreationDate, + BreakTimeSpan = x.BreakTimeSpan + }).ToList(); - List groupedRollCall = rollCallResult.GroupBy(x => x.StartDate!.Value.Date).Select(x => new GroupedRollCalls() - { - CreationDate = x.Key, - ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), - HasFriday = x.Any(s => s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value.DayOfWeek == DayOfWeek.Friday), - SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - CalculateBreakTime(x.First().BreakTimeSpan, - new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), + List groupedRollCall = rollCallResult.GroupBy(x => x.StartDate!.Value.Date).Select(x => new GroupedRollCalls() + { + CreationDate = x.Key, + ShiftList = x.Select(s => new ShiftList() { Start = s.StartDate!.Value, End = s.EndDate!.Value }).ToList(), + HasFriday = x.Any(s => s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value.DayOfWeek == DayOfWeek.Friday), - BreakTime = CalculateBreakTime(x.First().BreakTimeSpan, new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))) - }).ToList(); + SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - CalculateBreakTime(x.First().BreakTimeSpan, + new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), + BreakTime = CalculateBreakTime(x.First().BreakTimeSpan, new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))) + }).ToList(); - TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); - numberOfFridays = groupedRollCall.Count(x => x.HasFriday); + TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); - numberOfWorkingDay = groupedRollCall.Count(); - //تعداد روز های قرارداد - int contractDays = (int)contractDuration.TotalDays + 1; + numberOfFridays = groupedRollCall.Count(x => x.HasFriday); - //روز های غیبت + numberOfWorkingDay = groupedRollCall.Count(); + //تعداد روز های قرارداد + int contractDays = (int)contractDuration.TotalDays + 1; + //روز های غیبت - int fridays = 0; - int holiday = _context.HolidayItems.Count(x => x.Holidaydate >= contractStart && x.Holidaydate <= contractEnd); + int fridays = 0; + int holiday = _context.HolidayItems.Count(x => x.Holidaydate >= contractStart && x.Holidaydate <= contractEnd); - for (var gDate = contractStart; gDate <= contractEnd; gDate = gDate.AddDays(1)) - { - if (gDate.DayOfWeek == DayOfWeek.Friday) - { - fridays += 1; - } - } - if (customizeWorkshopEmployeeSettings.FridayWork == FridayWork.Default) - { - var fridayWorkingTotalDays = CalculateFridayWorkingTotalDays(rollCallResult); - fridays = fridays - fridayWorkingTotalDays; + for (var gDate = contractStart; gDate <= contractEnd; gDate = gDate.AddDays(1)) + { + if (gDate.DayOfWeek == DayOfWeek.Friday) + { + fridays += 1; + } + } - mandatoryDays -= fridays; + if (customizeWorkshopEmployeeSettings.FridayWork == FridayWork.Default) + { + var fridayWorkingTotalDays = CalculateFridayWorkingTotalDays(rollCallResult); + fridays = fridays - fridayWorkingTotalDays; - } + mandatoryDays -= fridays; - if (customizeWorkshopEmployeeSettings.HolidayWork == HolidayWork.Default) - { - var groupStartDaysDates = groupedRollCall.Select(x => x.CreationDate.Date).ToList(); - var holidayWorkingDays = _context.HolidayItems.Count(x => - groupStartDaysDates.Any(r => r == x.Holidaydate.Date)); - holiday = holiday - holidayWorkingDays; + } - mandatoryDays -= holiday; + if (customizeWorkshopEmployeeSettings.HolidayWork == HolidayWork.Default) + { + var groupStartDaysDates = groupedRollCall.Select(x => x.CreationDate.Date).ToList(); + var holidayWorkingDays = _context.HolidayItems.Count(x => + groupStartDaysDates.Any(r => r == x.Holidaydate.Date)); + holiday = holiday - holidayWorkingDays; - } - TimeSpan absentTimeSpans = new(); + mandatoryDays -= holiday; - if ((mandatoryDays * sumOfEmployeeShiftSpan) > sumSpans) - { - absentTimeSpans = (mandatoryDays * sumOfEmployeeShiftSpan) - sumSpans; - } + } + TimeSpan absentTimeSpans = new(); - dailyWage = monthySalary / monthDays; + if ((mandatoryDays * sumOfEmployeeShiftSpan) > sumSpans) + { + absentTimeSpans = (mandatoryDays * sumOfEmployeeShiftSpan) - sumSpans; + } - var minuteWage = sumOfEmployeeShiftSpan.TotalMinutes == 0 ? 0 : (dailyWage / sumOfEmployeeShiftSpan.TotalMinutes); + dailyWage = monthySalary / monthDays; + var minuteWage = sumOfEmployeeShiftSpan.TotalMinutes == 0 ? 0 : (dailyWage / sumOfEmployeeShiftSpan.TotalMinutes); - // یافتن مرخصی ساعتی - #region LeavHourse - LeaveSearchModel leaveHourseSearch = new LeaveSearchModel() - { - EmployeeId = employeeId, - WorkshopId = workshopId, - LeaveType = "استحقاقی", + // یافتن مرخصی ساعتی + #region LeavHourse - StartLeaveGr = contractStart, - EndLeaveGr = contractEnd, - IsAccepted = true, - }; - List leaveList = _leaveRepository.search(leaveHourseSearch); + LeaveSearchModel leaveHourseSearch = new LeaveSearchModel() + { + EmployeeId = employeeId, + WorkshopId = workshopId, + LeaveType = "استحقاقی", - #endregion + StartLeaveGr = contractStart, + EndLeaveGr = contractEnd, + IsAccepted = true, + }; + List leaveList = _leaveRepository.search(leaveHourseSearch); - //****افزودن مرخصی پرسنل به مجموع ساعات کار*** - #region AddEmployeeLeaves + #endregion - //TimeSpan workingPerDayAve = sumSpans / numberOfWorkingDay;//میانگین ساعت کار در روز + //****افزودن مرخصی پرسنل به مجموع ساعات کار*** + #region AddEmployeeLeaves + //TimeSpan workingPerDayAve = sumSpans / numberOfWorkingDay;//میانگین ساعت کار در روز - //if (workingPerDayAve <= new TimeSpan(7, 20, 0)) - //{ - // sumLeave = leavingDayCout * workingPerDayAve; - //} - //else - //{ - // sumLeave = leavingDayCout * new TimeSpan(7, 20, 0); - //} + //if (workingPerDayAve <= new TimeSpan(7, 20, 0)) + //{ + // sumLeave = leavingDayCout * workingPerDayAve; + //} + //else + //{ + // sumLeave = leavingDayCout * new TimeSpan(7, 20, 0); + //} - double leavePayAmount = 0; - double absentsDeductionAmount = 0; - if (customizeWorkshopEmployeeSettings.LeavePay.LeavePayType != LeavePayType.None) - { - int permittedDays = customizeWorkshopEmployeeSettings.LeavePermittedDays; - double leaveValue = customizeWorkshopEmployeeSettings.LeavePay.Value; - sumSpans = CalculateLeavePay(sumOfEmployeeShiftSpan, absentTimeSpans, permittedDays, monthDays, contractDays, sumSpans - , leaveValue, minuteWage, contractStart, contractEnd, out leavePayAmount, out absentsDeductionAmount); - } - else - { - absentsDeductionAmount = absentTimeSpans.TotalMinutes * minuteWage; - } + double leavePayAmount = 0; + double absentsDeductionAmount = 0; + if (customizeWorkshopEmployeeSettings.LeavePay.LeavePayType != LeavePayType.None) + { + int permittedDays = customizeWorkshopEmployeeSettings.LeavePermittedDays; + double leaveValue = customizeWorkshopEmployeeSettings.LeavePay.Value; + sumSpans = CalculateLeavePay(sumOfEmployeeShiftSpan, absentTimeSpans, permittedDays, monthDays, contractDays, sumSpans + , leaveValue, minuteWage, contractStart, contractEnd, out leavePayAmount, out absentsDeductionAmount); + } + else + { + absentsDeductionAmount = absentTimeSpans.TotalMinutes * minuteWage; + } - Console.WriteLine(sumSpans); - #endregion - //***********************************// - //ToTal Hours Employee Worked - double totalHours = (sumSpans.TotalMinutes) / 60; - int totalHolidaysAndNotH = (int)sumSpans.TotalHours; - int totalHolidaysAndNotM = (int)(sumSpans.TotalMinutes % 60); - //***********************************// + Console.WriteLine(sumSpans); + #endregion + //***********************************// + //ToTal Hours Employee Worked + double totalHours = (sumSpans.TotalMinutes) / 60; + int totalHolidaysAndNotH = (int)sumSpans.TotalHours; + int totalHolidaysAndNotM = (int)(sumSpans.TotalMinutes % 60); + //***********************************// - #region Deductions - //غیبت + #region Deductions - //تاخیر و تعجیل + //غیبت + //تاخیر و تعجیل - //حق بیمه - #region InsurancePay - InsuranceDeduction insuranceDeduction = customizeWorkshopEmployeeSettings.InsuranceDeduction; - //farokhiChange - double insuranceDeductionAmount = InsurancePayCalculation(employeeId, contractStart, contractEnd, insuranceDeduction, monthySalary); - #endregion - #region SalaryAidDeduction + //حق بیمه + #region InsurancePay - var salaryAidViewModel = SalaryAidsForCheckout(employeeId, workshopId, checkoutStart, checkoutEnd); - double salaryAidDeduction = salaryAidViewModel.Sum(x => x.AmountDouble); + InsuranceDeduction insuranceDeduction = customizeWorkshopEmployeeSettings.InsuranceDeduction; + //farokhiChange + double insuranceDeductionAmount = InsurancePayCalculation(employeeId, contractStart, contractEnd, insuranceDeduction, monthySalary); + #endregion + #region SalaryAidDeduction - #endregion + var salaryAidViewModel = SalaryAidsForCheckout(employeeId, workshopId, checkoutStart, checkoutEnd); + double salaryAidDeduction = salaryAidViewModel.Sum(x => x.AmountDouble); - #region Loan + #endregion - var loanInstallments = LoanInstallmentForCheckout(employeeId, workshopId, contractStart, contractEnd); + #region Loan - double loanDeduction = loanInstallments.Sum(x => x.AmountDouble); + var loanInstallments = LoanInstallmentForCheckout(employeeId, workshopId, contractStart, contractEnd); - #endregion + double loanDeduction = loanInstallments.Sum(x => x.AmountDouble); - #region Fine + #endregion - var fineViewModels = FinesForCheckout(employeeId, workshopId, contractStart, contractEnd); - double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble()); + #region Fine - #endregion + var fineViewModels = FinesForCheckout(employeeId, workshopId, contractStart, contractEnd); + double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble()); + #endregion - #endregion + #endregion - #region Payments - //اضافه کاری - #region OvertimePay - double overtimePayAmount = 0; + #region Payments + //اضافه کاری + #region OvertimePay + double overtimePayAmount = 0; - TimeSpan overtimeTimeSpan; - if (customizeWorkshopSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular && customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) - { - TimeOnly employeeOffSet = customizeWorkshopSettings.EndTimeOffSet; - overtimeTimeSpan = CalculateOvertimeTimeSpan(rollCallResult, shiftSettings, employeeOffSet); - } - else if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) - { - var date = new DateOnly(); - var firstStartShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MinBy(x => x.Placement).StartTime); - var lastEndShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MaxBy(x => x.Placement).EndTime); - if (lastEndShift > firstStartShift) - firstStartShift = firstStartShift.AddDays(1); - var offSet = (firstStartShift - lastEndShift).Divide(2); - var employeeOffSet = TimeOnly.FromDateTime(lastEndShift.Add(offSet)); + TimeSpan overtimeTimeSpan; - overtimeTimeSpan = CalculateOvertimeTimeSpan(rollCallResult, shiftSettings, employeeOffSet); - } - else - { - var irregularShifts = customizeWorkshopEmployeeSettings.IrregularShift.WorkshopIrregularShifts; - overtimeTimeSpan = CalculateIrregularOverTime(rollCallResult, sumOfEmployeeShiftSpan, irregularShifts, mandatoryDays); - //Todo: fix for irregular and rotating shifts - } - overtimePayAmount = CalculateOvertimePay(overtimeTimeSpan, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage); - if (overtimePayAmount >= absentsDeductionAmount) - { - overtimePayAmount = overtimePayAmount - absentsDeductionAmount; - absentsDeductionAmount = 0; - } - else - { - absentsDeductionAmount = absentsDeductionAmount - overtimePayAmount; - overtimePayAmount = 0; - } - #endregion + if (customizeWorkshopSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular && customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) + { + TimeOnly employeeOffSet = customizeWorkshopSettings.EndTimeOffSet; + overtimeTimeSpan = CalculateOvertimeTimeSpan(rollCallResult, shiftSettings, employeeOffSet); + } + else if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) + { + var date = new DateOnly(); + var firstStartShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MinBy(x => x.Placement).StartTime); + var lastEndShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MaxBy(x => x.Placement).EndTime); + if (lastEndShift > firstStartShift) + firstStartShift = firstStartShift.AddDays(1); + var offSet = (firstStartShift - lastEndShift).Divide(2); + var employeeOffSet = TimeOnly.FromDateTime(lastEndShift.Add(offSet)); - #region FridayPay - double fridayPayAmount = 0; + overtimeTimeSpan = CalculateOvertimeTimeSpan(rollCallResult, shiftSettings, employeeOffSet); + } + else + { + var irregularShifts = customizeWorkshopEmployeeSettings.IrregularShift.WorkshopIrregularShifts; + overtimeTimeSpan = CalculateIrregularOverTime(rollCallResult, sumOfEmployeeShiftSpan, irregularShifts, mandatoryDays); + //Todo: fix for irregular and rotating shifts + } + overtimePayAmount = CalculateOvertimePay(overtimeTimeSpan, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage); + if (overtimePayAmount >= absentsDeductionAmount) + { + overtimePayAmount = overtimePayAmount - absentsDeductionAmount; + absentsDeductionAmount = 0; + } + else + { + absentsDeductionAmount = absentsDeductionAmount - overtimePayAmount; + overtimePayAmount = 0; + } + #endregion - fridayPayAmount = FridayPayCalculation(customizeWorkshopEmployeeSettings, rollCallResult, dailyWage, shiftSettings, overtimePayAmount); + #region FridayPay + double fridayPayAmount = 0; + fridayPayAmount = FridayPayCalculation(customizeWorkshopEmployeeSettings, rollCallResult, dailyWage, shiftSettings, overtimePayAmount); - #endregion - //حق تاهل - #region MaritalAllownace - double maritalAllowancePay = 0; - if (employee.MaritalStatus == "متاهل") - { - switch (customizeWorkshopEmployeeSettings.MarriedAllowance.MarriedAllowanceType) - { - case MarriedAllowanceType.Money: - { - maritalAllowancePay = customizeWorkshopEmployeeSettings.MarriedAllowance.Value; - break; - } - //case MarriedAllowanceType.PercentageFromSalary: - - // { - // double multiplier = customizeWorkshopEmployeeSettings.MarriedAllowance.Value / 100; - // maritalAllowance = dailyWage * multiplier; - // break; - // } - } - } - #endregion - - //شب کاری - #region NightWorkPay - double nightworkPayAmount = 0; - List rotatingResultList = RotatingShiftCheck(groupedRollCall); - - // شبکاری - TimeSpan nightWorks = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); - - if (nightWorks > new TimeSpan()) - { - switch (customizeWorkshopEmployeeSettings.NightWorkPay.NightWorkingType) - { - case NightWorkType.MoneyPerHour: - { - var baseAmount = customizeWorkshopEmployeeSettings.NightWorkPay.Value; - var nightWorkMinutes = (int)(nightWorks).TotalMinutes; - nightworkPayAmount += nightWorkMinutes * (baseAmount / 60); - break; - } - case NightWorkType.PercentageFromSalary: - { - double multiplier = customizeWorkshopEmployeeSettings.NightWorkPay.Value / 100; - var nightWorkMinutes = (int)(nightWorks).TotalMinutes; - nightworkPayAmount += ((dailyWage * multiplier) / 60) * nightWorkMinutes; - break; - } - - - } - } - #endregion - - //سنوات - #region BaseYearsPay - double baseYearsPayAmount = CalculateYearsPayAmount(employeeId, workshopId, monthySalary, contractStart, contractEnd - , customizeWorkshopEmployeeSettings.BaseYearsPay, customizeWorkshopSettings.BaseYearsPayInEndOfYear, customizeWorkshopSettings.MaxMonthDays); - - #endregion - //حق اولاد - - #region FamilyAllowancePay - double familyAllowancePay = 0; - switch (customizeWorkshopEmployeeSettings.FamilyAllowance.FamilyAllowanceType) - { - case FamilyAllowanceType.Money: - { - double baseAmount = customizeWorkshopEmployeeSettings.FamilyAllowance.Value; - familyAllowancePay = CalculateFamilyAllowancePayAmount(employeeId, baseAmount, contractEnd); - break; - } - - case FamilyAllowanceType.Percentage: - { - double multiplier = customizeWorkshopEmployeeSettings.FamilyAllowance.Value / 100; - familyAllowancePay = CalculateFamilyAllowancePayAmount(employeeId, multiplier * monthySalary, contractEnd); - break; - } - } - #endregion - #region Reward - - var rewardViewModels = RewardForCheckout(employeeId, workshopId, checkoutEnd, checkoutStart); - - double rewardPay = rewardViewModels.Sum(x => x.AmountDouble); - #endregion - - #region LeavePay - - - - #endregion - - #region BonusesPay - - double bonusesPayAmount = 0; - - - if (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType != BonusesType.None) - { - switch (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType) - { - case BonusesType.OneTimeOfSalary: - bonusesPayAmount = monthySalary; - break; - case BonusesType.TwoTimeOfSalary: - bonusesPayAmount = monthySalary * 2; - break; - case BonusesType.Money: - bonusesPayAmount = customizeWorkshopEmployeeSettings.BonusesPay.Value; - break; - case BonusesType.PercentageOfSalary: - bonusesPayAmount = (monthySalary * customizeWorkshopEmployeeSettings.BonusesPay.Value) / 100; - break; - } - double bonusesPerMonth = bonusesPayAmount / 12; - - if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.YearlyPay) - { - var contractEndFarsi = Tools.FindeEndOfMonth(contractEnd.ToFarsi()); - if (monthOfCheckout == 12 && (contractEndFarsi.EndsWith("29")) || contractEndFarsi.EndsWith("30")) - { - } - else if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft) - { - TimeSpan bonusDuration; - DateTime startOfYear = new PersianCalendar().ToDateTime(yearOfCheckout, 1, 1, 0, 0, 0, 0); - if (startOfYear < leftWork.StartWorkDateGr) - bonusDuration = leftWorkDurationTimeSpan; - else - bonusDuration = leftWork.LeftWorkDateGr - startOfYear; - //ToDo: Check if should be absolute 365! - bonusesPayAmount = (bonusesPayAmount / 365) * bonusDuration.TotalDays; - } - else - { - bonusesPayAmount = 0; - } - } - else if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.MonthlyPay) - { - - - if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == - BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft && contractDays < monthDays) - bonusesPayAmount = (bonusesPerMonth / contractEnd.CountPersianMonthDays()) * contractDuration.TotalDays + 1; - - - bonusesPayAmount = bonusesPerMonth; - } - else - { - throw new InvalidDataException(); - } - } - - #endregion - - - #endregion - - #region LateToWork & EarlyExit - - var lateToWorkEarlyExit = LateToWorkEarlyExit(groupedRollCall, shiftSettings, leaveList); - foreach (var i in lateToWorkEarlyExit) - { - Console.WriteLine(" start : " + i.StartSpan + " end : " + i.EndSpan + " spaning : " + i.Spanning + " Type : " + i.TypeOfSapn); - } - - var lateToWoks = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "LateToWork"); - var earlyExits = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "EarlyExist"); - - var lateToWork = new TimeSpan(lateToWoks.Sum(x => x.Spanning.Ticks)); - var earlyExist = new TimeSpan(earlyExits.Sum(x => x.Spanning.Ticks)); - var totalSpaning = new TimeSpan(lateToWorkEarlyExit.Sum(x => x.Spanning.Ticks)); - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(" LateToWork H : " + (int)lateToWork.TotalHours + " M : " + (int)(lateToWork.TotalMinutes % 60)); - Console.WriteLine(" EarlyExist H : " + (int)earlyExist.TotalHours + " M : " + (int)(earlyExist.TotalMinutes % 60)); - Console.WriteLine(" TotalSpaning H : " + (int)totalSpaning.TotalHours + " M : " + (int)(totalSpaning.TotalMinutes % 60)); - Console.ResetColor(); - - double earlyExitDeduction = 0; - double lateToWorkDeduction = 0; - - ////محاسبه مزد روزانه به ازای هر دقیقه - //double dailyWagePerMinute = - // (customizeWorkshopEmployeeSettings.Salary / monthDays) / sumOfEmployeeShiftSpan.TotalMinutes; - - if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType != EarlyExitType.None && earlyExist > new TimeSpan()) - { - earlyExitDeduction = customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType switch - { - EarlyExitType.Default => earlyExist.TotalMinutes * minuteWage, - - EarlyExitType.MoneyPerMinute => earlyExist.TotalMinutes * customizeWorkshopEmployeeSettings.EarlyExit.Value, - - _ => 0 - }; - - } - - - if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType != LateToWorkType.None && lateToWork > new TimeSpan()) - { - lateToWorkDeduction = customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType switch - { - LateToWorkType.Default => lateToWork.TotalMinutes * minuteWage, - - LateToWorkType.MoneyPerMinute => lateToWork.TotalMinutes * customizeWorkshopEmployeeSettings.LateToWork.Value, - - _ => 0 - }; - - } - - if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines.Any()) - { - lateToWorkDeduction += - (from lateToWorkTimeFine in customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines - let stepFine = lateToWoks.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(lateToWorkTimeFine.Minute)) - select stepFine * lateToWorkTimeFine.FineMoney).Sum(); - } - if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines.Any()) - { - earlyExitDeduction += - (from earlyExitFine in customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines - let stepFine = earlyExits.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(earlyExitFine.Minute)) - select stepFine * earlyExitFine.FineMoney).Sum(); - } - - - - #endregion - - return new CustomizeCheckoutMandatoryViewModel - { - InsuranceDeduction = insuranceDeductionAmount, - FridayPay = fridayPayAmount, - OverTimePay = overtimePayAmount, - BaseYearsPay = baseYearsPayAmount, - NightWorkPay = nightworkPayAmount, - MarriedAllowance = maritalAllowancePay, - FamilyAllowance = familyAllowancePay, - LeavePay = leavePayAmount, - FineAbsenceDeduction = absentsDeductionAmount, - BonusesPay = bonusesPayAmount, - ContractEndFa = contractEnd.ToFarsi(), - ContractStartFa = contractStart.ToFarsi(), - EmployeeName = employee.FullName, - InstallmentDeduction = loanDeduction, - SalaryAidDeduction = salaryAidDeduction, - FineDeduction = fineDeduction, - RewardPay = rewardPay, - Month = monthOfCheckout, - Year = yearOfCheckout, - LateToWorkDeduction = lateToWorkDeduction, - EarlyExitDeduction = earlyExitDeduction, - ShiftPay = 0, - TaxDeduction = 0, - EmployeeId = employeeId, - SumOfWorkingDays = totalDays.ToString(), - ContractNo = contract?.ContractNo ?? "-", - MonthlySalary = dailyWage * mandatoryDays, - PersonnelCode = personnelCode, - FineViewModels = fineViewModels, - InstallmentViewModels = loanInstallments, - SalaryAidViewModels = salaryAidViewModel, - RewardViewModels = rewardViewModels - }; - } - - - - public CustomizeCheckoutMandatoryViewModel CustomizeCheckoutMandatoryComputeForKebabMahdi(long employeeId, - long workshopId, - DateTime contractStart, DateTime contractEnd) - { - var checkoutEnd = contractEnd; - var checkoutStart = contractStart; - - var exceptionEmployees = _context.CustomizeWorkshopGroupSettings.Where(x => x.id == 117) - .Include(x => x.CustomizeWorkshopEmployeeSettingsCollection).AsSplitQuery().FirstOrDefault()?.CustomizeWorkshopEmployeeSettingsCollection.Select(x => x.EmployeeId).ToList() ?? []; - - if (exceptionEmployees.Contains(employeeId)) - { - return CheckoutWithoutCalculationForKebabMahdi(workshopId, employeeId, contractStart, contractEnd); - } - - var firstDayOfMonth = $"{(contractStart.ToFarsi())[..8]}/01".ToGeorgianDateTime(); - - #region LeftWork - - var leftWork = - _leftWorkRepository.GetByWorkshopIdEmployeeIdInDates(workshopId, employeeId, contractStart, contractEnd); - - if (leftWork.StartWorkDateGr > contractStart) - { - contractStart = leftWork.StartWorkDateGr; - } - - if (leftWork.LeftWorkDateGr.AddDays(-1) < contractEnd) - { - contractEnd = leftWork.LeftWorkDateGr.AddDays(-1); - } - - TimeSpan leftWorkDurationTimeSpan = leftWork.HasLeft - ? leftWork.LeftWorkDateGr.AddDays(-1) - leftWork.StartWorkDateGr - : contractEnd - leftWork.StartWorkDateGr; - - - #endregion - - - #region Entities - - int numberOfFridays = 0; - double monthySalary = 0; - int monthDays = 0; - double dailyWage = 0; - int numberOfWorkingDay = 0; - string endPersianDate = contractEnd.ToFarsi(); - int monthOfCheckout = Convert.ToInt32(endPersianDate.Substring(5, 2)); - int yearOfCheckout = Convert.ToInt32(endPersianDate.Substring(0, 4)); - //روز هایی که پرسنل موظف بوده کار کند - var mandatoryDays = 0; - - TimeSpan contractDuration = contractEnd - contractStart; - var employee = _context.Employees.FirstOrDefault(x => x.id == employeeId); - var personnelCode = - _context.PersonnelCodeSet.FirstOrDefault(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId) - ?.PersonnelCode ?? 0; - var contract = _context.Contracts.Where(x => x.WorkshopIds == workshopId && x.EmployeeId == employeeId && - x.ContractEnd.Date >= contractStart.Date && - x.ContarctStart.Date <= contractEnd.Date).ToList() - ?.MaxBy(x => x.ContarctStart); - var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; - mandatoryDays = totalDays; - - - #endregion - - - - #region CustomizeSettings - - CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings = _context.CustomizeWorkshopEmployeeSettings - .AsSplitQuery().AsNoTracking().FirstOrDefault(x => - x.WorkshopId == workshopId && x.EmployeeId == employeeId); - CustomizeWorkshopSettings customizeWorkshopSettings = - _context.CustomizeWorkshopSettings.AsNoTracking().FirstOrDefault(x => x.WorkshopId == workshopId); - //ToDo handel exception if is null - monthySalary = customizeWorkshopEmployeeSettings?.Salary ?? 0; - monthDays = customizeWorkshopSettings.MaxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth - ? 30 - : firstDayOfMonth.CountMonthDays(); - - - var shiftSettings = customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts; - - var employeeShiftsSpans = shiftSettings.Select(x => - { - var start = new DateTime(new DateOnly(), x.StartTime); - var end = new DateTime(new DateOnly(), x.EndTime); - if (x.EndTime < x.StartTime) - end = end.AddDays(1); - var span = end - start; - return new EmployeeShiftResult - { - Placement = x.Placement, - ShiftSpan = span - }; + #endregion - }); - - - #endregion + //حق تاهل + #region MaritalAllownace + double maritalAllowancePay = 0; + if (employee.MaritalStatus == "متاهل") + { + switch (customizeWorkshopEmployeeSettings.MarriedAllowance.MarriedAllowanceType) + { + case MarriedAllowanceType.Money: + { + maritalAllowancePay = customizeWorkshopEmployeeSettings.MarriedAllowance.Value; + break; + } + //case MarriedAllowanceType.PercentageFromSalary: + + // { + // double multiplier = customizeWorkshopEmployeeSettings.MarriedAllowance.Value / 100; + // maritalAllowance = dailyWage * multiplier; + // break; + // } + } + } + #endregion + + //شب کاری + #region NightWorkPay + double nightworkPayAmount = 0; + List rotatingResultList = RotatingShiftCheck(groupedRollCall); + + // شبکاری + TimeSpan nightWorks = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); + + if (nightWorks > new TimeSpan()) + { + switch (customizeWorkshopEmployeeSettings.NightWorkPay.NightWorkingType) + { + case NightWorkType.MoneyPerHour: + { + var baseAmount = customizeWorkshopEmployeeSettings.NightWorkPay.Value; + var nightWorkMinutes = (int)(nightWorks).TotalMinutes; + nightworkPayAmount += nightWorkMinutes * (baseAmount / 60); + break; + } + case NightWorkType.PercentageFromSalary: + { + double multiplier = customizeWorkshopEmployeeSettings.NightWorkPay.Value / 100; + var nightWorkMinutes = (int)(nightWorks).TotalMinutes; + nightworkPayAmount += ((dailyWage * multiplier) / 60) * nightWorkMinutes; + break; + } + + + } + } + #endregion + + //سنوات + #region BaseYearsPay + double baseYearsPayAmount = CalculateYearsPayAmount(employeeId, workshopId, monthySalary, contractStart, contractEnd + , customizeWorkshopEmployeeSettings.BaseYearsPay, customizeWorkshopSettings.BaseYearsPayInEndOfYear, customizeWorkshopSettings.MaxMonthDays); + + #endregion + //حق اولاد + + #region FamilyAllowancePay + double familyAllowancePay = 0; + switch (customizeWorkshopEmployeeSettings.FamilyAllowance.FamilyAllowanceType) + { + case FamilyAllowanceType.Money: + { + double baseAmount = customizeWorkshopEmployeeSettings.FamilyAllowance.Value; + familyAllowancePay = CalculateFamilyAllowancePayAmount(employeeId, baseAmount, contractEnd); + break; + } + + case FamilyAllowanceType.Percentage: + { + double multiplier = customizeWorkshopEmployeeSettings.FamilyAllowance.Value / 100; + familyAllowancePay = CalculateFamilyAllowancePayAmount(employeeId, multiplier * monthySalary, contractEnd); + break; + } + } + #endregion + #region Reward + + var rewardViewModels = RewardForCheckout(employeeId, workshopId, checkoutEnd, checkoutStart); + + double rewardPay = rewardViewModels.Sum(x => x.AmountDouble); + #endregion + + #region LeavePay + + + + #endregion + + #region BonusesPay + + double bonusesPayAmount = 0; + + + if (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType != BonusesType.None) + { + switch (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType) + { + case BonusesType.OneTimeOfSalary: + bonusesPayAmount = monthySalary; + break; + case BonusesType.TwoTimeOfSalary: + bonusesPayAmount = monthySalary * 2; + break; + case BonusesType.Money: + bonusesPayAmount = customizeWorkshopEmployeeSettings.BonusesPay.Value; + break; + case BonusesType.PercentageOfSalary: + bonusesPayAmount = (monthySalary * customizeWorkshopEmployeeSettings.BonusesPay.Value) / 100; + break; + } + double bonusesPerMonth = bonusesPayAmount / 12; + + if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.YearlyPay) + { + var contractEndFarsi = Tools.FindeEndOfMonth(contractEnd.ToFarsi()); + if (monthOfCheckout == 12 && (contractEndFarsi.EndsWith("29")) || contractEndFarsi.EndsWith("30")) + { + } + else if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft) + { + TimeSpan bonusDuration; + DateTime startOfYear = new PersianCalendar().ToDateTime(yearOfCheckout, 1, 1, 0, 0, 0, 0); + if (startOfYear < leftWork.StartWorkDateGr) + bonusDuration = leftWorkDurationTimeSpan; + else + bonusDuration = leftWork.LeftWorkDateGr - startOfYear; + //ToDo: Check if should be absolute 365! + bonusesPayAmount = (bonusesPayAmount / 365) * bonusDuration.TotalDays; + } + else + { + bonusesPayAmount = 0; + } + } + else if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.MonthlyPay) + { + + + if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == + BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft && contractDays < monthDays) + bonusesPayAmount = (bonusesPerMonth / contractEnd.CountPersianMonthDays()) * contractDuration.TotalDays + 1; + + + bonusesPayAmount = bonusesPerMonth; + } + else + { + throw new InvalidDataException(); + } + } + + #endregion + + + #endregion + + #region LateToWork & EarlyExit + + var lateToWorkEarlyExit = LateToWorkEarlyExit(groupedRollCall, shiftSettings, leaveList); + foreach (var i in lateToWorkEarlyExit) + { + Console.WriteLine(" start : " + i.StartSpan + " end : " + i.EndSpan + " spaning : " + i.Spanning + " Type : " + i.TypeOfSapn); + } + + var lateToWoks = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "LateToWork"); + var earlyExits = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "EarlyExist"); + + var lateToWork = new TimeSpan(lateToWoks.Sum(x => x.Spanning.Ticks)); + var earlyExist = new TimeSpan(earlyExits.Sum(x => x.Spanning.Ticks)); + var totalSpaning = new TimeSpan(lateToWorkEarlyExit.Sum(x => x.Spanning.Ticks)); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(" LateToWork H : " + (int)lateToWork.TotalHours + " M : " + (int)(lateToWork.TotalMinutes % 60)); + Console.WriteLine(" EarlyExist H : " + (int)earlyExist.TotalHours + " M : " + (int)(earlyExist.TotalMinutes % 60)); + Console.WriteLine(" TotalSpaning H : " + (int)totalSpaning.TotalHours + " M : " + (int)(totalSpaning.TotalMinutes % 60)); + Console.ResetColor(); + + double earlyExitDeduction = 0; + double lateToWorkDeduction = 0; + + ////محاسبه مزد روزانه به ازای هر دقیقه + //double dailyWagePerMinute = + // (customizeWorkshopEmployeeSettings.Salary / monthDays) / sumOfEmployeeShiftSpan.TotalMinutes; + + if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType != EarlyExitType.None && earlyExist > new TimeSpan()) + { + earlyExitDeduction = customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType switch + { + EarlyExitType.Default => earlyExist.TotalMinutes * minuteWage, + + EarlyExitType.MoneyPerMinute => earlyExist.TotalMinutes * customizeWorkshopEmployeeSettings.EarlyExit.Value, + + _ => 0 + }; + + } + + + if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType != LateToWorkType.None && lateToWork > new TimeSpan()) + { + lateToWorkDeduction = customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType switch + { + LateToWorkType.Default => lateToWork.TotalMinutes * minuteWage, + + LateToWorkType.MoneyPerMinute => lateToWork.TotalMinutes * customizeWorkshopEmployeeSettings.LateToWork.Value, + + _ => 0 + }; + + } + + if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines.Any()) + { + lateToWorkDeduction += + (from lateToWorkTimeFine in customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines + let stepFine = lateToWoks.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(lateToWorkTimeFine.Minute)) + select stepFine * lateToWorkTimeFine.FineMoney).Sum(); + } + if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines.Any()) + { + earlyExitDeduction += + (from earlyExitFine in customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines + let stepFine = earlyExits.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(earlyExitFine.Minute)) + select stepFine * earlyExitFine.FineMoney).Sum(); + } + + + + #endregion + + return new CustomizeCheckoutMandatoryViewModel + { + InsuranceDeduction = insuranceDeductionAmount, + FridayPay = fridayPayAmount, + OverTimePay = overtimePayAmount, + BaseYearsPay = baseYearsPayAmount, + NightWorkPay = nightworkPayAmount, + MarriedAllowance = maritalAllowancePay, + FamilyAllowance = familyAllowancePay, + LeavePay = leavePayAmount, + FineAbsenceDeduction = absentsDeductionAmount, + BonusesPay = bonusesPayAmount, + ContractEndFa = contractEnd.ToFarsi(), + ContractStartFa = contractStart.ToFarsi(), + EmployeeName = employee.FullName, + InstallmentDeduction = loanDeduction, + SalaryAidDeduction = salaryAidDeduction, + FineDeduction = fineDeduction, + RewardPay = rewardPay, + Month = monthOfCheckout, + Year = yearOfCheckout, + LateToWorkDeduction = lateToWorkDeduction, + EarlyExitDeduction = earlyExitDeduction, + ShiftPay = 0, + TaxDeduction = 0, + EmployeeId = employeeId, + SumOfWorkingDays = totalDays.ToString(), + ContractNo = contract?.ContractNo ?? "-", + MonthlySalary = dailyWage * mandatoryDays, + PersonnelCode = personnelCode, + FineViewModels = fineViewModels, + InstallmentViewModels = loanInstallments, + SalaryAidViewModels = salaryAidViewModel, + RewardViewModels = rewardViewModels + }; + } + + + + public CustomizeCheckoutMandatoryViewModel CustomizeCheckoutMandatoryComputeForKebabMahdi(long employeeId, + long workshopId, + DateTime contractStart, DateTime contractEnd) + { + var checkoutEnd = contractEnd; + var checkoutStart = contractStart; + + var exceptionEmployees = _context.CustomizeWorkshopGroupSettings.Where(x => x.id == 117) + .Include(x => x.CustomizeWorkshopEmployeeSettingsCollection).AsSplitQuery().FirstOrDefault()?.CustomizeWorkshopEmployeeSettingsCollection.Select(x => x.EmployeeId).ToList() ?? []; + + if (exceptionEmployees.Contains(employeeId)) + { + return CheckoutWithoutCalculationForKebabMahdi(workshopId, employeeId, contractStart, contractEnd); + } + + var firstDayOfMonth = $"{(contractStart.ToFarsi())[..8]}/01".ToGeorgianDateTime(); + + #region LeftWork + + var leftWork = + _leftWorkRepository.GetByWorkshopIdEmployeeIdInDates(workshopId, employeeId, contractStart, contractEnd); + + if (leftWork.StartWorkDateGr > contractStart) + { + contractStart = leftWork.StartWorkDateGr; + } + + if (leftWork.LeftWorkDateGr.AddDays(-1) < contractEnd) + { + contractEnd = leftWork.LeftWorkDateGr.AddDays(-1); + } + + TimeSpan leftWorkDurationTimeSpan = leftWork.HasLeft + ? leftWork.LeftWorkDateGr.AddDays(-1) - leftWork.StartWorkDateGr + : contractEnd - leftWork.StartWorkDateGr; + + + #endregion + + + #region Entities + + int numberOfFridays = 0; + double monthySalary = 0; + int monthDays = 0; + double dailyWage = 0; + int numberOfWorkingDay = 0; + string endPersianDate = contractEnd.ToFarsi(); + int monthOfCheckout = Convert.ToInt32(endPersianDate.Substring(5, 2)); + int yearOfCheckout = Convert.ToInt32(endPersianDate.Substring(0, 4)); + //روز هایی که پرسنل موظف بوده کار کند + var mandatoryDays = 0; + + TimeSpan contractDuration = contractEnd - contractStart; + var employee = _context.Employees.FirstOrDefault(x => x.id == employeeId); + var personnelCode = + _context.PersonnelCodeSet.FirstOrDefault(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId) + ?.PersonnelCode ?? 0; + var contract = _context.Contracts.Where(x => x.WorkshopIds == workshopId && x.EmployeeId == employeeId && + x.ContractEnd.Date >= contractStart.Date && + x.ContarctStart.Date <= contractEnd.Date).ToList() + ?.MaxBy(x => x.ContarctStart); + var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; + mandatoryDays = totalDays; + + + #endregion + + + + #region CustomizeSettings + + CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings; + CustomizeWorkshopSettings customizeWorkshopSettings; + + + var endFarvarding = new DateTime(2025, 4, 20); + if (contractStart>endFarvarding) + { + customizeWorkshopEmployeeSettings=_context.CustomizeWorkshopEmployeeSettings + .AsSplitQuery().AsNoTracking().FirstOrDefault(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId); + + customizeWorkshopSettings =_context.CustomizeWorkshopSettings.AsNoTracking().FirstOrDefault(x => x.WorkshopId == workshopId); + } + + else + { + customizeWorkshopEmployeeSettings = _testDbContext.CustomizeWorkshopEmployeeSettings + .AsSplitQuery().AsNoTracking().FirstOrDefault(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId); - List rollCallResult = _context.RollCalls.AsNoTracking().Where(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.ShiftDate.Date >= contractStart.Date && - x.ShiftDate.Date <= contractEnd.Date && x.EndDate != null) - .Select(x => new RollCallViewModel() - { - StartDate = x.StartDate, - EndDate = x.EndDate, - ShiftSpan = (x.EndDate.Value - x.StartDate.Value), - CreationDate = x.CreationDate, - ShiftDate = x.ShiftDate, - EarlyEntryDuration = x.EarlyEntryDuration, - LateEntryDuration = x.LateEntryDuration, - EarlyExitDuration = x.EarlyExitDuration, - LateExitDuration = x.LateExitDuration, - ShiftDurationTimeSpan = x.ShiftDurationTimeSpan, - BreakTimeSpan = x.BreakTimeSpan - - }).ToList(); + customizeWorkshopSettings = _testDbContext.CustomizeWorkshopSettings.AsNoTracking().FirstOrDefault(x => x.WorkshopId == workshopId); + } + //ToDo handel exception if is null + monthySalary = customizeWorkshopEmployeeSettings?.Salary ?? 0; + monthDays = customizeWorkshopSettings.MaxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth + ? 30 + : firstDayOfMonth.CountMonthDays(); - List groupedRollCall = rollCallResult.GroupBy(x => x.ShiftDate.Date).Select(x => - new GroupedRollCalls() - { - CreationDate = x.Key, - ShiftList = x.Select(s => new ShiftList() - { - Start = s.StartDate!.Value, - End = s.EndDate!.Value, - EarlyEntryDuration = s.EarlyEntryDuration, - EarlyExitDuration = s.EarlyExitDuration, - LateEntryDuration = s.LateEntryDuration, - LateExitDuration = s.LateExitDuration, - }).ToList(), - HasFriday = x.Any(s => - s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value.DayOfWeek == DayOfWeek.Friday), + var shiftSettings = customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts; - SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - CalculateBreakTime( - x.First().BreakTimeSpan, - new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), + var employeeShiftsSpans = shiftSettings.Select(x => + { + var start = new DateTime(new DateOnly(), x.StartTime); + var end = new DateTime(new DateOnly(), x.EndTime); + if (x.EndTime < x.StartTime) + end = end.AddDays(1); + var span = end - start; + return new EmployeeShiftResult + { + Placement = x.Placement, + ShiftSpan = span + }; - BreakTime = CalculateBreakTime(x.First().BreakTimeSpan, - new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), - ShiftDate = x.Key, - TotalEarlyEntryDuration = new TimeSpan(x.Sum(rollCall => rollCall.EarlyEntryDuration.Ticks)), - TotalLateEntryDuration = new TimeSpan(x.Sum(rollCall => rollCall.LateEntryDuration.Ticks)), - TotalEarlyExitDuration = new TimeSpan(x.Sum(rollCall => rollCall.EarlyExitDuration.Ticks)), - TotalLateExitDuration = new TimeSpan(x.Sum(rollCall => rollCall.LateExitDuration.Ticks)), - TotalShiftDurationTimeSpan = - x.FirstOrDefault() == null ? TimeSpan.Zero : x.First().ShiftDurationTimeSpan - }).ToList(); + }); - var sumOfEmployeeShiftSpan = - groupedRollCall.Any() ? groupedRollCall.First().TotalShiftDurationTimeSpan : TimeSpan.Zero; + #endregion - if (customizeWorkshopEmployeeSettings.BreakTime.BreakTimeType == BreakTimeType.WithTime && - sumOfEmployeeShiftSpan != TimeSpan.Zero) - { - sumOfEmployeeShiftSpan -= customizeWorkshopEmployeeSettings.BreakTime.BreakTimeValue.ToTimeSpan(); - } + List rollCallResult = _context.RollCalls.AsNoTracking().Where(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.ShiftDate.Date >= contractStart.Date && + x.ShiftDate.Date <= contractEnd.Date && x.EndDate != null) + .Select(x => new RollCallViewModel() + { + StartDate = x.StartDate, + EndDate = x.EndDate, + ShiftSpan = (x.EndDate.Value - x.StartDate.Value), + CreationDate = x.CreationDate, + ShiftDate = x.ShiftDate, + EarlyEntryDuration = x.EarlyEntryDuration, + LateEntryDuration = x.LateEntryDuration, + EarlyExitDuration = x.EarlyExitDuration, + LateExitDuration = x.LateExitDuration, + ShiftDurationTimeSpan = x.ShiftDurationTimeSpan, + BreakTimeSpan = x.BreakTimeSpan + }).ToList(); - // ساخت لیست همه تاریخ‌ها در بازه - List allDates = Enumerable.Range(0, (contractEnd - contractStart).Days + 1) - .Select(offset => contractStart.AddDays(offset)) - .ToList(); - // فیلتر تاریخ‌هایی که در لیست حضور نیستند - List absentDates = allDates - .Where(date => !groupedRollCall.Any(g => g.ShiftDate.Date == date.Date)) - .ToList(); + List groupedRollCall = rollCallResult.GroupBy(x => x.ShiftDate.Date).Select(x => + new GroupedRollCalls() + { + CreationDate = x.Key, + ShiftList = x.Select(s => new ShiftList() + { + Start = s.StartDate!.Value, + End = s.EndDate!.Value, + EarlyEntryDuration = s.EarlyEntryDuration, + EarlyExitDuration = s.EarlyExitDuration, + LateEntryDuration = s.LateEntryDuration, + LateExitDuration = s.LateExitDuration, + }).ToList(), + HasFriday = x.Any(s => + s.StartDate.Value.DayOfWeek == DayOfWeek.Friday || s.EndDate.Value.DayOfWeek == DayOfWeek.Friday), - TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); + SumOneDaySpan = new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks)) - CalculateBreakTime( + x.First().BreakTimeSpan, + new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), - numberOfFridays = groupedRollCall.Count(x => x.HasFriday); + BreakTime = CalculateBreakTime(x.First().BreakTimeSpan, + new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))), + ShiftDate = x.Key, + TotalEarlyEntryDuration = new TimeSpan(x.Sum(rollCall => rollCall.EarlyEntryDuration.Ticks)), + TotalLateEntryDuration = new TimeSpan(x.Sum(rollCall => rollCall.LateEntryDuration.Ticks)), + TotalEarlyExitDuration = new TimeSpan(x.Sum(rollCall => rollCall.EarlyExitDuration.Ticks)), + TotalLateExitDuration = new TimeSpan(x.Sum(rollCall => rollCall.LateExitDuration.Ticks)), + TotalShiftDurationTimeSpan = + x.FirstOrDefault() == null ? TimeSpan.Zero : x.First().ShiftDurationTimeSpan + }).ToList(); - numberOfWorkingDay = groupedRollCall.Count(); - //تعداد روز های قرارداد - int contractDays = (int)contractDuration.TotalDays + 1; + var sumOfEmployeeShiftSpan = + groupedRollCall.Any() ? groupedRollCall.First().TotalShiftDurationTimeSpan : TimeSpan.Zero; - //روز های غیبت - var absenceDays = mandatoryDays - groupedRollCall.Count; - int fridays = 0; + if (customizeWorkshopEmployeeSettings.BreakTime.BreakTimeType == BreakTimeType.WithTime && + sumOfEmployeeShiftSpan != TimeSpan.Zero) + { + sumOfEmployeeShiftSpan -= customizeWorkshopEmployeeSettings.BreakTime.BreakTimeValue.ToTimeSpan(); + } - int holiday = _context.HolidayItems.Count(x => x.Holidaydate >= contractStart && x.Holidaydate <= contractEnd); - for (var gDate = contractStart; gDate <= contractEnd; gDate = gDate.AddDays(1)) - { - if (gDate.DayOfWeek == DayOfWeek.Friday) - { - fridays += 1; - } - } + // ساخت لیست همه تاریخ‌ها در بازه + List allDates = Enumerable.Range(0, (contractEnd - contractStart).Days + 1) + .Select(offset => contractStart.AddDays(offset)) + .ToList(); - if (customizeWorkshopEmployeeSettings.FridayWork == FridayWork.Default) - { - var fridayWorkingTotalDays = groupedRollCall.Count(x => x.ShiftDate.DayOfWeek == DayOfWeek.Friday); - var fridayWorking = fridays - fridayWorkingTotalDays; + // فیلتر تاریخ‌هایی که در لیست حضور نیستند + List absentDates = allDates + .Where(date => !groupedRollCall.Any(g => g.ShiftDate.Date == date.Date)) + .ToList(); - //mandatoryDays -= fridayWorking; + TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks)); - } + numberOfFridays = groupedRollCall.Count(x => x.HasFriday); - if (customizeWorkshopEmployeeSettings.HolidayWork == HolidayWork.Default) - { - var groupStartDaysDates = groupedRollCall.Select(x => x.CreationDate.Date).ToList(); - var holidayWorkingDays = _context.HolidayItems.Count(x => - groupStartDaysDates.Any(r => r == x.Holidaydate.Date)); - holiday = holiday - holidayWorkingDays; + numberOfWorkingDay = groupedRollCall.Count(); + //تعداد روز های قرارداد + int contractDays = (int)contractDuration.TotalDays + 1; - mandatoryDays -= holiday; + //روز های غیبت + var absenceDays = mandatoryDays - groupedRollCall.Count; - } + int fridays = 0; - TimeSpan absentTimeSpans = new(); + int holiday = _context.HolidayItems.Count(x => x.Holidaydate >= contractStart && x.Holidaydate <= contractEnd); - if ((mandatoryDays * sumOfEmployeeShiftSpan) > sumSpans) - { - absentTimeSpans = (mandatoryDays * sumOfEmployeeShiftSpan) - sumSpans; - } + for (var gDate = contractStart; gDate <= contractEnd; gDate = gDate.AddDays(1)) + { + if (gDate.DayOfWeek == DayOfWeek.Friday) + { + fridays += 1; + } + } - dailyWage = monthySalary / monthDays; + if (customizeWorkshopEmployeeSettings.FridayWork == FridayWork.Default) + { + var fridayWorkingTotalDays = groupedRollCall.Count(x => x.ShiftDate.DayOfWeek == DayOfWeek.Friday); + var fridayWorking = fridays - fridayWorkingTotalDays; - var minuteWage = sumOfEmployeeShiftSpan.TotalMinutes == 0 - ? 0 - : (dailyWage / sumOfEmployeeShiftSpan.TotalMinutes); + //mandatoryDays -= fridayWorking; + } - // یافتن مرخصی ساعتی + if (customizeWorkshopEmployeeSettings.HolidayWork == HolidayWork.Default) + { + var groupStartDaysDates = groupedRollCall.Select(x => x.CreationDate.Date).ToList(); + var holidayWorkingDays = _context.HolidayItems.Count(x => + groupStartDaysDates.Any(r => r == x.Holidaydate.Date)); + holiday = holiday - holidayWorkingDays; - #region LeavHourse + mandatoryDays -= holiday; - LeaveSearchModel leaveHourseSearch = new LeaveSearchModel() - { - EmployeeId = employeeId, - WorkshopId = workshopId, - LeaveType = "استحقاقی", + } - StartLeaveGr = contractStart, - EndLeaveGr = contractEnd, - IsAccepted = true, - }; - List leaveList = _leaveRepository.search(leaveHourseSearch); + TimeSpan absentTimeSpans = new(); - #endregion + if ((mandatoryDays * sumOfEmployeeShiftSpan) > sumSpans) + { + absentTimeSpans = (mandatoryDays * sumOfEmployeeShiftSpan) - sumSpans; + } - //****افزودن مرخصی پرسنل به مجموع ساعات کار*** - #region AddEmployeeLeaves + dailyWage = monthySalary / monthDays; - //TimeSpan workingPerDayAve = sumSpans / numberOfWorkingDay;//میانگین ساعت کار در روز + var minuteWage = sumOfEmployeeShiftSpan.TotalMinutes == 0 + ? 0 + : (dailyWage / sumOfEmployeeShiftSpan.TotalMinutes); - //if (workingPerDayAve <= new TimeSpan(7, 20, 0)) - //{ - // sumLeave = leavingDayCout * workingPerDayAve; - //} - //else - //{ - // sumLeave = leavingDayCout * new TimeSpan(7, 20, 0); - //} + // یافتن مرخصی ساعتی + #region LeavHourse + LeaveSearchModel leaveHourseSearch = new LeaveSearchModel() + { + EmployeeId = employeeId, + WorkshopId = workshopId, + LeaveType = "استحقاقی", - double leavePayAmount = 0; - double absentsDeductionAmount = 0; + StartLeaveGr = contractStart, + EndLeaveGr = contractEnd, + IsAccepted = true, + }; + List leaveList = _leaveRepository.search(leaveHourseSearch); - int leavePermittedDays = customizeWorkshopEmployeeSettings.LeavePermittedDays; - double leaveValue = customizeWorkshopEmployeeSettings.LeavePay.Value; + #endregion + //****افزودن مرخصی پرسنل به مجموع ساعات کار*** + #region AddEmployeeLeaves - if (customizeWorkshopEmployeeSettings.CustomizeWorkshopGroupSettingId == 77) - { - var startMonth = contractStart; - var endMonth = contractStart.ToFarsi().FindeEndOfMonth().ToGeorgianDateTime(); + //TimeSpan workingPerDayAve = sumSpans / numberOfWorkingDay;//میانگین ساعت کار در روز - int fridayInMonth = 0; - // Ensure the dates are in the correct order - if (startMonth > endMonth) - { - var temp = startMonth; - startMonth = endMonth; - endMonth = temp; - } - // Find the first Friday in the range - int daysUntilFriday = ((int)DayOfWeek.Friday - (int)startMonth.DayOfWeek + 7) % 7; - DateTime firstFriday = startMonth.AddDays(daysUntilFriday); + //if (workingPerDayAve <= new TimeSpan(7, 20, 0)) + //{ + // sumLeave = leavingDayCout * workingPerDayAve; + //} + //else + //{ + // sumLeave = leavingDayCout * new TimeSpan(7, 20, 0); + //} - // If the first Friday is outside the range, there are no Fridays - if (firstFriday > endMonth) - { - fridayInMonth = 0; - } - // Calculate the total number of days between the first Friday and the end date - int totalFridayPeriod = (endMonth - firstFriday).Days; - // Count the Fridays by dividing the total days by 7 and adding 1 for the first Friday - fridayInMonth = totalFridayPeriod / 7 + 1; + double leavePayAmount = 0; + double absentsDeductionAmount = 0; + int leavePermittedDays = customizeWorkshopEmployeeSettings.LeavePermittedDays; + double leaveValue = customizeWorkshopEmployeeSettings.LeavePay.Value; - leavePermittedDays = fridayInMonth; - } + if (customizeWorkshopEmployeeSettings.CustomizeWorkshopGroupSettingId == 77) + { + var startMonth = contractStart; + var endMonth = contractStart.ToFarsi().FindeEndOfMonth().ToGeorgianDateTime(); + int fridayInMonth = 0; + // Ensure the dates are in the correct order + if (startMonth > endMonth) + { + var temp = startMonth; + startMonth = endMonth; + endMonth = temp; + } + // Find the first Friday in the range + int daysUntilFriday = ((int)DayOfWeek.Friday - (int)startMonth.DayOfWeek + 7) % 7; + DateTime firstFriday = startMonth.AddDays(daysUntilFriday); + // If the first Friday is outside the range, there are no Fridays + if (firstFriday > endMonth) + { + fridayInMonth = 0; + } - sumSpans = CalculateLeavePay(sumOfEmployeeShiftSpan, absentTimeSpans, leavePermittedDays, monthDays, - contractDays, sumSpans - , leaveValue, minuteWage, contractStart, contractEnd, out leavePayAmount, out absentsDeductionAmount); + // Calculate the total number of days between the first Friday and the end date + int totalFridayPeriod = (endMonth - firstFriday).Days; - if (customizeWorkshopEmployeeSettings.LeavePay.LeavePayType != LeavePayType.None) - { + // Count the Fridays by dividing the total days by 7 and adding 1 for the first Friday + fridayInMonth = totalFridayPeriod / 7 + 1; - } - else - { - absentsDeductionAmount = absentTimeSpans.TotalMinutes * minuteWage; - } - leavePayAmount = 0; + leavePermittedDays = fridayInMonth; + } - absenceDays = (absenceDays - leavePermittedDays) < 0 ? 0 : (absenceDays - leavePermittedDays); - //اگر روز تولدش تاریخ فیش وجود داشت - var monthOfBirthDay = employee!.DateOfBirth.ToFarsi().Substring(5, 2); - var pc = new PersianCalendar(); - var birthdayMonth = pc.GetMonth(employee.DateOfBirth); - var birthdayDay = pc.GetDayOfMonth(employee.DateOfBirth); - if (birthdayMonth == 12 && birthdayDay == 30) - { - //چک کن که آیا سال قرارداد کبیسه هست یا نه - var leap = - pc.IsLeapYear(pc.GetYear(contractStart)); - if (!leap) - { - birthdayDay = 29; - } - } + sumSpans = CalculateLeavePay(sumOfEmployeeShiftSpan, absentTimeSpans, leavePermittedDays, monthDays, + contractDays, sumSpans + , leaveValue, minuteWage, contractStart, contractEnd, out leavePayAmount, out absentsDeductionAmount); + if (customizeWorkshopEmployeeSettings.LeavePay.LeavePayType != LeavePayType.None) + { + } + else + { + absentsDeductionAmount = absentTimeSpans.TotalMinutes * minuteWage; + } - var employeeBirthDay = $"{yearOfCheckout:0000}/{birthdayMonth:00}/{birthdayDay:00}".ToGeorgianDateTime(); + leavePayAmount = 0; - if (employeeBirthDay >= contractStart && employeeBirthDay <= contractEnd && absenceDays > 0) - { - CreateRewardForBirthDay(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, contractStart); - } + absenceDays = (absenceDays - leavePermittedDays) < 0 ? 0 : (absenceDays - leavePermittedDays); + //اگر روز تولدش تاریخ فیش وجود داشت + var monthOfBirthDay = employee!.DateOfBirth.ToFarsi().Substring(5, 2); + var pc = new PersianCalendar(); + var birthdayMonth = pc.GetMonth(employee.DateOfBirth); + var birthdayDay = pc.GetDayOfMonth(employee.DateOfBirth); + if (birthdayMonth == 12 && birthdayDay == 30) + { + //چک کن که آیا سال قرارداد کبیسه هست یا نه + var leap = + pc.IsLeapYear(pc.GetYear(contractStart)); + if (!leap) + { + birthdayDay = 29; + } + } - Console.WriteLine(sumSpans); - #endregion - //***********************************// - //ToTal Hours Employee Worked - double totalHours = (sumSpans.TotalMinutes) / 60; - int totalHolidaysAndNotH = (int)sumSpans.TotalHours; - int totalHolidaysAndNotM = (int)(sumSpans.TotalMinutes % 60); - //***********************************// + var employeeBirthDay = $"{yearOfCheckout:0000}/{birthdayMonth:00}/{birthdayDay:00}".ToGeorgianDateTime(); + if (employeeBirthDay >= contractStart && employeeBirthDay <= contractEnd && absenceDays > 0) + { - #region Deductions + CreateRewardForBirthDay(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, contractStart); + } - //غیبت - //تاخیر و تعجیل - //حق بیمه - #region InsurancePay + Console.WriteLine(sumSpans); - InsuranceDeduction insuranceDeduction = customizeWorkshopEmployeeSettings.InsuranceDeduction; - //farokhiChange - double insuranceDeductionAmount = - InsurancePayCalculation(employeeId, contractStart, contractEnd, insuranceDeduction, monthySalary); + #endregion - #endregion + //***********************************// + //ToTal Hours Employee Worked + double totalHours = (sumSpans.TotalMinutes) / 60; + int totalHolidaysAndNotH = (int)sumSpans.TotalHours; + int totalHolidaysAndNotM = (int)(sumSpans.TotalMinutes % 60); + //***********************************// - #region SalaryAidDeduction - var salaryAidViewModel = SalaryAidsForCheckout(employeeId, workshopId, checkoutStart, checkoutEnd); - double salaryAidDeduction = salaryAidViewModel.Sum(x => x.AmountDouble); - #endregion + #region Deductions - #region Loan + //غیبت - var loanInstallments = LoanInstallmentForCheckout(employeeId, workshopId, contractStart, contractEnd); + //تاخیر و تعجیل - double loanDeduction = loanInstallments.Sum(x => x.AmountDouble); - #endregion + //حق بیمه - #region Fine + #region InsurancePay - var fineViewModels = FinesForCheckout(employeeId, workshopId, contractStart, contractEnd); - double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble()); + InsuranceDeduction insuranceDeduction = customizeWorkshopEmployeeSettings.InsuranceDeduction; + //farokhiChange + double insuranceDeductionAmount = + InsurancePayCalculation(employeeId, contractStart, contractEnd, insuranceDeduction, monthySalary); - #endregion + #endregion + #region SalaryAidDeduction - #endregion + var salaryAidViewModel = SalaryAidsForCheckout(employeeId, workshopId, checkoutStart, checkoutEnd); + double salaryAidDeduction = salaryAidViewModel.Sum(x => x.AmountDouble); + #endregion - #region Payments + #region Loan - //اضافه کاری + var loanInstallments = LoanInstallmentForCheckout(employeeId, workshopId, contractStart, contractEnd); - #region OvertimePay + double loanDeduction = loanInstallments.Sum(x => x.AmountDouble); - double overtimePayAmount = 0; + #endregion + #region Fine + var fineViewModels = FinesForCheckout(employeeId, workshopId, contractStart, contractEnd); + double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble()); - TimeSpan overtimeTimeSpan; + #endregion - if (customizeWorkshopSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular && - customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) - { - overtimeTimeSpan = CalculateOvertimeSpanWithSumSpan(sumSpans, mandatoryDays, shiftSettings); - } - else if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) - { - //var date = new DateOnly(); - //var firstStartShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MinBy(x => x.Placement).StartTime); - //var lastEndShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MaxBy(x => x.Placement).EndTime); - //if (lastEndShift > firstStartShift) - // firstStartShift = firstStartShift.AddDays(1); - //var offSet = (firstStartShift - lastEndShift).Divide(2); - //var employeeOffSet = TimeOnly.FromDateTime(lastEndShift.Add(offSet)); - overtimeTimeSpan = CalculateOvertimeSpanWithSumSpan(sumSpans, mandatoryDays, shiftSettings); + #endregion - } - else - { - var irregularShifts = customizeWorkshopEmployeeSettings.IrregularShift.WorkshopIrregularShifts; - overtimeTimeSpan = CalculateRotatingOvertime(customizeWorkshopEmployeeSettings.CustomizeRotatingShifts, - groupedRollCall, mandatoryDays, sumSpans); - } - overtimePayAmount = - CalculateOvertimePay(overtimeTimeSpan, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage); + #region Payments - if (overtimePayAmount >= absentsDeductionAmount) - { - overtimePayAmount = overtimePayAmount - absentsDeductionAmount; - absentsDeductionAmount = 0; - } - else - { - absentsDeductionAmount = absentsDeductionAmount - overtimePayAmount; - overtimePayAmount = 0; - } + //اضافه کاری - overtimePayAmount = 0; + #region OvertimePay + double overtimePayAmount = 0; + TimeSpan overtimeTimeSpan; - #endregion + if (customizeWorkshopSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular && + customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) + { + overtimeTimeSpan = CalculateOvertimeSpanWithSumSpan(sumSpans, mandatoryDays, shiftSettings); + } + else if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Regular) + { + //var date = new DateOnly(); + //var firstStartShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MinBy(x => x.Placement).StartTime); + //var lastEndShift = new DateTime(date, customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts.MaxBy(x => x.Placement).EndTime); + //if (lastEndShift > firstStartShift) + // firstStartShift = firstStartShift.AddDays(1); + //var offSet = (firstStartShift - lastEndShift).Divide(2); + //var employeeOffSet = TimeOnly.FromDateTime(lastEndShift.Add(offSet)); - #region KebabMahdiAbsentsCaclculation + overtimeTimeSpan = CalculateOvertimeSpanWithSumSpan(sumSpans, mandatoryDays, shiftSettings); - var rollCallDays = groupedRollCall.Count > mandatoryDays ? mandatoryDays : groupedRollCall.Count; + } + else + { + var irregularShifts = customizeWorkshopEmployeeSettings.IrregularShift.WorkshopIrregularShifts; + overtimeTimeSpan = CalculateRotatingOvertime(customizeWorkshopEmployeeSettings.CustomizeRotatingShifts, + groupedRollCall, mandatoryDays, sumSpans); + } - absenceDays = mandatoryDays - rollCallDays; - absenceDays = absenceDays - leavePermittedDays < 0 ? 0 : absenceDays - leavePermittedDays; - absentsDeductionAmount = absenceDays * dailyWage; + overtimePayAmount = + CalculateOvertimePay(overtimeTimeSpan, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage); + if (overtimePayAmount >= absentsDeductionAmount) + { + overtimePayAmount = overtimePayAmount - absentsDeductionAmount; + absentsDeductionAmount = 0; + } + else + { + absentsDeductionAmount = absentsDeductionAmount - overtimePayAmount; + overtimePayAmount = 0; + } - #endregion + overtimePayAmount = 0; - var createReward = absenceDays; - if (monthOfCheckout == 1 && yearOfCheckout == 1404) - { - bool hasAbsents = _context.CustomizeCheckouts.Any(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.MonthInt == 12 && x.YearInt == 1403 && - x.FineAbsenceDeduction > 0); - bool absentInEid = !_context.RollCalls.Any(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.ShiftDate == new DateTime(2025, 3, 20)); - if (hasAbsents && absentInEid) - { - CreateReward(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, - new DateTime(2025, 3, 21), RewardType.Eid, "بابت تعطیلی آخر سال"); - } - if (absentDates.Any(x => x == new DateTime(2025, 4, 2) && createReward > 0)) - { - CreateReward(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, - new DateTime(2025, 4, 2), RewardType.SinzdahBedar, "بابت تعطیلی روز 13 فروردین"); - createReward--; - } - if (absentDates.Any(x => x == new DateTime(2025, 4, 3) && createReward > 0)) - { - CreateReward(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, - new DateTime(2025, 4, 3), RewardType.ChahardahFarvardin, "بابت تعطیلی روز 14 فروردین"); - createReward--; - } - } - #region FridayPay + #endregion - double fridayPayAmount = 0; + #region KebabMahdiAbsentsCaclculation - fridayPayAmount = FridayPayCalculation(customizeWorkshopEmployeeSettings, rollCallResult, dailyWage, - shiftSettings, overtimePayAmount); + var rollCallDays = groupedRollCall.Count > mandatoryDays ? mandatoryDays : groupedRollCall.Count; + absenceDays = mandatoryDays - rollCallDays; + absenceDays = absenceDays - leavePermittedDays < 0 ? 0 : absenceDays - leavePermittedDays; + absentsDeductionAmount = absenceDays * dailyWage; - #endregion - //حق تاهل + #endregion - #region MaritalAllownace + var createReward = absenceDays; + if (monthOfCheckout == 1 && yearOfCheckout == 1404) + { + bool hasAbsents = _context.CustomizeCheckouts.Any(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.MonthInt == 12 && x.YearInt == 1403 && + x.FineAbsenceDeduction > 0); + bool absentInEid = !_context.RollCalls.Any(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.ShiftDate == new DateTime(2025, 3, 20)); + if (hasAbsents && absentInEid) + { + CreateReward(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, + new DateTime(2025, 3, 21), RewardType.Eid, "بابت تعطیلی آخر سال"); + } - double maritalAllowancePay = 0; - if (employee.MaritalStatus == "متاهل") - { - switch (customizeWorkshopEmployeeSettings.MarriedAllowance.MarriedAllowanceType) - { - case MarriedAllowanceType.Money: - { - maritalAllowancePay = customizeWorkshopEmployeeSettings.MarriedAllowance.Value; - break; - } - //case MarriedAllowanceType.PercentageFromSalary: + if (absentDates.Any(x => x == new DateTime(2025, 4, 2) && createReward > 0)) + { + CreateReward(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, + new DateTime(2025, 4, 2), RewardType.SinzdahBedar, "بابت تعطیلی روز 13 فروردین"); + createReward--; + } - // { - // double multiplier = customizeWorkshopEmployeeSettings.MarriedAllowance.Value / 100; - // maritalAllowance = dailyWage * multiplier; - // break; - // } - } - } + if (absentDates.Any(x => x == new DateTime(2025, 4, 3) && createReward > 0)) + { + CreateReward(employeeId, workshopId, dailyWage, monthOfCheckout, yearOfCheckout, + new DateTime(2025, 4, 3), RewardType.ChahardahFarvardin, "بابت تعطیلی روز 14 فروردین"); + createReward--; + } + } - #endregion - //شب کاری + #region FridayPay - #region NightWorkPay + double fridayPayAmount = 0; - double nightworkPayAmount = 0; - List rotatingResultList = RotatingShiftCheck(groupedRollCall); + fridayPayAmount = FridayPayCalculation(customizeWorkshopEmployeeSettings, rollCallResult, dailyWage, + shiftSettings, overtimePayAmount); - // شبکاری - TimeSpan nightWorks = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); - if (nightWorks > new TimeSpan()) - { - switch (customizeWorkshopEmployeeSettings.NightWorkPay.NightWorkingType) - { - case NightWorkType.MoneyPerHour: - { - var baseAmount = customizeWorkshopEmployeeSettings.NightWorkPay.Value; - var nightWorkMinutes = (int)(nightWorks).TotalMinutes; - nightworkPayAmount += nightWorkMinutes * (baseAmount / 60); - break; - } - case NightWorkType.PercentageFromSalary: - { - double multiplier = customizeWorkshopEmployeeSettings.NightWorkPay.Value / 100; - var nightWorkMinutes = (int)(nightWorks).TotalMinutes; - nightworkPayAmount += ((dailyWage * multiplier) / 60) * nightWorkMinutes; - break; - } - - - } - } - - #endregion - - //سنوات - - #region BaseYearsPay - - double baseYearsPayAmount = CalculateYearsPayAmount(employeeId, workshopId, monthySalary, contractStart, - contractEnd - , customizeWorkshopEmployeeSettings.BaseYearsPay, customizeWorkshopSettings.BaseYearsPayInEndOfYear, - customizeWorkshopSettings.MaxMonthDays); - - #endregion - - //حق اولاد - - #region FamilyAllowancePay - - double familyAllowancePay = 0; - switch (customizeWorkshopEmployeeSettings.FamilyAllowance.FamilyAllowanceType) - { - case FamilyAllowanceType.Money: - { - double baseAmount = customizeWorkshopEmployeeSettings.FamilyAllowance.Value; - familyAllowancePay = CalculateFamilyAllowancePayAmount(employeeId, baseAmount, contractEnd); - break; - } + #endregion - case FamilyAllowanceType.Percentage: - { - double multiplier = customizeWorkshopEmployeeSettings.FamilyAllowance.Value / 100; - familyAllowancePay = - CalculateFamilyAllowancePayAmount(employeeId, multiplier * monthySalary, contractEnd); - break; - } - } - - #endregion - - #region Reward - - var rewardViewModels = RewardForCheckout(employeeId, workshopId, checkoutEnd, checkoutStart); - - double rewardPay = rewardViewModels.Sum(x => x.AmountDouble); - - #endregion - - #region LeavePay - - - - #endregion - - #region BonusesPay - - double bonusesPayAmount = 0; - - - if (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType != BonusesType.None) - { - switch (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType) - { - case BonusesType.OneTimeOfSalary: - bonusesPayAmount = monthySalary; - break; - case BonusesType.TwoTimeOfSalary: - bonusesPayAmount = monthySalary * 2; - break; - case BonusesType.Money: - bonusesPayAmount = customizeWorkshopEmployeeSettings.BonusesPay.Value; - break; - case BonusesType.PercentageOfSalary: - bonusesPayAmount = (monthySalary * customizeWorkshopEmployeeSettings.BonusesPay.Value) / 100; - break; - } - - double bonusesPerMonth = bonusesPayAmount / 12; + //حق تاهل - if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.YearlyPay) - { - var contractEndFarsi = Tools.FindeEndOfMonth(contractEnd.ToFarsi()); - if (monthOfCheckout == 12 && (contractEndFarsi.EndsWith("29")) || contractEndFarsi.EndsWith("30")) - { - } - else if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == - BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft) - { - TimeSpan bonusDuration; - DateTime startOfYear = new PersianCalendar().ToDateTime(yearOfCheckout, 1, 1, 0, 0, 0, 0); - if (startOfYear < leftWork.StartWorkDateGr) - bonusDuration = leftWorkDurationTimeSpan; - else - bonusDuration = leftWork.LeftWorkDateGr - startOfYear; - //ToDo: Check if should be absolute 365! - bonusesPayAmount = (bonusesPayAmount / 365) * bonusDuration.TotalDays; - } - else - { - bonusesPayAmount = 0; - } - } - else if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.MonthlyPay) - { + #region MaritalAllownace + double maritalAllowancePay = 0; + if (employee.MaritalStatus == "متاهل") + { + switch (customizeWorkshopEmployeeSettings.MarriedAllowance.MarriedAllowanceType) + { + case MarriedAllowanceType.Money: + { + maritalAllowancePay = customizeWorkshopEmployeeSettings.MarriedAllowance.Value; + break; + } + //case MarriedAllowanceType.PercentageFromSalary: - if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == - BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft && contractDays < monthDays) - bonusesPayAmount = (bonusesPerMonth / contractEnd.CountPersianMonthDays()) * - contractDuration.TotalDays + 1; - - - bonusesPayAmount = bonusesPerMonth; - } - else - { - throw new InvalidDataException(); - } - } - - #endregion - - - #endregion - - #region LateToWork & EarlyExit - - //var lateToWorkEarlyExit = LateToWorkEarlyExit(groupedRollCall, shiftSettings, leaveList); - //foreach (var i in lateToWorkEarlyExit) - //{ - // Console.WriteLine(" start : " + i.StartSpan + " end : " + i.EndSpan + " spaning : " + i.Spanning + " Type : " + i.TypeOfSapn); - //} - - //var lateToWoks = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "LateToWork"); - //var earlyExits = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "EarlyExist"); - - //var lateToWork = new TimeSpan(lateToWoks.Sum(x => x.Spanning.Ticks)); - //var earlyExist = new TimeSpan(earlyExits.Sum(x => x.Spanning.Ticks)); - //var totalSpaning = new TimeSpan(lateToWorkEarlyExit.Sum(x => x.Spanning.Ticks)); - //Console.ForegroundColor = ConsoleColor.Yellow; - //Console.WriteLine(" LateToWork H : " + (int)lateToWork.TotalHours + " M : " + (int)(lateToWork.TotalMinutes % 60)); - //Console.WriteLine(" EarlyExist H : " + (int)earlyExist.TotalHours + " M : " + (int)(earlyExist.TotalMinutes % 60)); - //Console.WriteLine(" TotalSpaning H : " + (int)totalSpaning.TotalHours + " M : " + (int)(totalSpaning.TotalMinutes % 60)); - //Console.ResetColor(); - - //double earlyExitDeduction = 0; - //double lateToWorkDeduction = 0; - - //////محاسبه مزد روزانه به ازای هر دقیقه - ////double dailyWagePerMinute = - //// (customizeWorkshopEmployeeSettings.Salary / monthDays) / sumOfEmployeeShiftSpan.TotalMinutes; - - //if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType != EarlyExitType.None && earlyExist > new TimeSpan()) - //{ - // earlyExitDeduction = customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType switch - // { - // EarlyExitType.Default => earlyExist.TotalMinutes * minuteWage, - - // EarlyExitType.MoneyPerMinute => earlyExist.TotalMinutes * customizeWorkshopEmployeeSettings.EarlyExit.Value, - - // _ => 0 - // }; - - //} - - - //if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType != LateToWorkType.None && lateToWork > new TimeSpan()) - //{ - // lateToWorkDeduction = customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType switch - // { - // LateToWorkType.Default => lateToWork.TotalMinutes * minuteWage, - - // LateToWorkType.MoneyPerMinute => lateToWork.TotalMinutes * customizeWorkshopEmployeeSettings.LateToWork.Value, - - // _ => 0 - // }; - - //} - - //if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines.Any()) - //{ - // lateToWorkDeduction += - // (from lateToWorkTimeFine in customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines - // let stepFine = lateToWoks.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(lateToWorkTimeFine.Minute)) - // select stepFine * lateToWorkTimeFine.FineMoney).Sum(); - //} - //if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines.Any()) - //{ - // earlyExitDeduction += - // (from earlyExitFine in customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines - // let stepFine = earlyExits.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(earlyExitFine.Minute)) - // select stepFine * earlyExitFine.FineMoney).Sum(); - //} - - double lateToWorkDeduction = 0; - TimeSpan totalLateToWorkSpan = TimeSpan.Zero; - - - - if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Rotating) - { - foreach (var rollCall in groupedRollCall) - { - - var rollCallShift = rollCall.TotalShiftDurationTimeSpan; - var dayMinuteWage = rollCallShift.TotalMinutes == 0 ? 0 : (dailyWage / rollCallShift.TotalMinutes); - (DateTime start, DateTime end)? firstShift = null; - foreach (var rc in rollCall.ShiftList.OrderBy(x => x.Start)) - { - double minutes = 0; - var shift = FindRotatingShift(rc.Start, rc.End, customizeWorkshopEmployeeSettings.CustomizeRotatingShifts); - if (firstShift == null) - { - firstShift = shift; - } - - - if (shift.start == firstShift.Value.start && shift.end == firstShift.Value.end) - { - minutes += rc.LateEntryDuration.TotalMinutes; - totalLateToWorkSpan = totalLateToWorkSpan.Add(rc.LateEntryDuration); - } - lateToWorkDeduction += dayMinuteWage * minutes; - } - - } - - - } - else - { - foreach (var rollCall in groupedRollCall) - { - - var rollCallShift = rollCall.TotalShiftDurationTimeSpan; - var dayMinuteWage = rollCallShift.TotalMinutes == 0 ? 0 : (dailyWage / rollCallShift.TotalMinutes); - var minutes = rollCall.TotalLateEntryDuration.TotalMinutes; - lateToWorkDeduction += dayMinuteWage * minutes; - totalLateToWorkSpan = totalLateToWorkSpan.Add(rollCall.TotalLateEntryDuration); - - } - } - - if (mandatoryDays == 31) - { - mandatoryDays = 30; - } - - - #endregion - - return new CustomizeCheckoutMandatoryViewModel - { - InsuranceDeduction = Math.Truncate(insuranceDeductionAmount), - FridayPay = Math.Truncate(fridayPayAmount), - OverTimePay = Math.Truncate(overtimePayAmount), - BaseYearsPay = Math.Truncate(baseYearsPayAmount), - NightWorkPay = Math.Truncate(nightworkPayAmount), - MarriedAllowance = Math.Truncate(maritalAllowancePay), - FamilyAllowance = Math.Truncate(familyAllowancePay), - LeavePay = Math.Truncate(leavePayAmount), - FineAbsenceDeduction = Math.Truncate(absentsDeductionAmount), - BonusesPay = Math.Truncate(bonusesPayAmount), - ContractEndFa = contractEnd.ToFarsi(), - ContractStartFa = contractStart.ToFarsi(), - EmployeeName = employee.FullName, - InstallmentDeduction = Math.Truncate(loanDeduction), - SalaryAidDeduction = Math.Truncate(salaryAidDeduction), - FineDeduction = Math.Truncate(fineDeduction), - RewardPay = Math.Truncate(rewardPay), - Month = monthOfCheckout, - Year = yearOfCheckout, - LateToWorkDeduction = Math.Truncate(lateToWorkDeduction), - EarlyExitDeduction = 0, - ShiftPay = 0, - TaxDeduction = 0, - EmployeeId = employeeId, - SumOfWorkingDays = totalDays.ToString(), - ContractNo = contract?.ContractNo ?? "-", - MonthlySalary = dailyWage * mandatoryDays, - PersonnelCode = personnelCode, - FineViewModels = fineViewModels, - InstallmentViewModels = loanInstallments, - SalaryAidViewModels = salaryAidViewModel, - RewardViewModels = rewardViewModels, - LateToWorkValue = totalLateToWorkSpan, - SettingSalary = customizeWorkshopEmployeeSettings.Salary, - DailyWage = dailyWage, - ShiftStatus = customizeWorkshopEmployeeSettings.WorkshopShiftStatus, - IrregularShift = customizeWorkshopEmployeeSettings.IrregularShift, - CustomizeRotatingShifts = customizeWorkshopEmployeeSettings.CustomizeRotatingShifts, - EmployeeSettingsShifts = customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts - .Select(x => (CustomizeSifts)x).ToList(), - }; - } - - private CustomizeCheckoutMandatoryViewModel CheckoutWithoutCalculationForKebabMahdi(long workshopId, long employeeId, DateTime contractStart, DateTime contractEnd) - { - var firstDayOfMonth = $"{(contractStart.ToFarsi())[..8]}/01".ToGeorgianDateTime(); - - CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings = _context.CustomizeWorkshopEmployeeSettings.AsSplitQuery().FirstOrDefault(x => - x.WorkshopId == workshopId && x.EmployeeId == employeeId); - CustomizeWorkshopSettings customizeWorkshopSettings = - _context.CustomizeWorkshopSettings.FirstOrDefault(x => x.WorkshopId == workshopId); - //ToDo handel exception if is null - var monthySalary = customizeWorkshopEmployeeSettings?.Salary ?? 0; - var monthDays = customizeWorkshopSettings.MaxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth - ? 30 - : firstDayOfMonth.CountMonthDays(); - double dailyWage = 0; - dailyWage = monthySalary / monthDays; - - var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; - var mandatoryDays = totalDays; - - - #region SalaryAidDeduction - - var salaryAidViewModel = SalaryAidsForCheckout(employeeId, workshopId, contractEnd, contractEnd); - double salaryAidDeduction = salaryAidViewModel.Sum(x => x.AmountDouble); - - #endregion - - #region Loan - - var loanInstallments = LoanInstallmentForCheckout(employeeId, workshopId, contractStart, contractEnd); - - double loanDeduction = loanInstallments.Sum(x => x.AmountDouble); - - #endregion - - #region Fine - - var fineViewModels = FinesForCheckout(employeeId, workshopId, contractStart, contractEnd); - double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble()); - - #endregion - #region Reward - - var rewardViewModels = RewardForCheckout(employeeId, workshopId, contractStart, contractEnd); - - double rewardPay = rewardViewModels.Sum(x => x.AmountDouble); - #endregion - - - if (mandatoryDays == 31) - { - mandatoryDays = 30; - } - return new CustomizeCheckoutMandatoryViewModel() - { - MonthlySalary = dailyWage * mandatoryDays, - RewardPay = rewardPay, - RewardViewModels = rewardViewModels, - SalaryAidDeduction = salaryAidDeduction, - SalaryAidViewModels = salaryAidViewModel, - InstallmentDeduction = loanDeduction, - InstallmentViewModels = loanInstallments, - FineDeduction = fineDeduction, - FineViewModels = fineViewModels - }; - } - - - private List RewardForCheckout(long employeeId, long workshopId, DateTime checkoutEnd, DateTime checkoutStart) - { - return _context.Rewards.Where(x => - x.WorkshopId == workshopId && x.EmployeeId == employeeId && x.GrantDate <= checkoutEnd && - x.GrantDate >= checkoutStart).Select(x => new RewardViewModel - { - Title = x.Title, - Amount = x.Amount.ToMoney(), - AmountDouble = x.Amount, - Description = x.Description, - GrantDateGr = x.GrantDate, - GrantDateFa = x.GrantDate.ToFarsi(), - IsActive = x.IsActive, - Id = x.id - }).ToList(); - } - - private List FinesForCheckout(long employeeId, long workshopId, DateTime contractStart, DateTime contractEnd) - { - return _context.Fines.Where(x => - x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.FineDate >= contractStart && - x.FineDate <= contractEnd && x.IsActive == IsActive.True).Select(x => new FineViewModel() - { - IsActive = x.IsActive, - Amount = x.Amount.ToMoney(), - FineDate = x.FineDate.ToFarsi(), - Id = x.id, - Title = x.Title, - EmployeeId = x.EmployeeId, - CreationDate = x.CreationDate.ToFarsi() - }).ToList(); - } - - private List LoanInstallmentForCheckout(long employeeId, long workshopId, DateTime contractStart, DateTime contractEnd) - { - return _context.Loans - .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId) - .SelectMany(x => x.LoanInstallments) - .Where(i => i.InstallmentDate >= contractStart && i.InstallmentDate <= contractEnd && i.IsActive == IsActive.True) - .Select(x => new LoanInstallmentViewModel() - { - Id = x.Id, - Month = x.Month, - IsActive = x.IsActive, - Amount = x.AmountForMonth.ToMoney(), - Year = x.Year, - AmountDouble = x.AmountForMonth, - RemainingAmount = _context.Loans.SelectMany(l => l.LoanInstallments).Where(i => i.LoanId == x.LoanId && i.IsActive == IsActive.True && i.InstallmentDate > x.InstallmentDate) - .Sum(i => i.AmountForMonth).ToMoney(), - LoanAmount = _context.Loans.FirstOrDefault(l => l.id == x.LoanId).Amount.ToMoney() - }).ToList(); - } - - private List SalaryAidsForCheckout(long employeeId, long workshopId, DateTime checkoutStart, DateTime checkoutEnd) - { - return _context.SalaryAids - .Where(x => x.CalculationDate >= checkoutStart && x.CalculationDate <= checkoutEnd && x.EmployeeId == employeeId && x.WorkshopId == workshopId).Select(x => new SalaryAidViewModel() - { - Amount = x.Amount.ToMoney(), - AmountDouble = x.Amount, - SalaryAidDateTimeFa = x.SalaryAidDateTime.ToFarsi(), - SalaryAidDateTimeGe = x.SalaryAidDateTime, - CalculationDateTimeGe = x.CalculationDate, - CalculationDateTimeFa = x.CalculationDate.ToFarsi(), - Id = x.id - }).ToList(); - } - - private void CreateRewardForBirthDay(long employeeId, long workshopId, double amount, int month, int year, - DateTime contractStart) - { - var start = $"{year}/{month:00}/01".ToGeorgianDateTime(); - var end = $"{year}/{month:00}/01".FindeEndOfMonth().ToGeorgianDateTime(); - if (_context.Rewards.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId - && x.GrantDate >= start && x.GrantDate <= end - && x.RewardType == RewardType.CreatedByCheckoutForBirthDay) == false) - { - var reward = new Reward(employeeId, workshopId, amount, "", 0, UserType.System, contractStart, "هدیه تولد", - RewardType.CreatedByCheckoutForBirthDay); - _context.Rewards.Add(reward); - _context.SaveChanges(); - } - } - - private void CreateReward(long employeeId, long workshopId, double amount, int month, int year, - DateTime contractStart, RewardType type, string title) - { - var start = $"{year}/{month:00}/01".ToGeorgianDateTime(); - var end = $"{year}/{month:00}/01".FindeEndOfMonth().ToGeorgianDateTime(); - if (_context.Rewards.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId - && x.GrantDate >= start && x.GrantDate <= end - && x.RewardType == type) == false) - { - var reward = new Reward(employeeId, workshopId, amount, "", 0, UserType.System, contractStart, title, type); - _context.Rewards.Add(reward); - _context.SaveChanges(); - } - } - //private void CreateRewardForChahardah(long employeeId, long workshopId, double amount, int month, int year, - // DateTime contractStart) - //{ - // var start = $"{year}/{month:00}/01".ToGeorgianDateTime(); - // var end = $"{year}/{month:00}/01".FindeEndOfMonth().ToGeorgianDateTime(); - // if (_context.Rewards.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId - // && x.GrantDate >= start && x.GrantDate <= end - // && x.RewardType == RewardType.ChahardahFarvardin) == false) - // { - // var reward = new Reward(employeeId, workshopId, amount, "", 0, contractStart, "بابت تعطیلی روز 14 فروردین", - // RewardType.ChahardahFarvardin); - // _context.Rewards.Add(reward); - // _context.SaveChanges(); - // } - //} - - - - - private TimeSpan CalculateIrregularOverTime(List rollCalls, TimeSpan employeeShiftSpan, WorkshopIrregularShifts irregularShifts, int mandatoryDays) - { - var sumOfRollCallTicks = rollCalls.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks); - - var sumRollCall = new TimeSpan(sumOfRollCallTicks); - var sumOfShift = employeeShiftSpan * mandatoryDays; - - if (sumOfShift > sumRollCall) - return TimeSpan.Zero; - - return sumRollCall - sumOfShift; - } - - - - public static TimeSpan CalculateIrregularShiftSpans(int totalDays, IrregularShift irregularShift) - { - //مبنای تقسیم که بر اساس جمع مقدار ساعت استراحت و ساعت کاری بدست میاد - double baseDivideTime = 0; - - //مقدار ساعت کارکرد در هر شیفت - double workTime = 0; - switch (irregularShift.WorkshopIrregularShifts) - { - case WorkshopIrregularShifts.TwelveThirtySix: - baseDivideTime = 48; - workTime = 12; - break; - case WorkshopIrregularShifts.TwelveTwentyFour: - baseDivideTime = 36; - workTime = 12; - break; - case WorkshopIrregularShifts.TwentyFourFortyEight: - baseDivideTime = 72; - workTime = 24; - break; - case WorkshopIrregularShifts.TwentyFourTwentyFour: - baseDivideTime = 48; - workTime = 24; - break; - } - //کل ساعاتی داخلش ممکنه کار کرده باشه - var workingHour = totalDays * 24; - - //مقدار تعداد خالصی که سر شیفت بوده است - int countOfWorking = (int)(workingHour / baseDivideTime); - - //باقی مونده تعدادی که سر شیفت بوده است - double fractionalPart = (workingHour / baseDivideTime) - countOfWorking; - - //مقدار ساعت خالصی که سر کار بوده است - TimeSpan sumOfEmployeeWorkingHours = TimeSpan.FromHours(countOfWorking * workTime); - - //مقدار احتمال سر کار بودن بر حسب باقی مونده تقسیم - var workingTimesDiff = fractionalPart * workTime; - - - workingTimesDiff = workingTimesDiff >= workTime ? workTime : workingTimesDiff; - - //جمع ساعات خالصی و احتمالی - sumOfEmployeeWorkingHours = sumOfEmployeeWorkingHours.Add(TimeSpan.FromHours(workingTimesDiff)); - - return sumOfEmployeeWorkingHours; - } - - public static TimeSpan CalculateIrregularShift(IrregularShift irregularShift) - { - var workingTime = irregularShift.WorkshopIrregularShifts switch - { - WorkshopIrregularShifts.TwelveThirtySix => TimeSpan.FromHours(6), - WorkshopIrregularShifts.TwelveTwentyFour => TimeSpan.FromHours(8), - WorkshopIrregularShifts.TwentyFourFortyEight => TimeSpan.FromHours(8), - WorkshopIrregularShifts.TwentyFourTwentyFour => TimeSpan.FromHours(12), - _ => new TimeSpan() - }; - return workingTime; - } - - - public static TimeSpan CalculateRotatingOvertime(ICollection rotatingShifts, - List rollCalls, int mandatoryDays, TimeSpan sumSpan) - { - TimeSpan mandatorySpan = TimeSpan.Zero; - foreach (var groupedRollCall in rollCalls) - { - var findRotatingShift = FindRotatingShift(groupedRollCall.ShiftList.Min(x => x.Start), - groupedRollCall.ShiftList.Max(x => x.End), rotatingShifts); - var span = findRotatingShift.end - findRotatingShift.start; - mandatorySpan += span; - } - - var leftDays = mandatoryDays - rollCalls.Count; - if (leftDays > 0) - { - - TimeSpan totalDuration = new TimeSpan(rotatingShifts.Sum(shift => Math.Abs(shift.EndTime.Ticks - shift.StartTime.Ticks))); - var averageDuration = totalDuration / rotatingShifts.Count; - mandatorySpan += averageDuration * leftDays; - } - - if (mandatorySpan < sumSpan) - { - return sumSpan - mandatorySpan; - } - return TimeSpan.Zero; - - } - - - #region CustomizeCheckoutCalculation - - public static double FridayPayCalculation(CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings, - List rollCallResult, double dailyWage, ICollection shiftSettings, double overtimePayAmount) - { - double fridayPayAmount = 0; - switch (customizeWorkshopEmployeeSettings.FridayPay.FridayPayType) - { - case (FridayPayType.MoneyPerFridayForDay): - { - int workedFridaysCount = CalculateFridayWorkingTotalDays(rollCallResult); - double baseAmount = customizeWorkshopEmployeeSettings.FridayPay.Value; - fridayPayAmount = baseAmount * workedFridaysCount; - break; - } - case (FridayPayType.MoneyPerFridayPerHour): - { - int workedFridaysMinutes = (int)CalculateFridayWorkingTimeSpan(rollCallResult).TotalMinutes; - double baseAmount = customizeWorkshopEmployeeSettings.FridayPay.Value; - fridayPayAmount = (baseAmount / 60) * workedFridaysMinutes; - break; - } - case (FridayPayType.PercentageFromSalaryPerHour): - { - int workedFridaysMinutes = (int)CalculateFridayWorkingTimeSpan(rollCallResult).TotalMinutes; - double percentageAmount = (customizeWorkshopEmployeeSettings.FridayPay.Value / 100 * dailyWage); - fridayPayAmount = (percentageAmount / 60) * workedFridaysMinutes; - break; - } - //case (FridayPayType.ExtraWorking): - // { - // var fridayOvertimeTimeSpan = CalculateFridayWorkingTimeSpanWithoutOvertime(rollCallResult, shiftSettings); - // overtimePayAmount += CalculateOvertimePay(fridayOvertimeTimeSpan, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage); - // return overtimePayAmount; - // break; - // } - default: - break; - } - - return fridayPayAmount; - } - - public double InsurancePayCalculation(long employeeId, DateTime contractStart, DateTime contractEnd, - InsuranceDeduction insuranceDeduction, double monthySalary) - { - double insurancePayAmount = 0; - switch (insuranceDeduction.InsuranceDeductionType) - { - case InsuranceDeductionType.BasedOnLaborLaw: - - //farokhiChange - double familyAllowance = _yearlySalaryRepository.FamilyAllowance(employeeId, contractStart, contractEnd).MoneyToDouble(); - - double housingAllowance = _yearlySalaryRepository.HousingAllowance(contractEnd).MoneyToDouble(); - - double consumableItemsAllowance = _yearlySalaryRepository.ConsumableItems(contractEnd).MoneyToDouble(); - - double wage = _context.YearlySalaries.Include(x => x.YearlySalaryItemsList) - .FirstOrDefault(x => x.StartDate <= contractEnd && x.EndDate <= contractEnd).YearlySalaryItemsList - .FirstOrDefault(x => x.ItemName == "مزد روزانه").ItemValue; - - insurancePayAmount = (familyAllowance + housingAllowance + consumableItemsAllowance + wage) * 7 / 100; - break; - - case InsuranceDeductionType.PercentageOfSalary: - - double multiplier = insuranceDeduction.Value / 100; - - insurancePayAmount = monthySalary * multiplier; - break; - - case InsuranceDeductionType.Money: - - double baseAmount = insuranceDeduction.Value; - - insurancePayAmount = baseAmount; - break; - - case InsuranceDeductionType.None: - break; - - default: - insurancePayAmount = 0; - break; - } - - return insurancePayAmount; - } - - public static TimeSpan CalculateLeavePay(TimeSpan sumOfEmployeeShiftSpan, TimeSpan absentsTimeSpan, - int permittedLeaveDay, int monthDays, int contractDays, TimeSpan sumSpans, - double leaveValue, double minuteWage, DateTime startDate, DateTime endDate, out double leavePayAmount, out double absentsDeduction) - { - - - - - // زمان مجاز مرخصی - TimeSpan permittedLeaveTimeSpan = sumOfEmployeeShiftSpan * permittedLeaveDay; - - // زمان مرخصی مجاز برای یک روز - TimeSpan leaveTimePerDay = (permittedLeaveTimeSpan / monthDays); - - - //اگر ترک کار کرده بود - if (contractDays < monthDays) - { - permittedLeaveTimeSpan = leaveTimePerDay * contractDays; - } + // { + // double multiplier = customizeWorkshopEmployeeSettings.MarriedAllowance.Value / 100; + // maritalAllowance = dailyWage * multiplier; + // break; + // } + } + } - //اگر قراردادش کامل بود - else - { + #endregion - } + //شب کاری - //اختلاف غیبت و مرخصی - (TimeSpan Diffrence, AbsentOrLeave absentOrLeave) absentAndLeaveDifference; + #region NightWorkPay - //مقدار مبلغ مرخصی - leavePayAmount = 0; + double nightworkPayAmount = 0; + List rotatingResultList = RotatingShiftCheck(groupedRollCall); - //مقدار مبلغ غیبت - absentsDeduction = 0; + // شبکاری + TimeSpan nightWorks = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks)); - //#region SumLeaves + if (nightWorks > new TimeSpan()) + { + switch (customizeWorkshopEmployeeSettings.NightWorkPay.NightWorkingType) + { + case NightWorkType.MoneyPerHour: + { + var baseAmount = customizeWorkshopEmployeeSettings.NightWorkPay.Value; + var nightWorkMinutes = (int)(nightWorks).TotalMinutes; + nightworkPayAmount += nightWorkMinutes * (baseAmount / 60); + break; + } + case NightWorkType.PercentageFromSalary: + { + double multiplier = customizeWorkshopEmployeeSettings.NightWorkPay.Value / 100; + var nightWorkMinutes = (int)(nightWorks).TotalMinutes; + nightworkPayAmount += ((dailyWage * multiplier) / 60) * nightWorkMinutes; + break; + } + + + } + } + + #endregion + + //سنوات + + #region BaseYearsPay + + double baseYearsPayAmount = CalculateYearsPayAmount(employeeId, workshopId, monthySalary, contractStart, + contractEnd + , customizeWorkshopEmployeeSettings.BaseYearsPay, customizeWorkshopSettings.BaseYearsPayInEndOfYear, + customizeWorkshopSettings.MaxMonthDays); + + #endregion + + //حق اولاد + + #region FamilyAllowancePay + + double familyAllowancePay = 0; + switch (customizeWorkshopEmployeeSettings.FamilyAllowance.FamilyAllowanceType) + { + case FamilyAllowanceType.Money: + { + double baseAmount = customizeWorkshopEmployeeSettings.FamilyAllowance.Value; + familyAllowancePay = CalculateFamilyAllowancePayAmount(employeeId, baseAmount, contractEnd); + break; + } - //var usedLeavesCheckout = new TimeSpan(); - //foreach (var item in leaveList) - //{ - // var start = new DateTime(); - // var end = new DateTime(); - // start = item.StartLeaveGr < startDate ? startDate : item.StartLeaveGr; - // end = item.EndLeaveGr > endDate ? endDate : item.EndLeaveGr; - // if (item.PaidLeaveType == "روزانه") - // { - // var leaveSpan = (end - start); + case FamilyAllowanceType.Percentage: + { + double multiplier = customizeWorkshopEmployeeSettings.FamilyAllowance.Value / 100; + familyAllowancePay = + CalculateFamilyAllowancePayAmount(employeeId, multiplier * monthySalary, contractEnd); + break; + } + } + + #endregion + + #region Reward + + var rewardViewModels = RewardForCheckout(employeeId, workshopId, checkoutEnd, checkoutStart); + + double rewardPay = rewardViewModels.Sum(x => x.AmountDouble); + + #endregion + + #region LeavePay + + + + #endregion + + #region BonusesPay + + double bonusesPayAmount = 0; + + + if (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType != BonusesType.None) + { + switch (customizeWorkshopEmployeeSettings.BonusesPay.BonusesPayType) + { + case BonusesType.OneTimeOfSalary: + bonusesPayAmount = monthySalary; + break; + case BonusesType.TwoTimeOfSalary: + bonusesPayAmount = monthySalary * 2; + break; + case BonusesType.Money: + bonusesPayAmount = customizeWorkshopEmployeeSettings.BonusesPay.Value; + break; + case BonusesType.PercentageOfSalary: + bonusesPayAmount = (monthySalary * customizeWorkshopEmployeeSettings.BonusesPay.Value) / 100; + break; + } + + double bonusesPerMonth = bonusesPayAmount / 12; - // usedLeavesCheckout = usedLeavesCheckout.Add(leaveSpan); - // } - // else - // { - // var leavingHourses = TimeSpan.Parse(item.LeaveHourses); - // usedLeavesCheckout = usedLeavesCheckout.Add(leavingHourses); - // } + if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.YearlyPay) + { + var contractEndFarsi = Tools.FindeEndOfMonth(contractEnd.ToFarsi()); + if (monthOfCheckout == 12 && (contractEndFarsi.EndsWith("29")) || contractEndFarsi.EndsWith("30")) + { + } + else if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == + BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft) + { + TimeSpan bonusDuration; + DateTime startOfYear = new PersianCalendar().ToDateTime(yearOfCheckout, 1, 1, 0, 0, 0, 0); + if (startOfYear < leftWork.StartWorkDateGr) + bonusDuration = leftWorkDurationTimeSpan; + else + bonusDuration = leftWork.LeftWorkDateGr - startOfYear; + //ToDo: Check if should be absolute 365! + bonusesPayAmount = (bonusesPayAmount / 365) * bonusDuration.TotalDays; + } + else + { + bonusesPayAmount = 0; + } + } + else if (customizeWorkshopEmployeeSettings.BonusesPay.PaymentType == BonusesPaymentType.MonthlyPay) + { - //} - //#endregion + if (customizeWorkshopSettings.BonusesPaysInEndOfMonth == + BonusesPaysInEndOfYear.WhenEverEmployeeLeftWork && leftWork.HasLeft && contractDays < monthDays) + bonusesPayAmount = (bonusesPerMonth / contractEnd.CountPersianMonthDays()) * + contractDuration.TotalDays + 1; + + + bonusesPayAmount = bonusesPerMonth; + } + else + { + throw new InvalidDataException(); + } + } + + #endregion + + + #endregion + + #region LateToWork & EarlyExit + + //var lateToWorkEarlyExit = LateToWorkEarlyExit(groupedRollCall, shiftSettings, leaveList); + //foreach (var i in lateToWorkEarlyExit) + //{ + // Console.WriteLine(" start : " + i.StartSpan + " end : " + i.EndSpan + " spaning : " + i.Spanning + " Type : " + i.TypeOfSapn); + //} + + //var lateToWoks = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "LateToWork"); + //var earlyExits = lateToWorkEarlyExit.Where(x => x.TypeOfSapn == "EarlyExist"); + + //var lateToWork = new TimeSpan(lateToWoks.Sum(x => x.Spanning.Ticks)); + //var earlyExist = new TimeSpan(earlyExits.Sum(x => x.Spanning.Ticks)); + //var totalSpaning = new TimeSpan(lateToWorkEarlyExit.Sum(x => x.Spanning.Ticks)); + //Console.ForegroundColor = ConsoleColor.Yellow; + //Console.WriteLine(" LateToWork H : " + (int)lateToWork.TotalHours + " M : " + (int)(lateToWork.TotalMinutes % 60)); + //Console.WriteLine(" EarlyExist H : " + (int)earlyExist.TotalHours + " M : " + (int)(earlyExist.TotalMinutes % 60)); + //Console.WriteLine(" TotalSpaning H : " + (int)totalSpaning.TotalHours + " M : " + (int)(totalSpaning.TotalMinutes % 60)); + //Console.ResetColor(); + + //double earlyExitDeduction = 0; + //double lateToWorkDeduction = 0; + + //////محاسبه مزد روزانه به ازای هر دقیقه + ////double dailyWagePerMinute = + //// (customizeWorkshopEmployeeSettings.Salary / monthDays) / sumOfEmployeeShiftSpan.TotalMinutes; + + //if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType != EarlyExitType.None && earlyExist > new TimeSpan()) + //{ + // earlyExitDeduction = customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitType switch + // { + // EarlyExitType.Default => earlyExist.TotalMinutes * minuteWage, + + // EarlyExitType.MoneyPerMinute => earlyExist.TotalMinutes * customizeWorkshopEmployeeSettings.EarlyExit.Value, + + // _ => 0 + // }; + + //} + + + //if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType != LateToWorkType.None && lateToWork > new TimeSpan()) + //{ + // lateToWorkDeduction = customizeWorkshopEmployeeSettings.LateToWork.LateToWorkType switch + // { + // LateToWorkType.Default => lateToWork.TotalMinutes * minuteWage, + + // LateToWorkType.MoneyPerMinute => lateToWork.TotalMinutes * customizeWorkshopEmployeeSettings.LateToWork.Value, + + // _ => 0 + // }; + + //} + + //if (customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines.Any()) + //{ + // lateToWorkDeduction += + // (from lateToWorkTimeFine in customizeWorkshopEmployeeSettings.LateToWork.LateToWorkTimeFines + // let stepFine = lateToWoks.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(lateToWorkTimeFine.Minute)) + // select stepFine * lateToWorkTimeFine.FineMoney).Sum(); + //} + //if (customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines.Any()) + //{ + // earlyExitDeduction += + // (from earlyExitFine in customizeWorkshopEmployeeSettings.EarlyExit.EarlyExitTimeFines + // let stepFine = earlyExits.Count(x => x.Spanning.TotalMinutes >= Convert.ToInt32(earlyExitFine.Minute)) + // select stepFine * earlyExitFine.FineMoney).Sum(); + //} + + double lateToWorkDeduction = 0; + TimeSpan totalLateToWorkSpan = TimeSpan.Zero; + + + + if (customizeWorkshopEmployeeSettings.WorkshopShiftStatus == WorkshopShiftStatus.Rotating) + { + foreach (var rollCall in groupedRollCall) + { + + var rollCallShift = rollCall.TotalShiftDurationTimeSpan; + var dayMinuteWage = rollCallShift.TotalMinutes == 0 ? 0 : (dailyWage / rollCallShift.TotalMinutes); + (DateTime start, DateTime end)? firstShift = null; + foreach (var rc in rollCall.ShiftList.OrderBy(x => x.Start)) + { + double minutes = 0; + var shift = FindRotatingShift(rc.Start, rc.End, customizeWorkshopEmployeeSettings.CustomizeRotatingShifts); + if (firstShift == null) + { + firstShift = shift; + } + + + if (shift.start == firstShift.Value.start && shift.end == firstShift.Value.end) + { + minutes += rc.LateEntryDuration.TotalMinutes; + totalLateToWorkSpan = totalLateToWorkSpan.Add(rc.LateEntryDuration); + } + lateToWorkDeduction += dayMinuteWage * minutes; + } + + } + + + } + else + { + foreach (var rollCall in groupedRollCall) + { + + var rollCallShift = rollCall.TotalShiftDurationTimeSpan; + var dayMinuteWage = rollCallShift.TotalMinutes == 0 ? 0 : (dailyWage / rollCallShift.TotalMinutes); + var minutes = rollCall.TotalLateEntryDuration.TotalMinutes; + lateToWorkDeduction += dayMinuteWage * minutes; + totalLateToWorkSpan = totalLateToWorkSpan.Add(rollCall.TotalLateEntryDuration); + + } + } + + if (mandatoryDays == 31) + { + mandatoryDays = 30; + } + + + #endregion + + return new CustomizeCheckoutMandatoryViewModel + { + InsuranceDeduction = Math.Truncate(insuranceDeductionAmount), + FridayPay = Math.Truncate(fridayPayAmount), + OverTimePay = Math.Truncate(overtimePayAmount), + BaseYearsPay = Math.Truncate(baseYearsPayAmount), + NightWorkPay = Math.Truncate(nightworkPayAmount), + MarriedAllowance = Math.Truncate(maritalAllowancePay), + FamilyAllowance = Math.Truncate(familyAllowancePay), + LeavePay = Math.Truncate(leavePayAmount), + FineAbsenceDeduction = Math.Truncate(absentsDeductionAmount), + BonusesPay = Math.Truncate(bonusesPayAmount), + ContractEndFa = contractEnd.ToFarsi(), + ContractStartFa = contractStart.ToFarsi(), + EmployeeName = employee.FullName, + InstallmentDeduction = Math.Truncate(loanDeduction), + SalaryAidDeduction = Math.Truncate(salaryAidDeduction), + FineDeduction = Math.Truncate(fineDeduction), + RewardPay = Math.Truncate(rewardPay), + Month = monthOfCheckout, + Year = yearOfCheckout, + LateToWorkDeduction = Math.Truncate(lateToWorkDeduction), + EarlyExitDeduction = 0, + ShiftPay = 0, + TaxDeduction = 0, + EmployeeId = employeeId, + SumOfWorkingDays = totalDays.ToString(), + ContractNo = contract?.ContractNo ?? "-", + MonthlySalary = dailyWage * mandatoryDays, + PersonnelCode = personnelCode, + FineViewModels = fineViewModels, + InstallmentViewModels = loanInstallments, + SalaryAidViewModels = salaryAidViewModel, + RewardViewModels = rewardViewModels, + LateToWorkValue = totalLateToWorkSpan, + SettingSalary = customizeWorkshopEmployeeSettings.Salary, + DailyWage = dailyWage, + ShiftStatus = customizeWorkshopEmployeeSettings.WorkshopShiftStatus, + IrregularShift = customizeWorkshopEmployeeSettings.IrregularShift, + CustomizeRotatingShifts = customizeWorkshopEmployeeSettings.CustomizeRotatingShifts, + EmployeeSettingsShifts = customizeWorkshopEmployeeSettings.CustomizeWorkshopEmployeeSettingsShifts + .Select(x => (CustomizeSifts)x).ToList(), + }; + } + + private CustomizeCheckoutMandatoryViewModel CheckoutWithoutCalculationForKebabMahdi(long workshopId, long employeeId, DateTime contractStart, DateTime contractEnd) + { + var firstDayOfMonth = $"{(contractStart.ToFarsi())[..8]}/01".ToGeorgianDateTime(); + + CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings; + CustomizeWorkshopSettings customizeWorkshopSettings; + + var endFarvarding = new DateTime(2025, 4, 20); + if (contractStart > endFarvarding) + { + customizeWorkshopEmployeeSettings = _context.CustomizeWorkshopEmployeeSettings + .AsSplitQuery().AsNoTracking().FirstOrDefault(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId); + + customizeWorkshopSettings = _context.CustomizeWorkshopSettings.AsNoTracking().FirstOrDefault(x => x.WorkshopId == workshopId); + } + + else + { + customizeWorkshopEmployeeSettings = _testDbContext.CustomizeWorkshopEmployeeSettings + .AsSplitQuery().AsNoTracking().FirstOrDefault(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId); + + customizeWorkshopSettings = _testDbContext.CustomizeWorkshopSettings.AsNoTracking().FirstOrDefault(x => x.WorkshopId == workshopId); + + } + //ToDo handel exception if is null + var monthySalary = customizeWorkshopEmployeeSettings?.Salary ?? 0; + var monthDays = customizeWorkshopSettings.MaxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth + ? 30 + : firstDayOfMonth.CountMonthDays(); + double dailyWage = 0; + dailyWage = monthySalary / monthDays; + + var totalDays = (int)(contractEnd - contractStart).TotalDays + 1; + var mandatoryDays = totalDays; + + + #region SalaryAidDeduction + + var salaryAidViewModel = SalaryAidsForCheckout(employeeId, workshopId, contractEnd, contractEnd); + double salaryAidDeduction = salaryAidViewModel.Sum(x => x.AmountDouble); + + #endregion + + #region Loan + + var loanInstallments = LoanInstallmentForCheckout(employeeId, workshopId, contractStart, contractEnd); + + double loanDeduction = loanInstallments.Sum(x => x.AmountDouble); + + #endregion + + #region Fine + + var fineViewModels = FinesForCheckout(employeeId, workshopId, contractStart, contractEnd); + double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble()); + + #endregion + #region Reward + + var rewardViewModels = RewardForCheckout(employeeId, workshopId, contractStart, contractEnd); + + double rewardPay = rewardViewModels.Sum(x => x.AmountDouble); + #endregion + + + if (mandatoryDays == 31) + { + mandatoryDays = 30; + } + return new CustomizeCheckoutMandatoryViewModel() + { + MonthlySalary = dailyWage * mandatoryDays, + RewardPay = rewardPay, + RewardViewModels = rewardViewModels, + SalaryAidDeduction = salaryAidDeduction, + SalaryAidViewModels = salaryAidViewModel, + InstallmentDeduction = loanDeduction, + InstallmentViewModels = loanInstallments, + FineDeduction = fineDeduction, + FineViewModels = fineViewModels + }; + } + + + private List RewardForCheckout(long employeeId, long workshopId, DateTime checkoutEnd, DateTime checkoutStart) + { + return _context.Rewards.Where(x => + x.WorkshopId == workshopId && x.EmployeeId == employeeId && x.GrantDate <= checkoutEnd && + x.GrantDate >= checkoutStart).Select(x => new RewardViewModel + { + Title = x.Title, + Amount = x.Amount.ToMoney(), + AmountDouble = x.Amount, + Description = x.Description, + GrantDateGr = x.GrantDate, + GrantDateFa = x.GrantDate.ToFarsi(), + IsActive = x.IsActive, + Id = x.id + }).ToList(); + } + + private List FinesForCheckout(long employeeId, long workshopId, DateTime contractStart, DateTime contractEnd) + { + return _context.Fines.Where(x => + x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.FineDate >= contractStart && + x.FineDate <= contractEnd && x.IsActive == IsActive.True).Select(x => new FineViewModel() + { + IsActive = x.IsActive, + Amount = x.Amount.ToMoney(), + FineDate = x.FineDate.ToFarsi(), + Id = x.id, + Title = x.Title, + EmployeeId = x.EmployeeId, + CreationDate = x.CreationDate.ToFarsi() + }).ToList(); + } + + private List LoanInstallmentForCheckout(long employeeId, long workshopId, DateTime contractStart, DateTime contractEnd) + { + return _context.Loans + .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId) + .SelectMany(x => x.LoanInstallments) + .Where(i => i.InstallmentDate >= contractStart && i.InstallmentDate <= contractEnd && i.IsActive == IsActive.True) + .Select(x => new LoanInstallmentViewModel() + { + Id = x.Id, + Month = x.Month, + IsActive = x.IsActive, + Amount = x.AmountForMonth.ToMoney(), + Year = x.Year, + AmountDouble = x.AmountForMonth, + RemainingAmount = _context.Loans.SelectMany(l => l.LoanInstallments).Where(i => i.LoanId == x.LoanId && i.IsActive == IsActive.True && i.InstallmentDate > x.InstallmentDate) + .Sum(i => i.AmountForMonth).ToMoney(), + LoanAmount = _context.Loans.FirstOrDefault(l => l.id == x.LoanId).Amount.ToMoney() + }).ToList(); + } + + private List SalaryAidsForCheckout(long employeeId, long workshopId, DateTime checkoutStart, DateTime checkoutEnd) + { + return _context.SalaryAids + .Where(x => x.CalculationDate >= checkoutStart && x.CalculationDate <= checkoutEnd && x.EmployeeId == employeeId && x.WorkshopId == workshopId).Select(x => new SalaryAidViewModel() + { + Amount = x.Amount.ToMoney(), + AmountDouble = x.Amount, + SalaryAidDateTimeFa = x.SalaryAidDateTime.ToFarsi(), + SalaryAidDateTimeGe = x.SalaryAidDateTime, + CalculationDateTimeGe = x.CalculationDate, + CalculationDateTimeFa = x.CalculationDate.ToFarsi(), + Id = x.id + }).ToList(); + } + + private void CreateRewardForBirthDay(long employeeId, long workshopId, double amount, int month, int year, + DateTime contractStart) + { + var start = $"{year}/{month:00}/01".ToGeorgianDateTime(); + var end = $"{year}/{month:00}/01".FindeEndOfMonth().ToGeorgianDateTime(); + if (_context.Rewards.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId + && x.GrantDate >= start && x.GrantDate <= end + && x.RewardType == RewardType.CreatedByCheckoutForBirthDay) == false) + { + var reward = new Reward(employeeId, workshopId, amount, "", 0, UserType.System, contractStart, "هدیه تولد", + RewardType.CreatedByCheckoutForBirthDay); + _context.Rewards.Add(reward); + _context.SaveChanges(); + } + } + + private void CreateReward(long employeeId, long workshopId, double amount, int month, int year, + DateTime contractStart, RewardType type, string title) + { + var start = $"{year}/{month:00}/01".ToGeorgianDateTime(); + var end = $"{year}/{month:00}/01".FindeEndOfMonth().ToGeorgianDateTime(); + if (_context.Rewards.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId + && x.GrantDate >= start && x.GrantDate <= end + && x.RewardType == type) == false) + { + var reward = new Reward(employeeId, workshopId, amount, "", 0, UserType.System, contractStart, title, type); + _context.Rewards.Add(reward); + _context.SaveChanges(); + } + } + //private void CreateRewardForChahardah(long employeeId, long workshopId, double amount, int month, int year, + // DateTime contractStart) + //{ + // var start = $"{year}/{month:00}/01".ToGeorgianDateTime(); + // var end = $"{year}/{month:00}/01".FindeEndOfMonth().ToGeorgianDateTime(); + // if (_context.Rewards.Any(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId + // && x.GrantDate >= start && x.GrantDate <= end + // && x.RewardType == RewardType.ChahardahFarvardin) == false) + // { + // var reward = new Reward(employeeId, workshopId, amount, "", 0, contractStart, "بابت تعطیلی روز 14 فروردین", + // RewardType.ChahardahFarvardin); + // _context.Rewards.Add(reward); + // _context.SaveChanges(); + // } + //} + + + + + private TimeSpan CalculateIrregularOverTime(List rollCalls, TimeSpan employeeShiftSpan, WorkshopIrregularShifts irregularShifts, int mandatoryDays) + { + var sumOfRollCallTicks = rollCalls.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks); + + var sumRollCall = new TimeSpan(sumOfRollCallTicks); + var sumOfShift = employeeShiftSpan * mandatoryDays; + + if (sumOfShift > sumRollCall) + return TimeSpan.Zero; + + return sumRollCall - sumOfShift; + } + + + + public static TimeSpan CalculateIrregularShiftSpans(int totalDays, IrregularShift irregularShift) + { + //مبنای تقسیم که بر اساس جمع مقدار ساعت استراحت و ساعت کاری بدست میاد + double baseDivideTime = 0; + + //مقدار ساعت کارکرد در هر شیفت + double workTime = 0; + switch (irregularShift.WorkshopIrregularShifts) + { + case WorkshopIrregularShifts.TwelveThirtySix: + baseDivideTime = 48; + workTime = 12; + break; + case WorkshopIrregularShifts.TwelveTwentyFour: + baseDivideTime = 36; + workTime = 12; + break; + case WorkshopIrregularShifts.TwentyFourFortyEight: + baseDivideTime = 72; + workTime = 24; + break; + case WorkshopIrregularShifts.TwentyFourTwentyFour: + baseDivideTime = 48; + workTime = 24; + break; + } + //کل ساعاتی داخلش ممکنه کار کرده باشه + var workingHour = totalDays * 24; + + //مقدار تعداد خالصی که سر شیفت بوده است + int countOfWorking = (int)(workingHour / baseDivideTime); + + //باقی مونده تعدادی که سر شیفت بوده است + double fractionalPart = (workingHour / baseDivideTime) - countOfWorking; + + //مقدار ساعت خالصی که سر کار بوده است + TimeSpan sumOfEmployeeWorkingHours = TimeSpan.FromHours(countOfWorking * workTime); + + //مقدار احتمال سر کار بودن بر حسب باقی مونده تقسیم + var workingTimesDiff = fractionalPart * workTime; + + + workingTimesDiff = workingTimesDiff >= workTime ? workTime : workingTimesDiff; + + //جمع ساعات خالصی و احتمالی + sumOfEmployeeWorkingHours = sumOfEmployeeWorkingHours.Add(TimeSpan.FromHours(workingTimesDiff)); + + return sumOfEmployeeWorkingHours; + } + + public static TimeSpan CalculateIrregularShift(IrregularShift irregularShift) + { + var workingTime = irregularShift.WorkshopIrregularShifts switch + { + WorkshopIrregularShifts.TwelveThirtySix => TimeSpan.FromHours(6), + WorkshopIrregularShifts.TwelveTwentyFour => TimeSpan.FromHours(8), + WorkshopIrregularShifts.TwentyFourFortyEight => TimeSpan.FromHours(8), + WorkshopIrregularShifts.TwentyFourTwentyFour => TimeSpan.FromHours(12), + _ => new TimeSpan() + }; + return workingTime; + } + + + public static TimeSpan CalculateRotatingOvertime(ICollection rotatingShifts, + List rollCalls, int mandatoryDays, TimeSpan sumSpan) + { + TimeSpan mandatorySpan = TimeSpan.Zero; + foreach (var groupedRollCall in rollCalls) + { + var findRotatingShift = FindRotatingShift(groupedRollCall.ShiftList.Min(x => x.Start), + groupedRollCall.ShiftList.Max(x => x.End), rotatingShifts); + var span = findRotatingShift.end - findRotatingShift.start; + mandatorySpan += span; + } + + var leftDays = mandatoryDays - rollCalls.Count; + if (leftDays > 0) + { + + TimeSpan totalDuration = new TimeSpan(rotatingShifts.Sum(shift => Math.Abs(shift.EndTime.Ticks - shift.StartTime.Ticks))); + var averageDuration = totalDuration / rotatingShifts.Count; + mandatorySpan += averageDuration * leftDays; + } + + if (mandatorySpan < sumSpan) + { + return sumSpan - mandatorySpan; + } + return TimeSpan.Zero; + + } + + + #region CustomizeCheckoutCalculation + + public static double FridayPayCalculation(CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings, + List rollCallResult, double dailyWage, ICollection shiftSettings, double overtimePayAmount) + { + double fridayPayAmount = 0; + switch (customizeWorkshopEmployeeSettings.FridayPay.FridayPayType) + { + case (FridayPayType.MoneyPerFridayForDay): + { + int workedFridaysCount = CalculateFridayWorkingTotalDays(rollCallResult); + double baseAmount = customizeWorkshopEmployeeSettings.FridayPay.Value; + fridayPayAmount = baseAmount * workedFridaysCount; + break; + } + case (FridayPayType.MoneyPerFridayPerHour): + { + int workedFridaysMinutes = (int)CalculateFridayWorkingTimeSpan(rollCallResult).TotalMinutes; + double baseAmount = customizeWorkshopEmployeeSettings.FridayPay.Value; + fridayPayAmount = (baseAmount / 60) * workedFridaysMinutes; + break; + } + case (FridayPayType.PercentageFromSalaryPerHour): + { + int workedFridaysMinutes = (int)CalculateFridayWorkingTimeSpan(rollCallResult).TotalMinutes; + double percentageAmount = (customizeWorkshopEmployeeSettings.FridayPay.Value / 100 * dailyWage); + fridayPayAmount = (percentageAmount / 60) * workedFridaysMinutes; + break; + } + //case (FridayPayType.ExtraWorking): + // { + // var fridayOvertimeTimeSpan = CalculateFridayWorkingTimeSpanWithoutOvertime(rollCallResult, shiftSettings); + // overtimePayAmount += CalculateOvertimePay(fridayOvertimeTimeSpan, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage); + // return overtimePayAmount; + // break; + // } + default: + break; + } + + return fridayPayAmount; + } + + public double InsurancePayCalculation(long employeeId, DateTime contractStart, DateTime contractEnd, + InsuranceDeduction insuranceDeduction, double monthySalary) + { + double insurancePayAmount = 0; + switch (insuranceDeduction.InsuranceDeductionType) + { + case InsuranceDeductionType.BasedOnLaborLaw: + + //farokhiChange + double familyAllowance = _yearlySalaryRepository.FamilyAllowance(employeeId, contractStart, contractEnd).MoneyToDouble(); + + double housingAllowance = _yearlySalaryRepository.HousingAllowance(contractEnd).MoneyToDouble(); + + double consumableItemsAllowance = _yearlySalaryRepository.ConsumableItems(contractEnd).MoneyToDouble(); + + double wage = _context.YearlySalaries.Include(x => x.YearlySalaryItemsList) + .FirstOrDefault(x => x.StartDate <= contractEnd && x.EndDate <= contractEnd).YearlySalaryItemsList + .FirstOrDefault(x => x.ItemName == "مزد روزانه").ItemValue; + + insurancePayAmount = (familyAllowance + housingAllowance + consumableItemsAllowance + wage) * 7 / 100; + break; + + case InsuranceDeductionType.PercentageOfSalary: + + double multiplier = insuranceDeduction.Value / 100; + + insurancePayAmount = monthySalary * multiplier; + break; + + case InsuranceDeductionType.Money: + + double baseAmount = insuranceDeduction.Value; + + insurancePayAmount = baseAmount; + break; + + case InsuranceDeductionType.None: + break; + + default: + insurancePayAmount = 0; + break; + } + + return insurancePayAmount; + } + + public static TimeSpan CalculateLeavePay(TimeSpan sumOfEmployeeShiftSpan, TimeSpan absentsTimeSpan, + int permittedLeaveDay, int monthDays, int contractDays, TimeSpan sumSpans, + double leaveValue, double minuteWage, DateTime startDate, DateTime endDate, out double leavePayAmount, out double absentsDeduction) + { + + + + + // زمان مجاز مرخصی + TimeSpan permittedLeaveTimeSpan = sumOfEmployeeShiftSpan * permittedLeaveDay; + + // زمان مرخصی مجاز برای یک روز + TimeSpan leaveTimePerDay = (permittedLeaveTimeSpan / monthDays); + + + //اگر ترک کار کرده بود + if (contractDays < monthDays) + { + permittedLeaveTimeSpan = leaveTimePerDay * contractDays; + } - //if (permittedLeaveTimeSpan >= usedLeavesCheckout) - //{ - // permittedLeaveTimeSpan = permittedLeaveTimeSpan - usedLeavesCheckout; - // sumSpans += usedLeavesCheckout; - // usedLeavesCheckout = new TimeSpan(); - //} - //else - //{ - // sumSpans += permittedLeaveTimeSpan; - // absentsTimeSpan = (absentsTimeSpan - usedLeavesCheckout) - permittedLeaveTimeSpan; - // permittedLeaveTimeSpan = new TimeSpan(); - //} - - - - //اگر مقدار مجاز مرخصی بیشتر از غیبت یا مساوی باشد - if (permittedLeaveTimeSpan >= absentsTimeSpan) - { - //محاسبه مقدار باقی مانده مزد مرخصی - absentAndLeaveDifference.Diffrence = permittedLeaveTimeSpan - absentsTimeSpan; - absentAndLeaveDifference.absentOrLeave = AbsentOrLeave.LeavePay; - - //صفر کردن مقدار غیبت - absentsTimeSpan = new TimeSpan(0); - - ////برگرداندن ساعت کاری باقی مونده از مزد مرخصی به ساعت کاری - //sumSpans += absentAndLeaveDifference.Diffrence; - - //مقدار مزد مرخصی برای هرروز استفاده نشده - double leavePayPerDayWage = (leaveValue * (minuteWage * sumOfEmployeeShiftSpan.TotalMinutes)); - - if (permittedLeaveTimeSpan.TotalHours == 0) - return sumSpans; - - leavePayAmount = (leavePayPerDayWage / permittedLeaveTimeSpan.TotalMinutes) * absentAndLeaveDifference.Diffrence.TotalMinutes; - - } - //اگر مقدار غیبت بیشتر از مرخصی باشد - else - { - //محاسبه مقدار باقی مانده از غیبت - absentAndLeaveDifference.Diffrence = absentsTimeSpan - permittedLeaveTimeSpan; - absentAndLeaveDifference.absentOrLeave = AbsentOrLeave.AbsentDeduction; - - //صفر کردن مقدار مزد مرخصی - permittedLeaveTimeSpan = new TimeSpan(0); - permittedLeaveDay = 0; - - ////برگرداندن ساعت کاری باقی مونده از مزد مرخصی به ساعت کاری - //sumSpans += permittedLeaveTimeSpan; - - absentsDeduction = absentsTimeSpan.TotalMinutes * minuteWage; - - } - - return sumSpans; - } - - /// - /// محاسبه تاخیر در ورورد و تعجیل در خروج - /// - /// - /// - /// - public List LateToWorkEarlyExit(List groupedRollCall, ICollection shiftSettings, List leavList) - { - List lateToWorkEarlyExistSpannig = new List(); - - foreach (var day in groupedRollCall) - { - - foreach (var shift in shiftSettings) - { - //DateTime start = DateTime.Parse(shift.StartTime); - //DateTime end = DateTime.Parse(shift.EndTime); - DateTime startShift = new DateTime(day.CreationDate.Year, day.CreationDate.Month, day.CreationDate.Day, shift.StartTime.Hour, shift.StartTime.Minute, 0); - DateTime endShift = new DateTime(day.CreationDate.Year, day.CreationDate.Month, day.CreationDate.Day, shift.EndTime.Hour, shift.EndTime.Minute, 0); - if (shift.StartTime > shift.EndTime) - endShift = endShift.AddDays(1); - - //اگر در بازه شیف تعیین شده حضور غیاب داشت - - var hasRollCall = day.ShiftList.Where(x => - (x.Start <= startShift && x.End > startShift) || - (x.Start >= startShift && x.End <= endShift) || - (x.Start > startShift && x.End > endShift)).ToList(); - - if (!hasRollCall.Any())// اگر در بازه شیفت هیچ حضور غیابی نداشت - { - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = startShift, - EndSpan = endShift, - Spanning = (endShift - startShift), - TypeOfSapn = shift.Placement == ShiftPlacement.First ? "LateToWork" : "EarlyExist" - }); - } - else if (hasRollCall.Count() == 1) - { - var singleHasRollCall = hasRollCall.FirstOrDefault(); - if (singleHasRollCall != null && singleHasRollCall.Start > startShift && - singleHasRollCall.End >= endShift) - { - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = startShift, - EndSpan = singleHasRollCall.Start, - Spanning = (singleHasRollCall.Start - startShift), - TypeOfSapn = "LateToWork" - }); - } - else if (singleHasRollCall != null && singleHasRollCall.Start <= startShift && - singleHasRollCall.End < endShift) - { - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = singleHasRollCall.End, - EndSpan = endShift, - Spanning = (endShift - singleHasRollCall.End), - TypeOfSapn = "EarlyExist" - }); - } - else if (singleHasRollCall != null && singleHasRollCall.Start > startShift && - singleHasRollCall.End < endShift) - { - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = startShift, - EndSpan = singleHasRollCall.Start, - Spanning = (singleHasRollCall.Start - startShift), - TypeOfSapn = "LateToWork" - }); - - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = singleHasRollCall.End, - EndSpan = endShift, - Spanning = (endShift - singleHasRollCall.End), - TypeOfSapn = "EarlyExist" - }); - } - } - else if (hasRollCall.Count() > 1) - { - var multiHasRollCall = hasRollCall.OrderBy(x => x.Start); - var firstRollcall = multiHasRollCall.First(); - var lastRollCall = multiHasRollCall.Last(); - - if (firstRollcall.Start > startShift && - firstRollcall.End >= endShift) - { - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = startShift, - EndSpan = firstRollcall.Start, - Spanning = (firstRollcall.Start - startShift), - TypeOfSapn = "LateToWork" - }); - } - - if (lastRollCall.Start <= startShift && - lastRollCall.End < endShift) - { - lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() - { - StartSpan = lastRollCall.End, - EndSpan = endShift, - Spanning = (endShift - lastRollCall.End), - TypeOfSapn = "EarlyExist" - }); - } - } - } - } - - leavList = leavList.Where(x => x.PaidLeaveType == "ساعتی").ToList(); - // اگر تاخیر یا تعجیل به دلیل مرخصی ساعتی بود حساب نشود - if (leavList.Count > 0 && lateToWorkEarlyExistSpannig.Count > 0) - { - foreach (var el in lateToWorkEarlyExistSpannig.ToList()) - { - var hasLeve = leavList.Any(x => - (x.StartLeaveGr <= el.StartSpan && x.EndLeaveGr > el.StartSpan) || - (x.StartLeaveGr >= el.StartSpan && x.EndLeaveGr <= el.EndSpan) || - (x.StartLeaveGr > el.StartSpan && x.EndLeaveGr > el.EndSpan)); - if (hasLeve) - lateToWorkEarlyExistSpannig.Remove(el); - } - - } - - - return lateToWorkEarlyExistSpannig; - } - - #region Pooya - - public double CalculateFamilyAllowancePayAmount(long employeeId, double basePay, DateTime contractEnd) - { - int underageChildrenCount = _context.EmployeeChildrenSet.Where(x => x.EmployeeId == employeeId && - x.DateOfBirth.AddYears(18) > contractEnd).Count(); - return basePay * underageChildrenCount; - } - - //Deprecated - private TimeSpan CalculateOvertimeTimeSpanWithThreshold(List rollCalls, - ICollection shiftSettings, int overtimeThresholdMinutes) - { - - var mandatoryTotalTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks)); - mandatoryTotalTimeSpan += new TimeSpan(0, overtimeThresholdMinutes, 0); - - var rollCallsTimeSpans = rollCalls.Select(x => x.EndDate.Value - x.StartDate.Value).Where(x => x > mandatoryTotalTimeSpan).ToList(); - var rollCallTotalTimeSpan = new TimeSpan(rollCallsTimeSpans.Sum(x => x.Ticks)); - - if (rollCallTotalTimeSpan < mandatoryTotalTimeSpan) - return TimeSpan.Zero; - return rollCallTotalTimeSpan - mandatoryTotalTimeSpan; - } - - #region سنوات - - /// - /// فرمول اصلی محاسبه سنوات برای پرسنل در بازه زمانی با تنظیمات پیشرفته - /// - /// حقوق ماهیانه پرسنل - /// تنظیمات سنوات - /// تنظیم مربوط به پرداخت هنگام ترک کار - public double CalculateYearsPayAmount(long employeeId, long workshopId, double monthlySalary, DateTime contractStart, DateTime contractEnd, - BaseYearsPay baseYearsSettings, BaseYearsPayInEndOfYear payOnLeave, MaxMonthDays maxMonthDays) - { - double baseYearPayAmount = 0; - - - var leftWorks = _context.LeftWorkList - .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId && - x.LeftWorkDate.Date.AddDays(-1) >= contractStart && x.StartWorkDate.Date <= contractEnd).ToList(); - - if (!leftWorks.Any()) - return 0; - - int daysWorked = (int)new TimeSpan(leftWorks.Select(x => new - { - Start = x.StartWorkDate < contractStart ? contractStart : x.StartWorkDate - , - End = x.LeftWorkDate.AddDays(-1) > contractEnd ? contractEnd : x.LeftWorkDate.AddDays(-1) - }).Sum(x => (x.End - x.Start).Ticks)).TotalDays + 1; - - bool hasLeftWork = leftWorks.MaxBy(x => x.LeftWorkDate).LeftWorkDate.AddDays(-1) < contractEnd; - - //محاسبه سنوات سالیانه - switch (baseYearsSettings.BaseYearsPayType) - { - case BaseYearsPayType.PercentageOfSalary: - { - baseYearPayAmount = monthlySalary * baseYearsSettings.Value / 100; - break; - } - case BaseYearsPayType.Money: - { - baseYearPayAmount = baseYearsSettings.Value; - break; - } - case BaseYearsPayType.None: - { - return 0; - } - } - - //در صورت ترک کار - if (hasLeftWork) - - { - switch (payOnLeave) - { - //اگر سنوات در آخر سال تعلق می گیرد ترک کار قبل از پایان دوره موجب صفر شدن آن میشود - case BaseYearsPayInEndOfYear.EndOfYear: - return 0; - - //اگر هنگام ترک کار سنوات تعلق می گیرد - case BaseYearsPayInEndOfYear.WhenEverEmployeeLeftWork: - { - - //بر اساس نوع پرداخت سالیانه یا ماهیانه سنوات محاسبه می گردد - switch (baseYearsSettings.PaymentType) - { - case BaseYearsPaymentType.MonthlyPay: - { - return CalculateYearsPayMonthlyByDays(baseYearPayAmount, daysWorked, contractStart.CountPersianMonthDays(), maxMonthDays); - } - case BaseYearsPaymentType.YearlyPay: - { - - return CalculateYearsPayYearlyByDays(baseYearPayAmount, daysWorked); - } - default: - return 0; - } - } - } - } - - //در صورت عدم ترک کار - switch (baseYearsSettings.PaymentType) - { - case BaseYearsPaymentType.MonthlyPay: - { - return CalculateYearsPayMonthlyByDays(baseYearPayAmount, daysWorked, contractStart.CountPersianMonthDays(), maxMonthDays); - } - case BaseYearsPaymentType.YearlyPay: - { - string contractEndFa = contractEnd.ToFarsi(); - bool isCheckoutForEsfand = contractEndFa.Substring(5, 2) == "12"; - bool isContractEndOfMonth = contractEndFa.FindeEndOfMonth() == contractEndFa; - - //اگر آخر ماه نبود یا اسفند نبود سنوات سالیانه محاسبه نمی گردد - if (isContractEndOfMonth == false || isCheckoutForEsfand == false) - return 0; - - return CalculateYearsPayYearlyByDays(baseYearPayAmount, daysWorked); - } - default: - return 0; - } - - } - - /// - /// محاسبه سنوات ماهیانه بر اساس روز های کارکرد - /// - /// سنوات در کل سال - /// روز های کارکرد - /// تعداد روز های ماه - public static double CalculateYearsPayMonthlyByDays(double baseYears, int daysWorked, int totalDaysInMonth, MaxMonthDays maxMonthDays) - { - daysWorked = maxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth && daysWorked > 30 ? 30 : daysWorked; - totalDaysInMonth = maxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth ? 30 : totalDaysInMonth; - return baseYears / 12 / totalDaysInMonth * daysWorked; - } - - /// - /// محاسبه سنوات سالیانه بر اساس روز های کارکرد - /// - /// سنوات در کل سال - /// روز های کارکرد - /// - /// - public static double CalculateYearsPayYearlyByDays(double baseYears, int daysWorked) - { - return baseYears / 365 * daysWorked; - } - #endregion - - - - //TODO: this must be updated with Mahan's method for leaves - /// - /// محاسبه مدت اضافه کاری - /// - public static TimeSpan CalculateOvertimeTimeSpan(List rollCalls, - ICollection shiftSettings, TimeOnly employeeOffSet) - { - - //for (DateTime offset = start; offset <= end; offset.AddDays(1)) - //{ - // DayOfWeek dayOfWeek = offset.DayOfWeek; - // switch (dayOfWeek) - // { - // case DayOfWeek.Thursday: - // shifts.Add(new ShiftViewModel { Start = offset.AddHours(9), End = offset.AddHours(14) }); - // break; - // case DayOfWeek.Friday: - // break; - // default: - // shifts.Add(new ShiftViewModel { Start = offset.AddHours(8), End = offset.AddHours(16) }); - // break; - // } - //} - - //if (!rollCalls.Any()) - // return TimeSpan.Zero; - //var startRollCall = rollCalls.MinBy(x => x.StartDate!.Value).StartDate!.Value; - //var endRollCall = rollCalls.Max(x => x.EndDate)!.Value; - - //DateTime startDateTime = new DateTime(DateOnly.FromDateTime(startRollCall), employeeOffSet); - //DateTime endDateTime = new DateTime(DateOnly.FromDateTime(endRollCall), employeeOffSet); - //endDateTime = endDateTime == startDateTime ? endDateTime.AddDays(1) : endDateTime; - - - var mandatoryPerDayTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks)); - - //bool isFirst = true; - - //var sumOfOverTime = TimeSpan.Zero; - - //for (var startDateOffset = startDateTime; startDateOffset <= endDateTime; startDateOffset = startDateOffset.AddDays(1)) - //{ - // IEnumerable rollCallViewModels; - // var startPeriod = startDateOffset; - // var endPeriod = startDateOffset.AddDays(1); - - // if (isFirst) - // { - // rollCallViewModels = rollCalls - // .Where(x => x.StartDate.Value > startPeriod.Date && x.EndDate.Value <= endPeriod); - // isFirst = false; - // } - // else - // { - // rollCallViewModels = rollCalls - // .Where(x => x.StartDate.Value > startPeriod && x.EndDate.Value <= endPeriod); - // } - - // var sum = rollCallViewModels.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks); - // var rollCallTimeSpan = new TimeSpan(sum); - // if (rollCallTimeSpan > mandatoryPerDayTimeSpan) - // { - // var overTime = rollCallTimeSpan - mandatoryPerDayTimeSpan; - // sumOfOverTime = sumOfOverTime.Add(overTime); - // } - //} - - - //return sumOfOverTime; - - - var groupedRollCalls = rollCalls.GroupBy(x => x.StartDate!.Value.Date); - - - var rollCallsTimeSpans = groupedRollCalls.Where(x => - x.Sum(y => (y.EndDate!.Value - y.StartDate!.Value).Ticks) > mandatoryPerDayTimeSpan.Ticks) - .Select(x => x.Sum(y => (y.EndDate!.Value - y.StartDate!.Value).Ticks)).ToList(); - - var daysCount = rollCallsTimeSpans.Count(); - - var totalMandatoryTotalTimeSpan = mandatoryPerDayTimeSpan * daysCount; - var rollCallTotalTimeSpan = new TimeSpan(rollCallsTimeSpans.Sum(x => x)); - - if (rollCallTotalTimeSpan < totalMandatoryTotalTimeSpan) - return TimeSpan.Zero; - return rollCallTotalTimeSpan - totalMandatoryTotalTimeSpan; - } - - - public static TimeSpan CalculateOvertimeSpanWithSumSpan(TimeSpan sumSpan, int mandatoryDays, - ICollection shiftSettings) - { - var mandatoryPerDayTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks)); - var mandatoryWorkingTimeSpan = mandatoryPerDayTimeSpan * mandatoryDays; - if (mandatoryWorkingTimeSpan > sumSpan) - return TimeSpan.Zero; - - return sumSpan - mandatoryWorkingTimeSpan; - - } - - /// - /// محاسبه مبلغ اضافه کاری با استفاده از تنظیمات - /// - /// مدت اضافه کاری - /// تنظیمات اضافه کاری - /// مزد روزانه - /// - public static double CalculateOvertimePay(TimeSpan overtimeTimeSpan, OverTimePay overTimePaySettings, double dailyWage) - { - double baseAmount = overTimePaySettings.Value; - double result = 0; - switch (overTimePaySettings.OverTimePayType) - { - - case OverTimePayType.None: - break; - - - case OverTimePayType.MoneyPerHour: - { - int totalMinutes = (int)overtimeTimeSpan.TotalMinutes; - result = totalMinutes * (baseAmount / 60); - break; - } - - - case OverTimePayType.PercentagePerHourOfSalary: - { - int totalMinutes = (int)overtimeTimeSpan.TotalMinutes; - double multiplier = overTimePaySettings.Value / 100; - result = ((dailyWage * multiplier) / 60) * totalMinutes; - break; - } - - } - return result; - } - - /// - /// محاسبه مدت جمعه کاری بدون در نظر گرفتن اضافه کاری - /// - public static TimeSpan CalculateFridayWorkingTimeSpanWithoutOvertime(List rollCallsList, ICollection shiftSettings) - { - var _rollCallsList = rollCallsList; - _rollCallsList = _rollCallsList.Where(x => x.StartDate.Value.DayOfWeek == DayOfWeek.Friday || - x.EndDate.Value.DayOfWeek == DayOfWeek.Friday || - (x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday && x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday)).ToList(); - - var preprocessedRollCalls = _rollCallsList.Select(x => - new RollCallViewModel - { - StartDate = x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday ? x.StartDate.Value.AddDays(1).Date : x.StartDate.Value - , - EndDate = x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday ? x.EndDate.Value.Date : x.EndDate.Value - }).ToList(); - - //var timeSpan = new TimeSpan(preprocessedRollCalls.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks)); - - var extraWorkingTimeSpan = CalculateOvertimeTimeSpan(preprocessedRollCalls, shiftSettings, new TimeOnly()); - var rollCallTimeSpan = CalculateFridayWorkingTimeSpan(preprocessedRollCalls); - - if (rollCallTimeSpan <= extraWorkingTimeSpan) - return TimeSpan.Zero; - return rollCallTimeSpan - extraWorkingTimeSpan; - - - } - - /// - /// محاسبه مدت جمعه کاری - /// - public static TimeSpan CalculateFridayWorkingTimeSpan(List rollCallsList) - { - var _rollCallsList = rollCallsList; - _rollCallsList = _rollCallsList.Where(x => x.StartDate.Value.DayOfWeek == DayOfWeek.Friday || - x.EndDate.Value.DayOfWeek == DayOfWeek.Friday || - (x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday && x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday)).ToList(); - - var preprocessedRollCalls = _rollCallsList.Select(x => - new - { - Start = x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday ? x.StartDate.Value.AddDays(1).Date : x.StartDate.Value - , - End = x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday ? x.EndDate.Value.Date : x.EndDate.Value - }).ToList(); - - var timeSpan = new TimeSpan(preprocessedRollCalls.Sum(x => (x.End - x.Start).Ticks)); - return timeSpan; - } - - /// - /// محاسبه روز های جمعه کاری - /// - public static int CalculateFridayWorkingTotalDays(List rollCallsList) - { - var _rollCallsList = rollCallsList; - _rollCallsList = _rollCallsList.Where(x => x.StartDate.Value.DayOfWeek == DayOfWeek.Friday || - x.EndDate.Value.DayOfWeek == DayOfWeek.Friday || - (x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday && x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday)).ToList(); - - var preprocessedRollCalls = _rollCallsList.Select(x => - new - { - Start = x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday ? x.StartDate.Value.AddDays(1).Date : x.StartDate.Value - , - End = x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday ? x.StartDate.Value.Date : x.EndDate.Value, - ShiftDate = x.ShiftDate - }).ToList(); - - int fridaysCount = preprocessedRollCalls.GroupBy(x => x.ShiftDate).Count(); - return fridaysCount; - } - - #endregion - - #endregion - - - public static (DateTime start, DateTime end) FindRotatingShift(DateTime startRollCall, DateTime endRollCall, - ICollection rotatingShifts) - { - DateTime startDate = startRollCall.Date; - DateTime endDate = endRollCall.Date; - - - - DateTime startEntryWithDate = startDate.Add(startRollCall.TimeOfDay); - DateTime endEntryWithDate = endDate.Add(endRollCall.TimeOfDay); - - DateTime twoHourBeforeStart = startEntryWithDate.AddHours(-2); - DateTime twoHourAfterStart = startEntryWithDate.AddHours(2); - DateTime twoHourBeforeEnd = endEntryWithDate.AddHours(-2); - DateTime twoHourAfterEnd = endEntryWithDate.AddHours(2); - - - var shiftDateTimes = rotatingShifts.SelectMany(shift => - { - var shifts = new List<(DateTime Start, DateTime End)>(); - for (int i = -1; i <= 1; i++) - { - var shiftStart = startDate.AddDays(i).Date; - shiftStart = shiftStart.Add(shift.StartTime.ToTimeSpan()); - var shiftEnd = shift.StartTime < shift.EndTime - ? startDate.AddDays(i).Date.Add(shift.EndTime.ToTimeSpan()) - : startDate.AddDays(i + 1).Date.Add(shift.EndTime.ToTimeSpan()); - shifts.Add((shiftStart, shiftEnd)); - } - - return shifts; - }).ToList(); - - #region مقایسه شروع حضور غیاب با شیفت - - //var startFilteredTimes = shiftDateTimes.Where(shift => - // (twoHourBeforeStart <= shift.Start && twoHourAfterStart >= shift.Start) || - // (twoHourBeforeStart <= shift.End && twoHourAfterStart >= shift.End)).ToList(); - - //if (startFilteredTimes.Count == 0) - //{ - // startFilteredTimes = shiftDateTimes; - //} - //else if (startFilteredTimes.Count == 1) - //{ - // var startChosenShift = startFilteredTimes.First(); - - // if (startChosenShift.End < startChosenShift.Start) - // startChosenShift.End = startChosenShift.End.AddDays(1); - - // return startChosenShift; - //} - - - //#endregion - - //#region مقایسه پایان حضورغیاب با شیفت - - //var endFilteredTimes = shiftDateTimes.Where(shift => - // (twoHourBeforeEnd <= shift.Start && twoHourAfterEnd >= shift.Start) || - // (twoHourBeforeEnd <= shift.End && twoHourAfterEnd >= shift.End)).ToList(); - //if (endFilteredTimes.Count == 0) - //{ - // endFilteredTimes = startFilteredTimes; - //} - //else if (endFilteredTimes.Count == 1) - //{ - // var endChosenShift = endFilteredTimes.First(); - // return endChosenShift; - //} - - #endregion - - #region اشتراک حضور غیاب و شیفت - - var overlapShifts = shiftDateTimes - .Select(shift => new - { - Shift = shift, - Overlap = new TimeSpan(Math.Max(0, - Math.Min(shift.End.Ticks, endRollCall.Ticks) - - Math.Max(shift.Start.Ticks, startRollCall.Ticks))), - // زمان حضور فرد در شیفت (مجموع Overlap با شیفت) - TotalTimeInShift = new TimeSpan(Math.Max(0, - Math.Min(shift.End.Ticks, endRollCall.Ticks) - - Math.Max(shift.Start.Ticks, startRollCall.Ticks))), - StartDistance = Math.Abs((shift.Start - startRollCall).Ticks), - EndDistance = Math.Abs((shift.End - endRollCall).Ticks), - TotalDistance = Math.Abs((shift.Start - startRollCall).Ticks) + Math.Abs((shift.End - endRollCall).Ticks) - }) - .OrderByDescending(s => s.TotalTimeInShift) // 1. بیشترین زمان حضور فرد - .ThenByDescending(s => s.Overlap) // 2. بیشترین Overlap - .ThenBy(s => s.TotalDistance) - .ThenBy(s => s.StartDistance) - .ThenBy(x => x.EndDistance); // 3. اگر برابر بود، Start نزدیک‌تر - - var overlapChosenShift = overlapShifts.First(); - var end = overlapChosenShift.Shift.End; - if (overlapChosenShift.Shift.End < overlapChosenShift.Shift.Start) - end = overlapChosenShift.Shift.End.AddDays(1); - - - return (overlapChosenShift.Shift.Start, end); - - #endregion - } - #endregion + //اگر قراردادش کامل بود + else + { + + } + + //اختلاف غیبت و مرخصی + (TimeSpan Diffrence, AbsentOrLeave absentOrLeave) absentAndLeaveDifference; + + //مقدار مبلغ مرخصی + leavePayAmount = 0; + + //مقدار مبلغ غیبت + absentsDeduction = 0; + + //#region SumLeaves + + //var usedLeavesCheckout = new TimeSpan(); + //foreach (var item in leaveList) + //{ + // var start = new DateTime(); + // var end = new DateTime(); + // start = item.StartLeaveGr < startDate ? startDate : item.StartLeaveGr; + // end = item.EndLeaveGr > endDate ? endDate : item.EndLeaveGr; + // if (item.PaidLeaveType == "روزانه") + // { + // var leaveSpan = (end - start); + + // usedLeavesCheckout = usedLeavesCheckout.Add(leaveSpan); + // } + // else + // { + // var leavingHourses = TimeSpan.Parse(item.LeaveHourses); + // usedLeavesCheckout = usedLeavesCheckout.Add(leavingHourses); + // } + + //} + + //#endregion + + //if (permittedLeaveTimeSpan >= usedLeavesCheckout) + //{ + // permittedLeaveTimeSpan = permittedLeaveTimeSpan - usedLeavesCheckout; + // sumSpans += usedLeavesCheckout; + // usedLeavesCheckout = new TimeSpan(); + //} + //else + //{ + // sumSpans += permittedLeaveTimeSpan; + // absentsTimeSpan = (absentsTimeSpan - usedLeavesCheckout) - permittedLeaveTimeSpan; + // permittedLeaveTimeSpan = new TimeSpan(); + //} + + + + //اگر مقدار مجاز مرخصی بیشتر از غیبت یا مساوی باشد + if (permittedLeaveTimeSpan >= absentsTimeSpan) + { + //محاسبه مقدار باقی مانده مزد مرخصی + absentAndLeaveDifference.Diffrence = permittedLeaveTimeSpan - absentsTimeSpan; + absentAndLeaveDifference.absentOrLeave = AbsentOrLeave.LeavePay; + + //صفر کردن مقدار غیبت + absentsTimeSpan = new TimeSpan(0); + + ////برگرداندن ساعت کاری باقی مونده از مزد مرخصی به ساعت کاری + //sumSpans += absentAndLeaveDifference.Diffrence; + + //مقدار مزد مرخصی برای هرروز استفاده نشده + double leavePayPerDayWage = (leaveValue * (minuteWage * sumOfEmployeeShiftSpan.TotalMinutes)); + + if (permittedLeaveTimeSpan.TotalHours == 0) + return sumSpans; + + leavePayAmount = (leavePayPerDayWage / permittedLeaveTimeSpan.TotalMinutes) * absentAndLeaveDifference.Diffrence.TotalMinutes; + + } + //اگر مقدار غیبت بیشتر از مرخصی باشد + else + { + //محاسبه مقدار باقی مانده از غیبت + absentAndLeaveDifference.Diffrence = absentsTimeSpan - permittedLeaveTimeSpan; + absentAndLeaveDifference.absentOrLeave = AbsentOrLeave.AbsentDeduction; + + //صفر کردن مقدار مزد مرخصی + permittedLeaveTimeSpan = new TimeSpan(0); + permittedLeaveDay = 0; + + ////برگرداندن ساعت کاری باقی مونده از مزد مرخصی به ساعت کاری + //sumSpans += permittedLeaveTimeSpan; + + absentsDeduction = absentsTimeSpan.TotalMinutes * minuteWage; + + } + + return sumSpans; + } + + /// + /// محاسبه تاخیر در ورورد و تعجیل در خروج + /// + /// + /// + /// + public List LateToWorkEarlyExit(List groupedRollCall, ICollection shiftSettings, List leavList) + { + List lateToWorkEarlyExistSpannig = new List(); + + foreach (var day in groupedRollCall) + { + + foreach (var shift in shiftSettings) + { + //DateTime start = DateTime.Parse(shift.StartTime); + //DateTime end = DateTime.Parse(shift.EndTime); + DateTime startShift = new DateTime(day.CreationDate.Year, day.CreationDate.Month, day.CreationDate.Day, shift.StartTime.Hour, shift.StartTime.Minute, 0); + DateTime endShift = new DateTime(day.CreationDate.Year, day.CreationDate.Month, day.CreationDate.Day, shift.EndTime.Hour, shift.EndTime.Minute, 0); + if (shift.StartTime > shift.EndTime) + endShift = endShift.AddDays(1); + + //اگر در بازه شیف تعیین شده حضور غیاب داشت + + var hasRollCall = day.ShiftList.Where(x => + (x.Start <= startShift && x.End > startShift) || + (x.Start >= startShift && x.End <= endShift) || + (x.Start > startShift && x.End > endShift)).ToList(); + + if (!hasRollCall.Any())// اگر در بازه شیفت هیچ حضور غیابی نداشت + { + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = startShift, + EndSpan = endShift, + Spanning = (endShift - startShift), + TypeOfSapn = shift.Placement == ShiftPlacement.First ? "LateToWork" : "EarlyExist" + }); + } + else if (hasRollCall.Count() == 1) + { + var singleHasRollCall = hasRollCall.FirstOrDefault(); + if (singleHasRollCall != null && singleHasRollCall.Start > startShift && + singleHasRollCall.End >= endShift) + { + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = startShift, + EndSpan = singleHasRollCall.Start, + Spanning = (singleHasRollCall.Start - startShift), + TypeOfSapn = "LateToWork" + }); + } + else if (singleHasRollCall != null && singleHasRollCall.Start <= startShift && + singleHasRollCall.End < endShift) + { + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = singleHasRollCall.End, + EndSpan = endShift, + Spanning = (endShift - singleHasRollCall.End), + TypeOfSapn = "EarlyExist" + }); + } + else if (singleHasRollCall != null && singleHasRollCall.Start > startShift && + singleHasRollCall.End < endShift) + { + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = startShift, + EndSpan = singleHasRollCall.Start, + Spanning = (singleHasRollCall.Start - startShift), + TypeOfSapn = "LateToWork" + }); + + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = singleHasRollCall.End, + EndSpan = endShift, + Spanning = (endShift - singleHasRollCall.End), + TypeOfSapn = "EarlyExist" + }); + } + } + else if (hasRollCall.Count() > 1) + { + var multiHasRollCall = hasRollCall.OrderBy(x => x.Start); + var firstRollcall = multiHasRollCall.First(); + var lastRollCall = multiHasRollCall.Last(); + + if (firstRollcall.Start > startShift && + firstRollcall.End >= endShift) + { + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = startShift, + EndSpan = firstRollcall.Start, + Spanning = (firstRollcall.Start - startShift), + TypeOfSapn = "LateToWork" + }); + } + + if (lastRollCall.Start <= startShift && + lastRollCall.End < endShift) + { + lateToWorkEarlyExistSpannig.Add(new LateToWorkEarlyExistSpannig() + { + StartSpan = lastRollCall.End, + EndSpan = endShift, + Spanning = (endShift - lastRollCall.End), + TypeOfSapn = "EarlyExist" + }); + } + } + } + } + + leavList = leavList.Where(x => x.PaidLeaveType == "ساعتی").ToList(); + // اگر تاخیر یا تعجیل به دلیل مرخصی ساعتی بود حساب نشود + if (leavList.Count > 0 && lateToWorkEarlyExistSpannig.Count > 0) + { + foreach (var el in lateToWorkEarlyExistSpannig.ToList()) + { + var hasLeve = leavList.Any(x => + (x.StartLeaveGr <= el.StartSpan && x.EndLeaveGr > el.StartSpan) || + (x.StartLeaveGr >= el.StartSpan && x.EndLeaveGr <= el.EndSpan) || + (x.StartLeaveGr > el.StartSpan && x.EndLeaveGr > el.EndSpan)); + if (hasLeve) + lateToWorkEarlyExistSpannig.Remove(el); + } + + } + + + return lateToWorkEarlyExistSpannig; + } + + #region Pooya + + public double CalculateFamilyAllowancePayAmount(long employeeId, double basePay, DateTime contractEnd) + { + int underageChildrenCount = _context.EmployeeChildrenSet.Where(x => x.EmployeeId == employeeId && + x.DateOfBirth.AddYears(18) > contractEnd).Count(); + return basePay * underageChildrenCount; + } + + //Deprecated + private TimeSpan CalculateOvertimeTimeSpanWithThreshold(List rollCalls, + ICollection shiftSettings, int overtimeThresholdMinutes) + { + + var mandatoryTotalTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks)); + mandatoryTotalTimeSpan += new TimeSpan(0, overtimeThresholdMinutes, 0); + + var rollCallsTimeSpans = rollCalls.Select(x => x.EndDate.Value - x.StartDate.Value).Where(x => x > mandatoryTotalTimeSpan).ToList(); + var rollCallTotalTimeSpan = new TimeSpan(rollCallsTimeSpans.Sum(x => x.Ticks)); + + if (rollCallTotalTimeSpan < mandatoryTotalTimeSpan) + return TimeSpan.Zero; + return rollCallTotalTimeSpan - mandatoryTotalTimeSpan; + } + + #region سنوات + + /// + /// فرمول اصلی محاسبه سنوات برای پرسنل در بازه زمانی با تنظیمات پیشرفته + /// + /// حقوق ماهیانه پرسنل + /// تنظیمات سنوات + /// تنظیم مربوط به پرداخت هنگام ترک کار + public double CalculateYearsPayAmount(long employeeId, long workshopId, double monthlySalary, DateTime contractStart, DateTime contractEnd, + BaseYearsPay baseYearsSettings, BaseYearsPayInEndOfYear payOnLeave, MaxMonthDays maxMonthDays) + { + double baseYearPayAmount = 0; + + + var leftWorks = _context.LeftWorkList + .Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId && + x.LeftWorkDate.Date.AddDays(-1) >= contractStart && x.StartWorkDate.Date <= contractEnd).ToList(); + + if (!leftWorks.Any()) + return 0; + + int daysWorked = (int)new TimeSpan(leftWorks.Select(x => new + { + Start = x.StartWorkDate < contractStart ? contractStart : x.StartWorkDate + , + End = x.LeftWorkDate.AddDays(-1) > contractEnd ? contractEnd : x.LeftWorkDate.AddDays(-1) + }).Sum(x => (x.End - x.Start).Ticks)).TotalDays + 1; + + bool hasLeftWork = leftWorks.MaxBy(x => x.LeftWorkDate).LeftWorkDate.AddDays(-1) < contractEnd; + + //محاسبه سنوات سالیانه + switch (baseYearsSettings.BaseYearsPayType) + { + case BaseYearsPayType.PercentageOfSalary: + { + baseYearPayAmount = monthlySalary * baseYearsSettings.Value / 100; + break; + } + case BaseYearsPayType.Money: + { + baseYearPayAmount = baseYearsSettings.Value; + break; + } + case BaseYearsPayType.None: + { + return 0; + } + } + + //در صورت ترک کار + if (hasLeftWork) + + { + switch (payOnLeave) + { + //اگر سنوات در آخر سال تعلق می گیرد ترک کار قبل از پایان دوره موجب صفر شدن آن میشود + case BaseYearsPayInEndOfYear.EndOfYear: + return 0; + + //اگر هنگام ترک کار سنوات تعلق می گیرد + case BaseYearsPayInEndOfYear.WhenEverEmployeeLeftWork: + { + + //بر اساس نوع پرداخت سالیانه یا ماهیانه سنوات محاسبه می گردد + switch (baseYearsSettings.PaymentType) + { + case BaseYearsPaymentType.MonthlyPay: + { + return CalculateYearsPayMonthlyByDays(baseYearPayAmount, daysWorked, contractStart.CountPersianMonthDays(), maxMonthDays); + } + case BaseYearsPaymentType.YearlyPay: + { + + return CalculateYearsPayYearlyByDays(baseYearPayAmount, daysWorked); + } + default: + return 0; + } + } + } + } + + //در صورت عدم ترک کار + switch (baseYearsSettings.PaymentType) + { + case BaseYearsPaymentType.MonthlyPay: + { + return CalculateYearsPayMonthlyByDays(baseYearPayAmount, daysWorked, contractStart.CountPersianMonthDays(), maxMonthDays); + } + case BaseYearsPaymentType.YearlyPay: + { + string contractEndFa = contractEnd.ToFarsi(); + bool isCheckoutForEsfand = contractEndFa.Substring(5, 2) == "12"; + bool isContractEndOfMonth = contractEndFa.FindeEndOfMonth() == contractEndFa; + + //اگر آخر ماه نبود یا اسفند نبود سنوات سالیانه محاسبه نمی گردد + if (isContractEndOfMonth == false || isCheckoutForEsfand == false) + return 0; + + return CalculateYearsPayYearlyByDays(baseYearPayAmount, daysWorked); + } + default: + return 0; + } + + } + + /// + /// محاسبه سنوات ماهیانه بر اساس روز های کارکرد + /// + /// سنوات در کل سال + /// روز های کارکرد + /// تعداد روز های ماه + public static double CalculateYearsPayMonthlyByDays(double baseYears, int daysWorked, int totalDaysInMonth, MaxMonthDays maxMonthDays) + { + daysWorked = maxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth && daysWorked > 30 ? 30 : daysWorked; + totalDaysInMonth = maxMonthDays == MaxMonthDays.ThirtyDaysForAllMonth ? 30 : totalDaysInMonth; + return baseYears / 12 / totalDaysInMonth * daysWorked; + } + + /// + /// محاسبه سنوات سالیانه بر اساس روز های کارکرد + /// + /// سنوات در کل سال + /// روز های کارکرد + /// + /// + public static double CalculateYearsPayYearlyByDays(double baseYears, int daysWorked) + { + return baseYears / 365 * daysWorked; + } + #endregion + + + + //TODO: this must be updated with Mahan's method for leaves + /// + /// محاسبه مدت اضافه کاری + /// + public static TimeSpan CalculateOvertimeTimeSpan(List rollCalls, + ICollection shiftSettings, TimeOnly employeeOffSet) + { + + //for (DateTime offset = start; offset <= end; offset.AddDays(1)) + //{ + // DayOfWeek dayOfWeek = offset.DayOfWeek; + // switch (dayOfWeek) + // { + // case DayOfWeek.Thursday: + // shifts.Add(new ShiftViewModel { Start = offset.AddHours(9), End = offset.AddHours(14) }); + // break; + // case DayOfWeek.Friday: + // break; + // default: + // shifts.Add(new ShiftViewModel { Start = offset.AddHours(8), End = offset.AddHours(16) }); + // break; + // } + //} + + //if (!rollCalls.Any()) + // return TimeSpan.Zero; + //var startRollCall = rollCalls.MinBy(x => x.StartDate!.Value).StartDate!.Value; + //var endRollCall = rollCalls.Max(x => x.EndDate)!.Value; + + //DateTime startDateTime = new DateTime(DateOnly.FromDateTime(startRollCall), employeeOffSet); + //DateTime endDateTime = new DateTime(DateOnly.FromDateTime(endRollCall), employeeOffSet); + //endDateTime = endDateTime == startDateTime ? endDateTime.AddDays(1) : endDateTime; + + + var mandatoryPerDayTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks)); + + //bool isFirst = true; + + //var sumOfOverTime = TimeSpan.Zero; + + //for (var startDateOffset = startDateTime; startDateOffset <= endDateTime; startDateOffset = startDateOffset.AddDays(1)) + //{ + // IEnumerable rollCallViewModels; + // var startPeriod = startDateOffset; + // var endPeriod = startDateOffset.AddDays(1); + + // if (isFirst) + // { + // rollCallViewModels = rollCalls + // .Where(x => x.StartDate.Value > startPeriod.Date && x.EndDate.Value <= endPeriod); + // isFirst = false; + // } + // else + // { + // rollCallViewModels = rollCalls + // .Where(x => x.StartDate.Value > startPeriod && x.EndDate.Value <= endPeriod); + // } + + // var sum = rollCallViewModels.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks); + // var rollCallTimeSpan = new TimeSpan(sum); + // if (rollCallTimeSpan > mandatoryPerDayTimeSpan) + // { + // var overTime = rollCallTimeSpan - mandatoryPerDayTimeSpan; + // sumOfOverTime = sumOfOverTime.Add(overTime); + // } + //} + + + //return sumOfOverTime; + + + var groupedRollCalls = rollCalls.GroupBy(x => x.StartDate!.Value.Date); + + + var rollCallsTimeSpans = groupedRollCalls.Where(x => + x.Sum(y => (y.EndDate!.Value - y.StartDate!.Value).Ticks) > mandatoryPerDayTimeSpan.Ticks) + .Select(x => x.Sum(y => (y.EndDate!.Value - y.StartDate!.Value).Ticks)).ToList(); + + var daysCount = rollCallsTimeSpans.Count(); + + var totalMandatoryTotalTimeSpan = mandatoryPerDayTimeSpan * daysCount; + var rollCallTotalTimeSpan = new TimeSpan(rollCallsTimeSpans.Sum(x => x)); + + if (rollCallTotalTimeSpan < totalMandatoryTotalTimeSpan) + return TimeSpan.Zero; + return rollCallTotalTimeSpan - totalMandatoryTotalTimeSpan; + } + + + public static TimeSpan CalculateOvertimeSpanWithSumSpan(TimeSpan sumSpan, int mandatoryDays, + ICollection shiftSettings) + { + var mandatoryPerDayTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks)); + var mandatoryWorkingTimeSpan = mandatoryPerDayTimeSpan * mandatoryDays; + if (mandatoryWorkingTimeSpan > sumSpan) + return TimeSpan.Zero; + + return sumSpan - mandatoryWorkingTimeSpan; + + } + + /// + /// محاسبه مبلغ اضافه کاری با استفاده از تنظیمات + /// + /// مدت اضافه کاری + /// تنظیمات اضافه کاری + /// مزد روزانه + /// + public static double CalculateOvertimePay(TimeSpan overtimeTimeSpan, OverTimePay overTimePaySettings, double dailyWage) + { + double baseAmount = overTimePaySettings.Value; + double result = 0; + switch (overTimePaySettings.OverTimePayType) + { + + case OverTimePayType.None: + break; + + + case OverTimePayType.MoneyPerHour: + { + int totalMinutes = (int)overtimeTimeSpan.TotalMinutes; + result = totalMinutes * (baseAmount / 60); + break; + } + + + case OverTimePayType.PercentagePerHourOfSalary: + { + int totalMinutes = (int)overtimeTimeSpan.TotalMinutes; + double multiplier = overTimePaySettings.Value / 100; + result = ((dailyWage * multiplier) / 60) * totalMinutes; + break; + } + + } + return result; + } + + /// + /// محاسبه مدت جمعه کاری بدون در نظر گرفتن اضافه کاری + /// + public static TimeSpan CalculateFridayWorkingTimeSpanWithoutOvertime(List rollCallsList, ICollection shiftSettings) + { + var _rollCallsList = rollCallsList; + _rollCallsList = _rollCallsList.Where(x => x.StartDate.Value.DayOfWeek == DayOfWeek.Friday || + x.EndDate.Value.DayOfWeek == DayOfWeek.Friday || + (x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday && x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday)).ToList(); + + var preprocessedRollCalls = _rollCallsList.Select(x => + new RollCallViewModel + { + StartDate = x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday ? x.StartDate.Value.AddDays(1).Date : x.StartDate.Value + , + EndDate = x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday ? x.EndDate.Value.Date : x.EndDate.Value + }).ToList(); + + //var timeSpan = new TimeSpan(preprocessedRollCalls.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks)); + + var extraWorkingTimeSpan = CalculateOvertimeTimeSpan(preprocessedRollCalls, shiftSettings, new TimeOnly()); + var rollCallTimeSpan = CalculateFridayWorkingTimeSpan(preprocessedRollCalls); + + if (rollCallTimeSpan <= extraWorkingTimeSpan) + return TimeSpan.Zero; + return rollCallTimeSpan - extraWorkingTimeSpan; + + + } + + /// + /// محاسبه مدت جمعه کاری + /// + public static TimeSpan CalculateFridayWorkingTimeSpan(List rollCallsList) + { + var _rollCallsList = rollCallsList; + _rollCallsList = _rollCallsList.Where(x => x.StartDate.Value.DayOfWeek == DayOfWeek.Friday || + x.EndDate.Value.DayOfWeek == DayOfWeek.Friday || + (x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday && x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday)).ToList(); + + var preprocessedRollCalls = _rollCallsList.Select(x => + new + { + Start = x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday ? x.StartDate.Value.AddDays(1).Date : x.StartDate.Value + , + End = x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday ? x.EndDate.Value.Date : x.EndDate.Value + }).ToList(); + + var timeSpan = new TimeSpan(preprocessedRollCalls.Sum(x => (x.End - x.Start).Ticks)); + return timeSpan; + } + + /// + /// محاسبه روز های جمعه کاری + /// + public static int CalculateFridayWorkingTotalDays(List rollCallsList) + { + var _rollCallsList = rollCallsList; + _rollCallsList = _rollCallsList.Where(x => x.StartDate.Value.DayOfWeek == DayOfWeek.Friday || + x.EndDate.Value.DayOfWeek == DayOfWeek.Friday || + (x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday && x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday)).ToList(); + + var preprocessedRollCalls = _rollCallsList.Select(x => + new + { + Start = x.StartDate.Value.DayOfWeek == DayOfWeek.Thursday ? x.StartDate.Value.AddDays(1).Date : x.StartDate.Value + , + End = x.EndDate.Value.DayOfWeek == DayOfWeek.Saturday ? x.StartDate.Value.Date : x.EndDate.Value, + ShiftDate = x.ShiftDate + }).ToList(); + + int fridaysCount = preprocessedRollCalls.GroupBy(x => x.ShiftDate).Count(); + return fridaysCount; + } + + #endregion + + #endregion + + + public static (DateTime start, DateTime end) FindRotatingShift(DateTime startRollCall, DateTime endRollCall, + ICollection rotatingShifts) + { + DateTime startDate = startRollCall.Date; + DateTime endDate = endRollCall.Date; + + + + DateTime startEntryWithDate = startDate.Add(startRollCall.TimeOfDay); + DateTime endEntryWithDate = endDate.Add(endRollCall.TimeOfDay); + + DateTime twoHourBeforeStart = startEntryWithDate.AddHours(-2); + DateTime twoHourAfterStart = startEntryWithDate.AddHours(2); + DateTime twoHourBeforeEnd = endEntryWithDate.AddHours(-2); + DateTime twoHourAfterEnd = endEntryWithDate.AddHours(2); + + + var shiftDateTimes = rotatingShifts.SelectMany(shift => + { + var shifts = new List<(DateTime Start, DateTime End)>(); + for (int i = -1; i <= 1; i++) + { + var shiftStart = startDate.AddDays(i).Date; + shiftStart = shiftStart.Add(shift.StartTime.ToTimeSpan()); + var shiftEnd = shift.StartTime < shift.EndTime + ? startDate.AddDays(i).Date.Add(shift.EndTime.ToTimeSpan()) + : startDate.AddDays(i + 1).Date.Add(shift.EndTime.ToTimeSpan()); + shifts.Add((shiftStart, shiftEnd)); + } + + return shifts; + }).ToList(); + + #region مقایسه شروع حضور غیاب با شیفت + + //var startFilteredTimes = shiftDateTimes.Where(shift => + // (twoHourBeforeStart <= shift.Start && twoHourAfterStart >= shift.Start) || + // (twoHourBeforeStart <= shift.End && twoHourAfterStart >= shift.End)).ToList(); + + //if (startFilteredTimes.Count == 0) + //{ + // startFilteredTimes = shiftDateTimes; + //} + //else if (startFilteredTimes.Count == 1) + //{ + // var startChosenShift = startFilteredTimes.First(); + + // if (startChosenShift.End < startChosenShift.Start) + // startChosenShift.End = startChosenShift.End.AddDays(1); + + // return startChosenShift; + //} + + + //#endregion + + //#region مقایسه پایان حضورغیاب با شیفت + + //var endFilteredTimes = shiftDateTimes.Where(shift => + // (twoHourBeforeEnd <= shift.Start && twoHourAfterEnd >= shift.Start) || + // (twoHourBeforeEnd <= shift.End && twoHourAfterEnd >= shift.End)).ToList(); + //if (endFilteredTimes.Count == 0) + //{ + // endFilteredTimes = startFilteredTimes; + //} + //else if (endFilteredTimes.Count == 1) + //{ + // var endChosenShift = endFilteredTimes.First(); + // return endChosenShift; + //} + + #endregion + + #region اشتراک حضور غیاب و شیفت + + var overlapShifts = shiftDateTimes + .Select(shift => new + { + Shift = shift, + Overlap = new TimeSpan(Math.Max(0, + Math.Min(shift.End.Ticks, endRollCall.Ticks) - + Math.Max(shift.Start.Ticks, startRollCall.Ticks))), + // زمان حضور فرد در شیفت (مجموع Overlap با شیفت) + TotalTimeInShift = new TimeSpan(Math.Max(0, + Math.Min(shift.End.Ticks, endRollCall.Ticks) - + Math.Max(shift.Start.Ticks, startRollCall.Ticks))), + StartDistance = Math.Abs((shift.Start - startRollCall).Ticks), + EndDistance = Math.Abs((shift.End - endRollCall).Ticks), + TotalDistance = Math.Abs((shift.Start - startRollCall).Ticks) + Math.Abs((shift.End - endRollCall).Ticks) + }) + .OrderByDescending(s => s.TotalTimeInShift) // 1. بیشترین زمان حضور فرد + .ThenByDescending(s => s.Overlap) // 2. بیشترین Overlap + .ThenBy(s => s.TotalDistance) + .ThenBy(s => s.StartDistance) + .ThenBy(x => x.EndDistance); // 3. اگر برابر بود، Start نزدیک‌تر + + var overlapChosenShift = overlapShifts.First(); + var end = overlapChosenShift.Shift.End; + if (overlapChosenShift.Shift.End < overlapChosenShift.Shift.Start) + end = overlapChosenShift.Shift.End.AddDays(1); + + + return (overlapChosenShift.Shift.Start, end); + + #endregion + } + #endregion } enum AbsentOrLeave { - LeavePay, - AbsentDeduction + LeavePay, + AbsentDeduction } internal class EmployeeShiftResult { - public ShiftPlacement Placement { get; set; } - public TimeSpan ShiftSpan { get; set; } + public ShiftPlacement Placement { get; set; } + public TimeSpan ShiftSpan { get; set; } } internal class StaticShiftStartEnd { - public DateTime StartShift { get; set; } - public DateTime EndShift { get; set; } - public TimeSpan ShiftSpanning { get; set; } - public bool HasValue { get; set; } - public string ShiftType { get; set; } + public DateTime StartShift { get; set; } + public DateTime EndShift { get; set; } + public TimeSpan ShiftSpanning { get; set; } + public bool HasValue { get; set; } + public string ShiftType { get; set; } } \ No newline at end of file diff --git a/CompanyManagment.EFCore/TestDbContext.cs b/CompanyManagment.EFCore/TestDbContext.cs index 83a8ff96..273b36bd 100644 --- a/CompanyManagment.EFCore/TestDbContext.cs +++ b/CompanyManagment.EFCore/TestDbContext.cs @@ -8,6 +8,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Company.Domain.CustomizeWorkshopEmployeeSettingsAgg.Entities; +using Company.Domain.CustomizeWorkshopSettingsAgg.Entities; +using CompanyManagment.EFCore.Migrations; namespace CompanyManagment.EFCore { @@ -15,6 +18,8 @@ namespace CompanyManagment.EFCore { public DbSet InsuranceJobItems { get; set; } public DbSet InsuranceJobs { get; set; } + public DbSet CustomizeWorkshopEmployeeSettings { get; set; } + public DbSet CustomizeWorkshopSettings { get; set; } public TestDbContext(DbContextOptions options) : base(options) {