From 24d41ffc68335dc35fc4221a1cd1a1756b4ede25 Mon Sep 17 00:00:00 2001 From: Mahan Ch Date: Tue, 10 Jun 2025 19:10:33 +0330 Subject: [PATCH] add rollcall to checkout --- .../Checkout/CreateCheckout.cs | 12 ++ .../CheckoutApplication.cs | 147 ++++++++++++++---- .../Pages/Company/Checkouts/Index.cshtml.cs | 15 +- 3 files changed, 145 insertions(+), 29 deletions(-) diff --git a/CompanyManagment.App.Contracts/Checkout/CreateCheckout.cs b/CompanyManagment.App.Contracts/Checkout/CreateCheckout.cs index dee0bc11..514fd4fd 100644 --- a/CompanyManagment.App.Contracts/Checkout/CreateCheckout.cs +++ b/CompanyManagment.App.Contracts/Checkout/CreateCheckout.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using CompanyManagment.App.Contracts.Contract; using CompanyManagment.App.Contracts.Employee; +using CompanyManagment.App.Contracts.RollCall; using CompanyManagment.App.Contracts.YearlySalary; using Microsoft.AspNetCore.Mvc.Rendering; @@ -138,4 +139,15 @@ public class CreateCheckout public string ShiftWork { get; set; } + + public List GroupedRollCalls { get; set; } + + public TimeSpan TotalWorkingTimeSpan { get; set; } + + public TimeSpan TotalBreakTimeSpan { get; set; } + + public TimeSpan TotalPresentTimeSpan { get; set; } + public TimeSpan TotalPaidLeave { get; set; } + public TimeSpan TotalSickLeave { get; set; } + } \ No newline at end of file diff --git a/CompanyManagment.Application/CheckoutApplication.cs b/CompanyManagment.Application/CheckoutApplication.cs index 80d050c2..dc58170f 100644 --- a/CompanyManagment.Application/CheckoutApplication.cs +++ b/CompanyManagment.Application/CheckoutApplication.cs @@ -14,6 +14,13 @@ using CompanyManagment.App.Contracts.Checkout; using CompanyManagment.App.Contracts.PersonalContractingParty; using CompanyManagment.App.Contracts.Leave; using CompanyManagment.App.Contracts.MandantoryHours; +using _0_Framework.Domain.CustomizeCheckoutShared.ValueObjects; +using Company.Domain.EmployeeAgg; +using CompanyManagment.App.Contracts.HolidayItem; +using CompanyManagment.App.Contracts.RollCall; +using CompanyManagment.EFCore.Migrations; +using CompanyManagment.EFCore.Repository; +using System.Globalization; namespace CompanyManagment.Application; @@ -28,11 +35,12 @@ public class CheckoutApplication : ICheckoutApplication private readonly IMandatoryHoursApplication _mandatoryHoursApplication; private readonly IRollCallMandatoryRepository _rollCallMandatoryRepository; private readonly IRollCallRepository _rollCallRepository; + private readonly IHolidayItemApplication _holidayItemApplication; public CheckoutApplication(ICheckoutRepository checkoutRepository, IYearlySalaryRepository yearlySalaryRepository, ILeftWorkRepository leftWorkRepository, - IEmployerRepository employerRepository, IPersonalContractingPartyApp contractingPartyApp, ILeaveApplication leaveApplication, IMandatoryHoursApplication mandatoryHoursApplication, IRollCallMandatoryRepository rollCallMandatoryRepository, IRollCallRepository rollCallRepository) + IEmployerRepository employerRepository, IPersonalContractingPartyApp contractingPartyApp, ILeaveApplication leaveApplication, IMandatoryHoursApplication mandatoryHoursApplication, IRollCallMandatoryRepository rollCallMandatoryRepository, IRollCallRepository rollCallRepository, IHolidayItemApplication holidayItemApplication) { _checkoutRepository = checkoutRepository; _yearlySalaryRepository = yearlySalaryRepository; @@ -43,6 +51,7 @@ public class CheckoutApplication : ICheckoutApplication _mandatoryHoursApplication = mandatoryHoursApplication; _rollCallMandatoryRepository = rollCallMandatoryRepository; _rollCallRepository = rollCallRepository; + _holidayItemApplication = holidayItemApplication; } [SuppressMessage("ReSharper.DPA", "DPA0007: Large number of DB records", MessageId = "count: 241")] @@ -131,7 +140,7 @@ public class CheckoutApplication : ICheckoutApplication //} #endregion - + var dayliWage = command.DayliWage.MoneyToDouble(); // کمک هزینه اقلام var consumableItem = command.ConsumableItems.MoneyToDouble(); @@ -191,33 +200,117 @@ public class CheckoutApplication : ICheckoutApplication command.InstallmentDeduction = loanInstallments.Sum(x => x.AmountForMonth.MoneyToDouble()); - var checkoutRollCallDays= _rollCallRepository.GetEmployeeRollCallsForMonth(command.EmployeeId, - command.WorkshopId, command.ContractStartGr, command.ContractEndGr).Select(x=>new CheckoutRollCallDay(x.DateTimeGr,x.StartDate1, - x.EndDate1,x.StartDate2,x.EndDate2,x.BreakTimeTimeSpan,x.IsSliced,x.TotalhourseSpan,x.IsAbsent,x.IsFriday,x.IsHoliday,x.LeaveType)).ToList(); - - - double mandatoryHours = _mandatoryHoursApplication.GetMandatoryHoursByYearAndMonth(syear,smonth); + double mandatoryHours = _mandatoryHoursApplication.GetMandatoryHoursByYearAndMonth(syear, smonth); int mandatoryWholeHours = (int)mandatoryHours; int mandatoryMinutes = (int)((mandatoryHours - mandatoryWholeHours) * 60); - var totalWorking = new TimeSpan(checkoutRollCallDays.Sum(y => y.WorkingTimeSpan.Ticks)); - var totalBreakTime = new TimeSpan(checkoutRollCallDays.Sum(y => y.BreakTimeSpan.Ticks)); - TimeSpan totalPresent = totalWorking + totalBreakTime; - - if (command.HasRollCall) - { - totalWorking = new TimeSpan(checkoutRollCallDays.Sum(x => x.WorkingTimeSpan.Ticks)) - x.TotalHourlyLeave; - totalBreakTime = new TimeSpan(checkoutRollCallDays.Sum(x => x.BreakTimeSpan.Ticks)); - totalPresent = totalWorking + totalBreakTime; - } - else - { - totalBreakTime = new TimeSpan(checkoutRollCallDays.Sum(x => x.BreakTimeSpan.Ticks)); - totalPresent = new TimeSpan(checkoutRollCallDays.Sum(x => x.WorkingTimeSpan.Ticks)); - totalWorking = totalPresent - totalBreakTime; - } TimeSpan totalMandatorySpan = TimeSpan.FromHours(mandatoryHours).Add(TimeSpan.FromMinutes(mandatoryMinutes)); - var checkoutRollCall = new CheckoutRollCall(totalMandatorySpan, totalPresent, totalBreakTime, totalWorking,,,checkoutRollCallDays); + var firstDayOfMonth = $"{command.ContractStart.Substring(0, 8)}01".ToGeorgianDateTime(); + var firstDayOfCurrentMonth = new DateTime(syear, smonth, 1, new PersianCalendar()); + + + + + + + firstDayOfMonth.AddMonthsFa(-1, out var lastDayOfCurrentMonth); + + lastDayOfCurrentMonth = lastDayOfCurrentMonth.AddDays(-1); + + int dateRange = (int)(lastDayOfCurrentMonth - firstDayOfCurrentMonth).TotalDays + 1; + + var holidays = _holidayItemApplication.Search(new HolidayItemSearchModel() + { + HolidayYear = command.ContractStartGr.ToFarsiYear() + }); + //all the dates from start to end, to be compared with present days to get absent dates + var completeDaysList = Enumerable.Range(0, dateRange).Select(offset => firstDayOfCurrentMonth.AddDays(offset).Date).ToList(); + + var absentRecords = completeDaysList + .ExceptBy(rollCalls.Select(x => x.ShiftDate.Date), y => y.Date) + .Select(x => + { + var leave = leaves.FirstOrDefault(y => + y.EmployeeId == employeeId && y.EndLeave.Date >= x.Date && y.StartLeave.Date <= x.Date); + var isHoliday = holidays.Any(y => y.HolidaydateGr == x.Date); + var isFriday = x.Date.DayOfWeek == DayOfWeek.Friday; + var isNormalWorkingDay = isHoliday == false && isFriday == false; + return new CheckoutDailyRollCallViewModel() + { + StartDate1 = null, + EndDate1 = null, + DateTimeGr = x.Date, + DayOfWeek = x.Date.DayOfWeek.ToString(), + RollCallDateFa = x.Date.ToFarsi(), + LeaveType = leave != null ? leave.LeaveType : "", + IsAbsent = leave == null && isNormalWorkingDay + }; + }); + + var presentDays = rollCalls.GroupBy(x => x.ShiftDate.Date).Select(x => + { + + var orderedRollcalls = x.OrderBy(y => y.ShiftDate); + + var rollCallTimeSpanPerDay = + new TimeSpan(x.Where(y => y.EndDate != null).Sum(y => (y.EndDate - y.StartDate)!.Value.Ticks)); + TimeSpan breakTimePerDay; + if (startMonthDay > endFarvardin) + breakTimePerDay = RollCallMandatoryRepository.CalculateBreakTime(x.First().BreakTimeSpan, rollCallTimeSpanPerDay); + else + breakTimePerDay = RollCallMandatoryRepository.CalculateBreakTime(breakTime, rollCallTimeSpanPerDay); + + return new CheckoutDailyRollCallViewModel() + { + StartDate1 = orderedRollcalls.FirstOrDefault().StartDate.Value.ToString("HH:mm"), + EndDate1 = orderedRollcalls.FirstOrDefault().EndDate.Value.ToString("HH:mm"), + + StartDate2 = orderedRollcalls.Skip(1).FirstOrDefault()?.StartDate?.ToString("HH:mm") ?? "", + EndDate2 = orderedRollcalls.Skip(1).FirstOrDefault()?.EndDate?.ToString("HH:mm") ?? "", + + TotalhourseSpan = rollCallTimeSpanPerDay - breakTimePerDay, + + BreakTimeTimeSpan = breakTimePerDay, + + DayOfWeek = x.Key.DayOfWeek.DayOfWeeKToPersian(), + RollCallDateFa = x.Key.Date.ToFarsi(), + DateTimeGr = x.Key.Date, + IsSliced = x.Count() > 2, + IsAbsent = false + }; + }); + + + presentDays = presentDays.Select(x => new CheckoutDailyRollCallViewModel + { + StartDate1 = x.StartDate1, + EndDate1 = x.EndDate1, + EndDate2 = x.EndDate2, + StartDate2 = x.StartDate2, + TotalWorkingHours = $"{(int)(x.TotalhourseSpan.TotalHours)}:{x.TotalhourseSpan.Minutes.ToString("00")}", + BreakTimeString = $"{(int)(x.BreakTimeTimeSpan.TotalHours)}:{x.BreakTimeTimeSpan.Minutes.ToString("00")}", + TotalhourseSpan = x.TotalhourseSpan, + BreakTimeTimeSpan = x.BreakTimeTimeSpan, + DayOfWeek = x.DayOfWeek, + RollCallDateFa = x.RollCallDateFa, + DateTimeGr = x.DateTimeGr, + IsSliced = x.IsSliced, + IsAbsent = false + }); + + var result = presentDays.Concat(absentRecords).OrderBy(x => x.DateTimeGr).ToList(); + result.ForEach(x => + { + x.IsHoliday = holidays.Any(y => x.DateTimeGr.Date == y.HolidaydateGr.Date); + x.IsFriday = x.DateTimeGr.DayOfWeek == DayOfWeek.Friday; + }); + + + + var checkoutRollCallDays = command.GroupedRollCalls.Select(x => new CheckoutRollCallDay()) + + var checkoutRollCall = new CheckoutRollCall(totalMandatorySpan, command.TotalPresentTimeSpan, command.TotalPresentTimeSpan, + command.TotalWorkingTimeSpan, command.TotalPaidLeave, command.TotalSickLeave, checkoutRollCallDays); @@ -365,7 +458,7 @@ public class CheckoutApplication : ICheckoutApplication { totalWorking = new TimeSpan(x.MonthlyRollCall.Sum(x => x.TotalhourseSpan.Ticks)) - x.TotalHourlyLeave; totalBreakTime = new TimeSpan(x.MonthlyRollCall.Sum(x => x.BreakTimeTimeSpan.Ticks)); - totalPresent = totalWorking + totalBreakTime ; + totalPresent = totalWorking + totalBreakTime; } else { @@ -409,7 +502,7 @@ public class CheckoutApplication : ICheckoutApplication { totalWorking = new TimeSpan(result.MonthlyRollCall.Sum(x => x.TotalhourseSpan.Ticks)) - result.TotalHourlyLeave; totalBreakTime = new TimeSpan(result.MonthlyRollCall.Sum(x => x.BreakTimeTimeSpan.Ticks)); - totalPresent = totalWorking + totalBreakTime ; + totalPresent = totalWorking + totalBreakTime; } else { diff --git a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs index 030752a4..4943ecb4 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs +++ b/ServiceHost/Areas/Admin/Pages/Company/Checkouts/Index.cshtml.cs @@ -56,7 +56,7 @@ public class IndexModel : PageModel private readonly IWorkshopApplication _workshopApplication; private readonly IYearlySalaryApplication _yearlySalaryApplication; private readonly IYearlySalaryRepository _yearlySalaryRepository; - + public List chekoutlist; public List ComputingView; @@ -966,7 +966,18 @@ public class IndexModel : PageModel TotalDayOfBunosesCompute = bunosesPay.Bunoses > 0 ? $"{bunosesPay.TotalDayCompute}" : "0", HolidayWorking = workshop.WorkshopHolidayWorking, ShiftWork = workingHours.ShiftWork, - }; + + TotalWorkingTimeSpan=mandatoryCompute.TotalWorkingTimeSpan, + + TotalBreakTimeSpan=mandatoryCompute.TotalBreakTimeSpan, + + TotalPresentTimeSpan=mandatoryCompute.TotalPresentTimeSpan, + + TotalPaidLeave=mandatoryCompute.TotalPaidLeave, + + TotalSickLeave=mandatoryCompute.TotalSickLeave, + + }; _checkoutApplication.Create(command); //var workshopId = $"{contract.WorkshopIds}";