280 lines
12 KiB
C#
280 lines
12 KiB
C#
|
|
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<CreateOrEditCheckoutCommand>
|
|
{
|
|
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<OperationResult> 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("نوع متد انتخاب نشده است");
|
|
}
|
|
|
|
/// <summary>
|
|
/// ایجاد گروهی فیش حقوقی
|
|
/// </summary>
|
|
/// <param name="Year"></param>
|
|
/// <param name="Month"></param>
|
|
/// <param name="UserIdList"></param>
|
|
/// <returns></returns>
|
|
public async Task<OperationResult> Create(string? Year, string? Month, List<long>? 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<GetUserToGroupCreatingResponse>.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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// متد ویراش گروهی و تکی
|
|
/// </summary>
|
|
/// <param name="CheckoutIdList"></param>
|
|
/// <param name="CheckoutId"></param>
|
|
/// <param name="TypeOfCheckoutHandler"></param>
|
|
/// <returns></returns>
|
|
public async Task<OperationResult> GroupOrSingleEditing(List<Guid>? 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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// محاسبه حقوق
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<ComputeResultDto> ComputeSalary(List<WorkingHoursListDto> 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<long>? UserIdList, List<Guid>? CheckoutIdList) : IBaseCommand;
|
|
|
|
public record ComputeResultDto
|
|
{
|
|
|
|
/// <summary>
|
|
/// ساعات باقی مانده
|
|
/// کسر کار یا اضافه کار
|
|
/// </summary>
|
|
public int RemainingHours { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
/// حقوق نهایی که به پرسنل داده می شود
|
|
/// </summary>
|
|
public double MonthlySalaryPay { get; set; }
|
|
|
|
/// <summary>
|
|
/// کسر از حقوق
|
|
/// </summary>
|
|
public double DeductionFromSalary { get; set; }
|
|
|
|
/// <summary>
|
|
/// ساعت موظفی
|
|
/// </summary>
|
|
public int MandatoryHours { get; set; }
|
|
}
|