2053 lines
72 KiB
C#
2053 lines
72 KiB
C#
using _0_Framework.Application;
|
||
using _0_Framework.InfraStructure;
|
||
using Company.Domain.CustomizeWorkshopEmployeeSettingsAgg.Entities;
|
||
using Company.Domain.CustomizeWorkshopSettingsAgg.Entities;
|
||
using Company.Domain.LeaveAgg;
|
||
using Company.Domain.LeftWorkAgg;
|
||
using Company.Domain.RollCallAgg;
|
||
using Company.Domain.YearlySalaryAgg;
|
||
using CompanyManagment.App.Contracts.Contract;
|
||
using CompanyManagment.App.Contracts.CustomizeCheckout;
|
||
using CompanyManagment.App.Contracts.CustomizeWorkshopSettings;
|
||
using CompanyManagment.App.Contracts.Leave;
|
||
using CompanyManagment.App.Contracts.LeftWork;
|
||
using CompanyManagment.App.Contracts.RollCall;
|
||
using CompanyManagment.App.Contracts.WorkingHoursTemp;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using CompanyManagment.App.Contracts.Fine;
|
||
using System.Globalization;
|
||
using System.IO;
|
||
using _0_Framework.Domain.CustomizeCheckoutShared.Base;
|
||
using _0_Framework.Domain.CustomizeCheckoutShared.Enums;
|
||
using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Company.Domain.EmployeeAgg;
|
||
|
||
|
||
namespace CompanyManagment.EFCore.Repository;
|
||
|
||
public class RollCallMandatoryRepository : RepositoryBase<long, RollCall>, IRollCallMandatoryRepository
|
||
{
|
||
private readonly CompanyContext _context;
|
||
private readonly IYearlySalaryRepository _yearlySalaryRepository;
|
||
private readonly ILeftWorkRepository _leftWorkRepository;
|
||
private readonly ILeaveRepository _leaveRepository;
|
||
|
||
public RollCallMandatoryRepository(CompanyContext context, IYearlySalaryRepository yearlySalaryRepository,
|
||
ILeftWorkRepository leftWorkRepository, ILeaveRepository leaveRepository) : base(context)
|
||
{
|
||
_context = context;
|
||
_yearlySalaryRepository = yearlySalaryRepository;
|
||
_leftWorkRepository = leftWorkRepository;
|
||
_leaveRepository = leaveRepository;
|
||
}
|
||
|
||
#region OfficialChckout
|
||
public ComputingViewModel MandatoryCompute(long employeeId, long workshopId, DateTime contractStart,
|
||
DateTime contractEnd,
|
||
CreateWorkingHoursTemp command, long leavId)
|
||
{
|
||
#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
|
||
|
||
|
||
//گرفتن ساعت استراحت پرسنل از تنظیمات
|
||
#region breakTime
|
||
BaseCustomizeEntity settings = _context.CustomizeWorkshopEmployeeSettings.AsSplitQuery().FirstOrDefault(x =>
|
||
x.WorkshopId == workshopId && x.EmployeeId == employeeId);
|
||
//اگر ساعت استراحت پرسنل وجود نداشت صفر است
|
||
var breakTime = settings == null ? new BreakTime(false, new TimeOnly()) : settings.BreakTime;
|
||
#endregion
|
||
|
||
List<RollCallViewModel> 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,
|
||
}).ToList();
|
||
List<GroupedRollCalls> 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(breakTime,
|
||
new TimeSpan(x.Sum(shift => shift.ShiftSpan.Ticks))),
|
||
|
||
}).ToList();
|
||
|
||
numberOfFridays = groupedRollCall.Count(x => x.HasFriday);
|
||
|
||
////*****کسر ساعاعت استراحت پرسنل از ساعت کار
|
||
//List<GroupedRollCalls> 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));
|
||
|
||
|
||
//****افزودن مرخصی پرسنل به مجموع ساعات کار***
|
||
#region AddEmployeeLeavs
|
||
|
||
|
||
LeaveSearchModel leaveSearch = new LeaveSearchModel()
|
||
{
|
||
EmployeeId = employeeId,
|
||
WorkshopId = workshopId,
|
||
LeaveType = "استحقاقی",
|
||
PaidLeaveType = "روزانه",
|
||
StartLeaveGr = contractStart,
|
||
EndLeaveGr = contractEnd,
|
||
IsAccepted = true,
|
||
};
|
||
var leaveSearchResult = _leaveRepository.search(leaveSearch);
|
||
if (leaveSearchResult.Count > 0)
|
||
{
|
||
int leavingDayCout = 0;
|
||
//مرخصی های مابین
|
||
List<LeaveViewModel> 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<LeaveViewModel> 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<LeaveViewModel> 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;
|
||
}
|
||
else
|
||
{
|
||
sumLeave = leavingDayCout * new TimeSpan(7, 20, 0);
|
||
}
|
||
|
||
sumSpans = sumSpans.Add(sumLeave);
|
||
}
|
||
|
||
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
|
||
|
||
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);
|
||
//***********************************//
|
||
//This Time Mandatory Hourse
|
||
double mandatoryHours = Math.Round((mandatorDays * 7.33), 2);
|
||
//***********************************//
|
||
var dailyFix = TimeSpan.Parse("07:20");
|
||
TimeSpan mandatoryHoursTimeSpan = new TimeSpan(7, 20, 0).Multiply(mandatorDays);
|
||
TimeSpan Mandatory = sumSpans.Subtract(mandatoryHoursTimeSpan);
|
||
|
||
#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<LeftWorkViewModel>();
|
||
|
||
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, 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 (command.ShiftWork == "1" || command.ShiftWork == "2" || command.ShiftWork == "4")
|
||
{
|
||
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 (totalHourses > mandatoryHours)
|
||
{
|
||
Console.WriteLine(Mandatory);
|
||
Console.WriteLine(Mandatory.Minutes);
|
||
int mandatoryH = (int)Mandatory.TotalHours;
|
||
int mandatoryM = (int)(Mandatory.TotalMinutes % 60);
|
||
overMandatoryHours = mandatoryH.ToString();
|
||
overMandatoryMinuts = mandatoryM.ToString();
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
//****** نوبت کاری و شب کاری ****
|
||
#region RotatingShiftCheckAndNightWorkOver22
|
||
|
||
List<RotatingShiftViewModel> rotatingResultList = RotatingShiftCheck(groupedRollCall);
|
||
var moriningCount = rotatingResultList.Count(x => x.IsMorningShift);
|
||
var eveningCount = rotatingResultList.Count(x => x.IsEveningShift);
|
||
var nightCount = rotatingResultList.Count(x => x.IsNightShift);
|
||
// شبکاری
|
||
TimeSpan over22 = new TimeSpan(rotatingResultList.Sum(x => x.NightWorkSpan.Ticks));
|
||
var RotatingfaName = new List<string>();
|
||
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("شب");
|
||
|
||
}
|
||
|
||
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;
|
||
}
|
||
else if (rotatingFaResult == "صبح و عصر و شب")
|
||
{
|
||
var shiftPyaPercent = DailyFeeNumberType * 15 / 100;
|
||
ShiftPayResult = shiftPyaPercent * TotalDays;
|
||
}
|
||
else if (rotatingFaResult == "صبح و شب" || rotatingFaResult == "عصر و شب")
|
||
{
|
||
var shiftPyaPercent = DailyFeeNumberType * 22.5 / 100;
|
||
ShiftPayResult = shiftPyaPercent * TotalDays;
|
||
}
|
||
}
|
||
|
||
#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,
|
||
};
|
||
|
||
#endregion
|
||
return res;
|
||
}
|
||
|
||
private TimeSpan CalculateBreakTime(BreakTime breakTime, TimeSpan sumOneDaySpan)
|
||
{
|
||
if (breakTime.BreakTimeType != BreakTimeType.WithTime)
|
||
return TimeSpan.Zero;
|
||
|
||
var breakTimeSpan = breakTime.BreakTimeValue.ToTimeSpan();
|
||
|
||
if (breakTimeSpan * 2 >= sumOneDaySpan)
|
||
return TimeSpan.Zero;
|
||
|
||
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<RotatingShiftViewModel> RotatingShiftCheck(List<GroupedRollCalls> rollCallList)
|
||
{
|
||
List<RotatingShiftViewModel> finalResult = new List<RotatingShiftViewModel>();
|
||
var nullDateTme = new DateTime(0001, 01, 01);
|
||
foreach (var item in rollCallList)
|
||
{
|
||
#region Entityes
|
||
|
||
var midNight24 = new DateTime(item.CreationDate.Year, item.CreationDate.Month, item.CreationDate.Day, 0, 0, 0).AddDays(1);
|
||
var morningWorkingTime = new TimeSpan();
|
||
var eveningWorkingTime = new TimeSpan();
|
||
var nightWorkingTime = new TimeSpan();
|
||
|
||
DateTime morningStart = new DateTime(item.CreationDate.Year, item.CreationDate.Month, item.CreationDate.Day, 6, 0, 0);
|
||
DateTime morningEnd = new DateTime(item.CreationDate.Year, item.CreationDate.Month, item.CreationDate.Day, 14, 0, 0);
|
||
DateTime eveningStart = morningEnd;
|
||
DateTime eveningEnd = new DateTime(item.CreationDate.Year, item.CreationDate.Month, item.CreationDate.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
|
||
|
||
foreach (var shift in item.ShiftList)
|
||
{
|
||
|
||
#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 = morningWorkingTime.Add(eveningEnd - eveningStart);
|
||
}
|
||
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.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)
|
||
{
|
||
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)
|
||
{
|
||
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)
|
||
{
|
||
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)
|
||
{
|
||
result.IsMorningShift = false;
|
||
result.IsEveningShift = false;
|
||
result.IsNightShift = true;
|
||
result.RotatingShiftStatus = "شب";
|
||
}
|
||
}
|
||
|
||
finalResult.Add(result);
|
||
#endregion
|
||
}
|
||
|
||
return finalResult;
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region CustomizeCheckout
|
||
|
||
/// <summary>
|
||
/// متد محاسبه فیش حقوقی دلخواه
|
||
/// </summary>
|
||
/// <param name="employeeId"></param>
|
||
/// <param name="workshopId"></param>
|
||
/// <param name="contractStart"></param>
|
||
/// <param name="contractEnd"></param>
|
||
/// <returns></returns>
|
||
public CustomizeCheckoutMandatoryViewModel CustomizeCheckoutMandatoryCompute(long employeeId, long workshopId, DateTime contractStart,
|
||
DateTime 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));
|
||
TimeSpan contractDuration = contractEnd - contractStart;
|
||
var employee = _context.Employees.FirstOrDefault(x => x.id == employeeId);
|
||
|
||
#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();
|
||
dailyWage = monthySalary / monthDays;
|
||
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
|
||
{
|
||
Placement = x.Placement,
|
||
ShiftSpan = span
|
||
};
|
||
|
||
});
|
||
|
||
|
||
|
||
var sumOfEmployeeShiftSpan = new TimeSpan(employeeShiftsSpans.Sum(x => x.ShiftSpan.Ticks));
|
||
#endregion
|
||
|
||
List<RollCallViewModel> 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,
|
||
}).ToList();
|
||
List<GroupedRollCalls> 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)),
|
||
}).ToList();
|
||
|
||
TimeSpan sumSpans = new TimeSpan(groupedRollCall.Sum(x => x.SumOneDaySpan.Ticks));
|
||
|
||
numberOfFridays = groupedRollCall.Count(x => x.HasFriday);
|
||
|
||
numberOfWorkingDay = groupedRollCall.Count();
|
||
//تعداد روز های قرارداد
|
||
int contractDays = (int)contractDuration.TotalDays + 1;
|
||
|
||
//روز های غیبت
|
||
int absentsDays = contractDays - numberOfWorkingDay;
|
||
|
||
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.WorkInFriday)
|
||
{
|
||
absentsDays -= fridays;
|
||
}
|
||
|
||
if (customizeWorkshopEmployeeSettings.HolidayWork != HolidayWork.WorkInHolidays)
|
||
{
|
||
absentsDays -= holiday;
|
||
}
|
||
|
||
|
||
// یافتن مرخصی ساعتی
|
||
#region LeavHourse
|
||
|
||
LeaveSearchModel leaveHourseSearch = new LeaveSearchModel()
|
||
{
|
||
EmployeeId = employeeId,
|
||
WorkshopId = workshopId,
|
||
LeaveType = "استحقاقی",
|
||
|
||
StartLeaveGr = contractStart,
|
||
EndLeaveGr = contractEnd,
|
||
IsAccepted = true,
|
||
};
|
||
List<LeaveViewModel> leaveList = _leaveRepository.search(leaveHourseSearch);
|
||
|
||
#endregion
|
||
|
||
//****افزودن مرخصی پرسنل به مجموع ساعات کار***
|
||
#region AddEmployeeLeaves
|
||
|
||
//TimeSpan workingPerDayAve = sumSpans / numberOfWorkingDay;//میانگین ساعت کار در روز
|
||
|
||
|
||
|
||
//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 = customizeWorkshopSettings.LeavePermittedDays;
|
||
double leaveValue = customizeWorkshopEmployeeSettings.LeavePay.Value;
|
||
sumSpans = CalculateLeavePay(sumOfEmployeeShiftSpan, absentsDays, permittedDays, monthDays, contractDays, sumSpans
|
||
, leaveValue, dailyWage, leaveList, contractStart, contractEnd, out leavePayAmount, out absentsDeductionAmount);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
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 InsurancePay
|
||
|
||
InsuranceDeduction insuranceDeduction = customizeWorkshopEmployeeSettings.InsuranceDeduction;
|
||
double insuranceDeductionAmount = InsurancePayCalculation(employeeId, contractEnd, insuranceDeduction, monthySalary);
|
||
#endregion
|
||
#region SalaryAidDeduction
|
||
|
||
double salaryAidDeduction = _context.SalaryAids.Where(x => x.SalaryAidDateTime > contractStart && x.SalaryAidDateTime < contractEnd).Sum(x => x.Amount);
|
||
|
||
#endregion
|
||
|
||
#region Loan
|
||
|
||
double loanInstallments = _context.Loans
|
||
.Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId)
|
||
.SelectMany(x => x.LoanInstallments)
|
||
.Where(i => i.Month == monthOfCheckout.ToString("00") && i.Year == yearOfCheckout.ToString("0000")).Select(x => x.AmountForMonth).Sum(x => x);
|
||
|
||
double loanDeduction = loanInstallments;
|
||
|
||
#endregion
|
||
|
||
#region Fine
|
||
|
||
var fineViewModels = _context.Fines.Where(x =>
|
||
x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.FineDate > contractStart &&
|
||
x.FineDate < contractStart && x.IsActive == IsActive.True).Select(x => new EditFineViewModel()
|
||
{
|
||
IsActive = x.IsActive,
|
||
Amount = x.Amount.ToMoney(),
|
||
FineDate = x.FineDate.ToFarsi(),
|
||
Id = x.id,
|
||
Title = x.Title
|
||
}).ToList();
|
||
double fineDeduction = fineViewModels.Sum(x => x.Amount.MoneyToDouble());
|
||
|
||
#endregion
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
#region Payments
|
||
//اضافه کاری
|
||
#region OvertimePay
|
||
double overtimePayAmount = 0;
|
||
overtimePayAmount = CalculateOvertimePay(sumSpans, customizeWorkshopEmployeeSettings.OverTimePay, dailyWage);
|
||
if (overtimePayAmount >= absentsDeductionAmount)
|
||
{
|
||
overtimePayAmount = overtimePayAmount - absentsDeductionAmount;
|
||
absentsDeductionAmount = 0;
|
||
}
|
||
else
|
||
{
|
||
absentsDeductionAmount = absentsDeductionAmount - overtimePayAmount;
|
||
overtimePayAmount = 0;
|
||
}
|
||
#endregion
|
||
|
||
#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;
|
||
var nightWorks = RotatingShiftCheck(groupedRollCall).Where(x => x.IsNightShift);
|
||
if (nightWorks.Any())
|
||
{
|
||
switch (customizeWorkshopEmployeeSettings.NightWorkPay.NightWorkingType)
|
||
{
|
||
case NightWorkType.MoneyPerHour:
|
||
{
|
||
var baseAmount = customizeWorkshopEmployeeSettings.NightWorkPay.Value;
|
||
var nightWorkHours = (int)(new TimeSpan(nightWorks.Sum(x => x.NightWorkSpan.Ticks))).TotalHours;
|
||
nightworkPayAmount += nightWorkHours * baseAmount;
|
||
break;
|
||
}
|
||
case NightWorkType.PercentageFromSalary:
|
||
{
|
||
double multiplier = customizeWorkshopEmployeeSettings.NightWorkPay.Value / 100;
|
||
var nightWorkHours = (int)(new TimeSpan(nightWorks.Sum(x => x.NightWorkSpan.Ticks))).TotalHours;
|
||
nightworkPayAmount += dailyWage * multiplier * nightWorkHours;
|
||
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
|
||
|
||
double rewardPay = _context.Rewards.Where(x =>
|
||
x.WorkshopId == workshopId && x.EmployeeId == employeeId && x.CreationDate < contractEnd &&
|
||
x.CreationDate > contractStart).Sum(x => x.Amount);
|
||
|
||
#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 Test
|
||
|
||
|
||
|
||
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 * dailyWagePerMinute,
|
||
|
||
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 * dailyWagePerMinute,
|
||
|
||
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,
|
||
};
|
||
}
|
||
|
||
|
||
#region CustomizeCheckoutCalculation
|
||
|
||
public static double FridayPayCalculation(CustomizeWorkshopEmployeeSettings customizeWorkshopEmployeeSettings,
|
||
List<RollCallViewModel> rollCallResult, double dailyWage, ICollection<CustomizeWorkshopEmployeeSettingsShift> 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 workedFridaysHours = (int)CalculateFridayWorkingTimeSpan(rollCallResult).TotalHours;
|
||
double baseAmount = customizeWorkshopEmployeeSettings.FridayPay.Value;
|
||
fridayPayAmount = baseAmount * workedFridaysHours;
|
||
break;
|
||
}
|
||
case (FridayPayType.PercentageFromSalaryPerHour):
|
||
{
|
||
int workedFridaysHours = (int)CalculateFridayWorkingTimeSpan(rollCallResult).TotalHours;
|
||
double percentageAmount = (customizeWorkshopEmployeeSettings.FridayPay.Value / 100 * dailyWage);
|
||
fridayPayAmount = percentageAmount * workedFridaysHours;
|
||
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 contractEnd,
|
||
InsuranceDeduction insuranceDeduction, double monthySalary)
|
||
{
|
||
double insurancePayAmount = 0;
|
||
switch (insuranceDeduction.InsuranceDeductionType)
|
||
{
|
||
case InsuranceDeductionType.BasedOnLaborLaw:
|
||
|
||
double familyAllowance = _yearlySalaryRepository.FamilyAllowance(employeeId, 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, int absentsDays,
|
||
int permittedLeaveDay, int monthDays, int contractDays, TimeSpan sumSpans,
|
||
double leaveValue, double dailyWage, List<LeaveViewModel> leaveList, DateTime startDate, DateTime endDate, out double leavePayAmount, out double absentsDeduction)
|
||
{
|
||
|
||
#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
|
||
|
||
// مقدار ساعت های غیبت
|
||
TimeSpan absentsTimeSpan = sumOfEmployeeShiftSpan * absentsDays;
|
||
|
||
|
||
// زمان مجاز مرخصی
|
||
TimeSpan permittedLeaveTimeSpan = sumOfEmployeeShiftSpan * permittedLeaveDay;
|
||
|
||
// زمان مرخصی مجاز برای یک روز
|
||
TimeSpan leaveTimePerDay = (permittedLeaveTimeSpan / monthDays);
|
||
|
||
|
||
//اگر ترک کار کرده بود
|
||
if (contractDays < monthDays)
|
||
{
|
||
permittedLeaveTimeSpan = leaveTimePerDay * contractDays;
|
||
}
|
||
|
||
//اگر قراردادش کامل بود
|
||
else
|
||
{
|
||
|
||
}
|
||
|
||
//اختلاف غیبت و مرخصی
|
||
(TimeSpan Diffrence, AbsentOrLeave absentOrLeave) absentAndLeaveDifference;
|
||
|
||
//مقدار مبلغ مرخصی
|
||
leavePayAmount = 0;
|
||
|
||
//مقدار مبلغ غیبت
|
||
absentsDeduction = 0;
|
||
|
||
if (permittedLeaveTimeSpan >= usedLeavesCheckout)
|
||
permittedLeaveTimeSpan = permittedLeaveTimeSpan - usedLeavesCheckout;
|
||
else
|
||
{
|
||
absentsTimeSpan = usedLeavesCheckout - permittedLeaveTimeSpan;
|
||
permittedLeaveTimeSpan = new TimeSpan();
|
||
}
|
||
|
||
|
||
|
||
//اگر مقدار مرخصی بیشتر از غیبت یا مساوی باشد
|
||
if (permittedLeaveTimeSpan >= absentsTimeSpan)
|
||
{
|
||
//محاسبه مقدار باقی مانده مزد مرخصی
|
||
absentAndLeaveDifference.Diffrence = absentsTimeSpan - permittedLeaveTimeSpan;
|
||
absentAndLeaveDifference.absentOrLeave = AbsentOrLeave.LeavePay;
|
||
|
||
//صفر کردن مقدار غیبت
|
||
absentsTimeSpan = new TimeSpan(0);
|
||
absentsDays = 0;
|
||
|
||
//برگرداندن ساعت کاری باقی مونده از مزد مرخصی به ساعت کاری
|
||
sumSpans += absentAndLeaveDifference.Diffrence;
|
||
|
||
//مقدار مزد مرخصی برای هرروز استفاده نشده
|
||
double leavePayPerDayWage = (leaveValue * dailyWage);
|
||
|
||
leavePayAmount = (leavePayPerDayWage / permittedLeaveTimeSpan.TotalHours) * absentAndLeaveDifference.Diffrence.TotalHours;
|
||
|
||
}
|
||
//اگر مقدار غیبت بیشتر از مرخصی باشد
|
||
else
|
||
{
|
||
//محاسبه مقدار باقی مانده از غیبت
|
||
absentAndLeaveDifference.Diffrence = permittedLeaveTimeSpan - absentsTimeSpan;
|
||
absentAndLeaveDifference.absentOrLeave = AbsentOrLeave.AbsentDeduction;
|
||
|
||
//صفر کردن مقدار مزد مرخصی
|
||
permittedLeaveTimeSpan = new TimeSpan(0);
|
||
permittedLeaveDay = 0;
|
||
|
||
//برگرداندن ساعت کاری باقی مونده از مزد مرخصی به ساعت کاری
|
||
sumSpans += permittedLeaveTimeSpan;
|
||
|
||
absentsDeduction = absentsDays * dailyWage;
|
||
|
||
}
|
||
|
||
return sumSpans;
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه تاخیر در ورورد و تعجیل در خروج
|
||
/// </summary>
|
||
/// <param name="groupedRollCall"></param>
|
||
/// <param name="shiftSettings"></param>
|
||
/// <returns></returns>
|
||
public List<LateToWorkEarlyExistSpannig> LateToWorkEarlyExit(List<GroupedRollCalls> groupedRollCall, ICollection<CustomizeWorkshopEmployeeSettingsShift> shiftSettings, List<LeaveViewModel> leavList)
|
||
{
|
||
List<LateToWorkEarlyExistSpannig> lateToWorkEarlyExistSpannig = new List<LateToWorkEarlyExistSpannig>();
|
||
|
||
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;
|
||
}
|
||
|
||
#region سنوات
|
||
|
||
/// <summary>
|
||
/// فرمول اصلی محاسبه سنوات برای پرسنل در بازه زمانی با تنظیمات پیشرفته
|
||
/// </summary>
|
||
/// <param name="monthlySalary">حقوق ماهیانه پرسنل</param>
|
||
/// <param name="baseYearsSettings">تنظیمات سنوات</param>
|
||
/// <param name="payOnLeave">تنظیم مربوط به پرداخت هنگام ترک کار</param>
|
||
private 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);
|
||
|
||
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;
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه سنوات ماهیانه بر اساس روز های کارکرد
|
||
/// </summary>
|
||
/// <param name="baseYears">سنوات در کل سال</param>
|
||
/// <param name="daysWorked">روز های کارکرد</param>
|
||
/// <param name="totalDaysInMonth">تعداد روز های ماه</param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه سنوات سالیانه بر اساس روز های کارکرد
|
||
/// </summary>
|
||
/// <param name="baseYears">سنوات در کل سال</param>
|
||
/// <param name="daysWorked">روز های کارکرد</param>
|
||
/// <param name="totalDaysInMonth"></param>
|
||
/// <param name="maxMonthDays"></param>
|
||
public static double CalculateYearsPayYearlyByDays(double baseYears, int daysWorked)
|
||
{
|
||
return baseYears / 365 * daysWorked;
|
||
}
|
||
#endregion
|
||
|
||
|
||
|
||
//TODO: this must be updated with Mahan's method for leaves
|
||
/// <summary>
|
||
/// محاسبه مدت اضافه کاری
|
||
/// </summary>
|
||
public static TimeSpan CalculateOvertimeTimeSpan(List<RollCallViewModel> rollCalls, ICollection<CustomizeWorkshopEmployeeSettingsShift> shiftSettings)
|
||
{
|
||
|
||
//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;
|
||
// }
|
||
//}
|
||
var groupedRollCalls = rollCalls.GroupBy(x => x.StartDate!.Value.Date);
|
||
var mandatoryPerDayTimeSpan = new TimeSpan(shiftSettings.Sum(x => (x.EndTime - x.StartTime).Ticks));
|
||
|
||
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه مبلغ اضافه کاری با استفاده از تنظیمات
|
||
/// </summary>
|
||
/// <param name="overtimeTimeSpan">مدت اضافه کاری</param>
|
||
/// <param name="overTimePaySettings">تنظیمات اضافه کاری</param>
|
||
/// <param name="dailyWage">مزد روزانه</param>
|
||
/// <returns></returns>
|
||
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 totalHours = (int)overtimeTimeSpan.TotalHours;
|
||
result = totalHours * baseAmount;
|
||
break;
|
||
}
|
||
|
||
|
||
case OverTimePayType.PercentagePerHourOfSalary:
|
||
{
|
||
int totalHours = (int)overtimeTimeSpan.TotalHours;
|
||
double multiplier = overTimePaySettings.Value / 100;
|
||
result = dailyWage * totalHours * multiplier;
|
||
break;
|
||
}
|
||
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه مدت جمعه کاری بدون در نظر گرفتن اضافه کاری
|
||
/// </summary>
|
||
public static TimeSpan CalculateFridayWorkingTimeSpanWithoutOvertime(List<RollCallViewModel> rollCallsList, ICollection<CustomizeWorkshopEmployeeSettingsShift> 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);
|
||
var rollCallTimeSpan = CalculateFridayWorkingTimeSpan(preprocessedRollCalls);
|
||
|
||
if (rollCallTimeSpan <= extraWorkingTimeSpan)
|
||
return TimeSpan.Zero;
|
||
return rollCallTimeSpan - extraWorkingTimeSpan;
|
||
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه مدت جمعه کاری
|
||
/// </summary>
|
||
public static TimeSpan CalculateFridayWorkingTimeSpan(List<RollCallViewModel> 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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// محاسبه روز های جمعه کاری
|
||
/// </summary>
|
||
public static int CalculateFridayWorkingTotalDays(List<RollCallViewModel> 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
|
||
}).ToList();
|
||
|
||
int fridaysCount = preprocessedRollCalls.GroupBy(x => x.Start.Date).Count();
|
||
return fridaysCount;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
}
|
||
|
||
|
||
enum AbsentOrLeave
|
||
{
|
||
LeavePay,
|
||
AbsentDeduction
|
||
} |