using GozareshgirProgramManager.Application._Common.Interfaces; using GozareshgirProgramManager.Application._Common.Models; using GozareshgirProgramManager.Application.Modules.Checkouts.Queries.GetUserToGropCreate; using GozareshgirProgramManager.Domain._Common; using GozareshgirProgramManager.Domain.CheckoutAgg.Entities; using GozareshgirProgramManager.Domain.CheckoutAgg.Enums; using GozareshgirProgramManager.Domain.CheckoutAgg.Repositories; using GozareshgirProgramManager.Domain.ProjectAgg.Repositories; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.DTOs; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Enums; using GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Repositories; using GozareshgirProgramManager.Domain.UserAgg.Entities; using MediatR; using PersianTools.Core; using System.Runtime.InteropServices; using Microsoft.EntityFrameworkCore; using Shared.Contracts.Holidays; namespace GozareshgirProgramManager.Application.Modules.Checkouts.Commands.CreateCheckout; public class CreateOrEditCheckoutCommandHandler : IBaseCommandHandler { private readonly ICheckoutRepository _checkoutRepository; private readonly ISalaryPaymentSettingRepository _salaryPaymentSettingRepository; private readonly ITaskSectionActivityRepository _taskSectionActivityRepository; private readonly IUnitOfWork _unitOfWork; private readonly IHolidayQueryService _holidayQueryService; public CreateOrEditCheckoutCommandHandler(ICheckoutRepository checkoutRepository, IUnitOfWork unitOfWork, ISalaryPaymentSettingRepository salaryPaymentSettingRepository, ITaskSectionActivityRepository taskSectionActivityRepository, IHolidayQueryService holidayQueryService) { _checkoutRepository = checkoutRepository; _unitOfWork = unitOfWork; _salaryPaymentSettingRepository = salaryPaymentSettingRepository; _taskSectionActivityRepository = taskSectionActivityRepository; _holidayQueryService = holidayQueryService; } public async Task Handle(CreateOrEditCheckoutCommand request, CancellationToken cancellationToken) { switch (request.TypeOfCheckoutHandler) { case TypeOfCheckoutHandler.CreateInGroup: return await Create(request.Year, request.Month, request.UserIdList); break; case TypeOfCheckoutHandler.SingleEdit: case TypeOfCheckoutHandler.GroupEditing: return await GroupOrSingleEditing(request.CheckoutIdList); break; } return OperationResult.Failure("نوع متد انتخاب نشده است"); } /// /// ایجاد گروهی فیش حقوقی /// /// /// /// /// public async Task Create(string? Year, string? Month, List? UserIdList) { if (string.IsNullOrWhiteSpace(Month)) return OperationResult.Failure("ماه خالی است"); if (string.IsNullOrWhiteSpace(Year)) return OperationResult.Failure("سال خالی است"); if (UserIdList == null) return OperationResult.Failure("هیچ موردی برای ایجاد انتخاب نشده اشت"); if (UserIdList.Count == 0) return OperationResult.Failure("هیچ موردی برای ایجاد انتخاب نشده اشت"); var startDateGr = new DateTime(); var EndDateGr = new DateTime(); var persianStart = new PersianDateTime(); int year = 0; int month = 0; try { year = Convert.ToInt32(Year); month = Convert.ToInt32(Month); persianStart = new PersianDateTime(year, month, 1); var startDateFa = $"{persianStart}"; startDateGr = startDateFa.ToGeorgianDateTime(); var endDateFa = startDateFa.FindeEndOfMonth(); EndDateGr = endDateFa.ToGeorgianDateTime(); } catch (Exception) { return OperationResult.Failure( "خطا در ورود سال و ماه"); } var totalDays = Convert.ToInt32((EndDateGr - startDateGr).TotalDays + 1); var getAllSettings = await _salaryPaymentSettingRepository.GetAllSettings(UserIdList); var get = await _taskSectionActivityRepository.GetTotalTimeSpentPerUserInRangeAsync(startDateGr, EndDateGr); foreach (var user in getAllSettings) { var totalWorked = get.FirstOrDefault(x => x.UserId == user.UserId); var totalTimeTotalMinutes = (int)totalWorked.TotalTime.TotalMinutes; var res = await ComputeSalary(user.WorkingHoursListDto, totalTimeTotalMinutes, user.MonthlySalary, startDateGr, EndDateGr, user.HolidayWorking); var createCheckout = new Checkout(startDateGr, EndDateGr, year, month, user.FullName, user.UserId, res.MandatoryHours, totalTimeTotalMinutes, totalDays, res.RemainingHours, user.MonthlySalary, res.MonthlySalaryPay, res.DeductionFromSalary); await _checkoutRepository.CreateAsync(createCheckout); } await _unitOfWork.SaveChangesAsync(); return OperationResult.Success(); } /// /// متد ویراش گروهی و تکی /// /// /// /// /// public async Task GroupOrSingleEditing(List? CheckoutIdList) { if (CheckoutIdList == null) return OperationResult.Failure("هیچ موردی برای ویرایش انتخاب نشده اشت"); if (CheckoutIdList.Count == 0) return OperationResult.Failure("هیچ موردی برای ویرایش انتخاب نشده اشت"); var checkouts = await _checkoutRepository.GetCheckoutListByIds(CheckoutIdList); if (!checkouts.Any()) return OperationResult.Failure("هیچ موردی برای ویرایش انتخاب نشده اشت"); var UserIdList = checkouts.Select(x => x.UserId).ToList(); var getAllSettings = await _salaryPaymentSettingRepository.GetAllSettings(UserIdList); if (!getAllSettings.Any()) return OperationResult.Failure("تنظیمات ساعت و حقوق یافت نشد"); foreach (var checkoutId in CheckoutIdList) { var checkout = checkouts.FirstOrDefault(x => x.Id == checkoutId); if (checkout == null) return OperationResult.Failure("فیش مورد نظر یافت نشد"); var userSetting = getAllSettings.FirstOrDefault(x => x.UserId == checkout.UserId); var get = await _taskSectionActivityRepository.GetTotalTimeSpentByUserInRangeAsync(checkout.UserId, checkout.CheckoutStartDate, checkout.CheckoutEndDate); var totalTimeTotalMinutes = (int)get.TotalMinutes; var totalDays = Convert.ToInt32((checkout.CheckoutEndDate - checkout.CheckoutStartDate).TotalDays + 1); var res = await ComputeSalary(userSetting.WorkingHoursListDto, totalTimeTotalMinutes, userSetting.MonthlySalary, checkout.CheckoutStartDate, checkout.CheckoutEndDate, userSetting.HolidayWorking); checkout.Edit(res.MandatoryHours, totalTimeTotalMinutes, totalDays, res.RemainingHours, userSetting.MonthlySalary, res.MonthlySalaryPay, res.DeductionFromSalary); await _unitOfWork.SaveChangesAsync(); } return OperationResult.Success(); } /// /// محاسبه حقوق /// /// public async Task ComputeSalary(List workingHoursListDto, int totalHoursWorked, double monthlySalaryDefined, DateTime start, DateTime end, bool holidayWorking) { var startDate = start.ToFarsi(); var startYear = Convert.ToInt32(startDate.Substring(0, 4)); var startMonth = Convert.ToInt32(startDate.Substring(5, 2)); var startDay = Convert.ToInt32(startDate.Substring(8, 2)); var persianStart = new PersianDateTime(startYear, startMonth, startDay); var endDate = end.ToFarsi(); var endYear = Convert.ToInt32(endDate.Substring(0, 4)); var endMonth = Convert.ToInt32(endDate.Substring(5, 2)); var endDay = Convert.ToInt32(endDate.Substring(8, 2)); var persianEnd = new PersianDateTime(endYear, endMonth, endDay); var holidays = await _holidayQueryService.GetHolidaysInDates(start, end); int mandatoryHours = 0; for (var currentDay = persianStart; currentDay <= persianEnd; currentDay = currentDay.AddDays(1)) { var currentDayOfWeek = new DNTPersianUtils.Core.PersianDateTime(currentDay.Year, currentDay.Month, currentDay.Day); var holidayDate = currentDay.ShamsiDate.ToGeorgianDateTime(); var day = (PersianDayOfWeek)currentDayOfWeek.WeekDayNumber!; var getDaySetting = workingHoursListDto.FirstOrDefault(x => x.PersianDayOfWeek == day); if (getDaySetting != null) { if (!holidayWorking && holidays.Any(x => x.Holidaydate == holidayDate)) { } else { mandatoryHours += (int)getDaySetting.ShiftDuration.TotalMinutes; Console.WriteLine((int)getDaySetting.ShiftDuration.TotalMinutes + " " + currentDay + " - " + day); } } } ////حقوق نهایی //var monthlySalaryPay = (totalHoursWorked * monthlySalaryDefined) / mandatoryHours; //// اگر اضافه کار داشت حقوق تعین شده به عنوان حقوق نهایی در نظر گرفته میشود //monthlySalaryPay = monthlySalaryPay > monthlySalaryDefined ? monthlySalaryDefined : monthlySalaryPay; ////حقوق کسر شده //var deductionFromSalary = monthlySalaryDefined - monthlySalaryPay; //new chang salary compute var monthlySalaryPay = totalHoursWorked * monthlySalaryDefined; //زمان باقی مانده var remainingTime = totalHoursWorked - mandatoryHours; //تناسب به دقیقه #region MyRegion //var monthlySalaryDefinedTest = monthlySalaryDefined * mandatoryHours; //var monthlySalaryPayTest = totalHoursWorked * monthlySalaryDefined; ////// اگر اضافه کار داشت حقوق تعین شده به عنوان حقوق نهایی در نظر گرفته میشود //monthlySalaryPayTest = monthlySalaryPayTest > monthlySalaryDefinedTest ? monthlySalaryDefinedTest : monthlySalaryPayTest; //////حقوق کسر شده //var deductionFromSalaryTest = monthlySalaryDefinedTest - monthlySalaryPayTest; #endregion var computeResult = new ComputeResultDto { MandatoryHours = mandatoryHours, MonthlySalaryPay = monthlySalaryPay, DeductionFromSalary = 0 /*deductionFromSalary*/, RemainingHours = remainingTime }; Console.WriteLine(mandatoryHours); return computeResult; } } public record CreateOrEditCheckoutCommand(TypeOfCheckoutHandler TypeOfCheckoutHandler, string? Year, string? Month, List? UserIdList, List? CheckoutIdList) : IBaseCommand; public record ComputeResultDto { /// /// ساعات باقی مانده /// کسر کار یا اضافه کار /// public int RemainingHours { get; set; } /// /// حقوق نهایی که به پرسنل داده می شود /// public double MonthlySalaryPay { get; set; } /// /// کسر از حقوق /// public double DeductionFromSalary { get; set; } /// /// ساعت موظفی /// public int MandatoryHours { get; set; } }