Files
Backend-Api/CompanyManagment.Application/CustomizeCheckoutApplication.cs

382 lines
20 KiB
C#

using _0_Framework.Application;
using Company.Domain.ContractAgg;
using Company.Domain.CustomizeCheckoutAgg;
using Company.Domain.CustomizeWorkshopSettingsAgg;
using Company.Domain.EmployeeAgg;
using Company.Domain.LeftWorkAgg;
using Company.Domain.RollCallAgg;
using Company.Domain.RollCallEmployeeStatusAgg;
using Company.Domain.WorkshopAgg;
using CompanyManagment.App.Contracts.CustomizeCheckout;
using CompanyManagment.App.Contracts.LeftWork;
using CompanyManagment.App.Contracts.RollCallEmployeeStatus;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Company.Domain.CheckoutAgg;
using Company.Domain.CustomizeCheckoutAgg.ValueObjects;
using Company.Domain.CustomizeCheckoutTempAgg;
using Company.Domain.PersonnelCodeAgg;
using CompanyManagment.App.Contracts.PersonnleCode;
using Company.Domain.CustomizeWorkshopGroupSettingsAgg;
namespace CompanyManagment.Application
{
public class CustomizeCheckoutApplication : ICustomizeCheckoutApplication
{
private readonly ICustomizeCheckoutRepository _customizeCheckoutRepository;
private readonly IEmployeeRepository _employeeRepository;
private readonly ILeftWorkRepository _leftWorkRepository;
private readonly IRollCallMandatoryRepository _rollCallMandatoryRepository;
private readonly IRollCallEmployeeStatusRepository _rollCallEmployeeStatusRepository;
private readonly IPersonnelCodeRepository _personnelCodeRepository;
private readonly IContractRepository _contractRepository;
private readonly IWorkshopRepository _workshopRepository;
private readonly ICustomizeWorkshopSettingsRepository _customizeWorkshopSettingsRepository;
private readonly ICustomizeCheckoutTempRepository _customizeCheckoutTempRepository;
private readonly ICheckoutRepository _checkoutRepository;
private readonly ICustomizeWorkshopGroupSettingsRepository _customizeWorkshopGroupSettingsRepository;
public CustomizeCheckoutApplication(ICustomizeCheckoutRepository customizeCheckoutRepository,
IRollCallEmployeeStatusRepository rollCallEmployeeStatusRepository, ILeftWorkRepository leftWorkRepository, IEmployeeRepository employeeRepository,
IRollCallMandatoryRepository rollCallMandatoryRepository, IContractRepository contractRepository, IWorkshopRepository workshopRepository, ICustomizeWorkshopSettingsRepository customizeWorkshopSettingsRepository, IPersonnelCodeRepository personnelCodeRepository, ICustomizeCheckoutTempRepository customizeCheckoutTempRepository, ICheckoutRepository checkoutRepository, ICustomizeWorkshopGroupSettingsRepository customizeWorkshopGroupSettingsRepository)
{
_customizeCheckoutRepository = customizeCheckoutRepository;
_rollCallEmployeeStatusRepository = rollCallEmployeeStatusRepository;
_leftWorkRepository = leftWorkRepository;
_employeeRepository = employeeRepository;
_rollCallMandatoryRepository = rollCallMandatoryRepository;
_contractRepository = contractRepository;
_workshopRepository = workshopRepository;
_customizeWorkshopSettingsRepository = customizeWorkshopSettingsRepository;
_personnelCodeRepository = personnelCodeRepository;
_customizeCheckoutTempRepository = customizeCheckoutTempRepository;
_checkoutRepository = checkoutRepository;
_customizeWorkshopGroupSettingsRepository = customizeWorkshopGroupSettingsRepository;
}
public List<CustomizeCheckoutViewModel> Search(SearchCustomizeCheckout searchModel)
{
if (!string.IsNullOrWhiteSpace(searchModel.SearchStartFa) || !string.IsNullOrWhiteSpace(searchModel.SearchEndFa))
{
if (!searchModel.SearchStartFa.TryToGeorgianDateTime(out DateTime start) ||
!searchModel.SearchEndFa.TryToGeorgianDateTime(out DateTime end))
return new();
if (start > end)
return new();
}
return _customizeCheckoutRepository.Search(searchModel).ToList();
}
public OperationResult Create(CreateCustomizeCheckout command)
{
OperationResult op = new();
DateTime.Today.AddMonthsFa(0, out DateTime firstOfCurrentMonth);
if (command.ContractEnd >= firstOfCurrentMonth)
return op.Failed("برای ماه جاری یا آینده نمی توانید فیش ایجاد کنید");
var contract = _contractRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, command.EmployeeId, command.ContractStart, command.ContractEnd);
Employee employee = _employeeRepository.Get(command.EmployeeId);
var workshop = _workshopRepository.Get(command.WorkshopId);
//get sumOfWorkingDays
var result = _rollCallMandatoryRepository.CustomizeCheckoutMandatoryCompute(command.EmployeeId, command.WorkshopId, command.ContractStart, command.ContractEnd);
var fines = result.FineViewModels
.Select(x =>
new CustomizeCheckoutFine(
x.Title,
x.Amount,
x.FineDate,
x.FineDate.ToGeorgianDateTime(),
x.IsActive, x.CreationDate.ToGeorgianDateTime(),
x.Id)
).ToList();
var rewards = result.RewardViewModels.Select(x =>
new CustomizeCheckoutReward(x.Amount, x.Description, x.GrantDateGr, x.GrantDateFa,
x.IsActive, x.Title,x.Id)).ToList();
var loanInstallments = result.InstallmentViewModels.Select(x =>
new CustomizeCheckoutLoanInstallments(x.Amount, x.Month, x.Year, x.IsActive, x.RemainingAmount, x.LoanAmount,x.Id)).ToList();
var salaryAids = result.SalaryAidViewModels.Select(x =>
new CustomizeCheckoutSalaryAid(x.Amount, x.SalaryAidDateTimeGe, x.SalaryAidDateTimeFa, x.CalculationDateTimeGe, x.CalculationDateTimeFa,x.Id)).ToList();
var regularShift = result.EmployeeSettingsShifts.Select(x =>
new CustomizeCheckoutRegularShift(x.StartTime, x.EndTime, x.Placement)).ToList();
var entity = new CustomizeCheckout(command.ContractStart, command.ContractEnd, command.EmployeeId, employee.FName, employee.LName, employee.DateOfBirth, employee.NationalCode,
workshop.WorkshopFullName, command.WorkshopId, contract?.Id,
result.MonthlySalary, result.FridayPay, result.OverTimePay, result.BaseYearsPay,
result.BonusesPay, result.NightWorkPay, result.MarriedAllowance, result.ShiftPay,
result.FamilyAllowance, result.LeavePay, result.InsuranceDeduction, result.FineAbsenceDeduction,
result.LateToWorkDeduction, result.EarlyExitDeduction, result.RewardPay, result.SalaryAidDeduction, result.InstallmentDeduction, result.FineDeduction,
result.TaxDeduction, result.SumOfWorkingDays, result.TotalClaimsStr, result.TotalDeductionsStr, result.TotalPayment, contract?.ContractNo ?? "-",
fines, loanInstallments, salaryAids, rewards, result.LateToWorkValue, result.SettingSalary, result.DailyWage, result.ShiftStatus, result.IrregularShift, result.CustomizeRotatingShifts,
regularShift);
_customizeCheckoutRepository.Create(entity);
_customizeCheckoutRepository.RemoveEmployeeCustomizeCheckoutInDates(command.WorkshopId, employee.id, command.ContractStart, command.ContractEnd);
_customizeCheckoutRepository.SaveChanges();
return op.Succcedded();
}
public (bool Checkout, bool CustomizeCheckout, bool CustomizeCheckoutTemp) ValidateExistsCheckouts(DateTime startDate,
DateTime endDate, long workshopId, List<long> employeeId)
{
return _customizeCheckoutRepository.ValidateExistsCheckouts(startDate, endDate, workshopId, employeeId);
}
public OperationResult GroupCreate(CreateCustomizeCheckoutGroup command)
{
OperationResult op = new();
var contracts = _contractRepository
.GetByWorkshopIdInDates(command.WorkshopId, command.ContractStart, command.ContractEnd);
var employees = _employeeRepository.GetRangeByIds(command.EmployeeIds);
var workshop = _workshopRepository.Get(command.WorkshopId);
foreach (var employeeId in command.EmployeeIds)
{
var computations = _rollCallMandatoryRepository
.CustomizeCheckoutMandatoryCompute(employeeId, command.WorkshopId, command.ContractStart, command.ContractEnd);
var contract = contracts.Where(x => x.IsActiveString == "true").FirstOrDefault(x => x.EmployeeId == employeeId);
var employee = employees.FirstOrDefault(x => x.id == employeeId);
var fines = computations.FineViewModels
.Select(x =>
new CustomizeCheckoutFine(
x.Title,
x.Amount,
x.FineDate,
x.FineDate.ToGeorgianDateTime(),
x.IsActive, x.CreationDate.ToGeorgianDateTime(), x.Id)
).ToList();
var rewards = computations.RewardViewModels.Select(x =>
new CustomizeCheckoutReward(x.Amount, x.Description, x.GrantDateGr, x.GrantDateFa,
x.IsActive, x.Title,x.Id)).ToList();
var loanInstallments = computations.InstallmentViewModels.Select(x =>
new CustomizeCheckoutLoanInstallments(x.Amount, x.Month, x.Year, x.IsActive, x.RemainingAmount, x.LoanAmount, x.Id)).ToList();
var salaryAids = computations.SalaryAidViewModels.Select(x =>
new CustomizeCheckoutSalaryAid(x.Amount, x.SalaryAidDateTimeGe, x.SalaryAidDateTimeFa, x.CalculationDateTimeGe, x.CalculationDateTimeFa,x.Id)).ToList();
var regularShift = computations.EmployeeSettingsShifts.Select(x =>
new CustomizeCheckoutRegularShift(x.StartTime, x.EndTime, x.Placement)).ToList();
var entity = new CustomizeCheckout(command.ContractStart, command.ContractEnd, employeeId, employee.FName, employee.LName, employee.DateOfBirth, employee.NationalCode,
workshop.WorkshopFullName, command.WorkshopId, contract?.Id,
computations.MonthlySalary, computations.FridayPay, computations.OverTimePay, computations.BaseYearsPay,
computations.BonusesPay, computations.NightWorkPay, computations.MarriedAllowance, computations.ShiftPay,
computations.FamilyAllowance, computations.LeavePay, computations.InsuranceDeduction, computations.FineAbsenceDeduction,
computations.LateToWorkDeduction, computations.EarlyExitDeduction, computations.RewardPay, computations.SalaryAidDeduction, computations.InstallmentDeduction, computations.FineDeduction,
computations.TaxDeduction, computations.SumOfWorkingDays, computations.TotalClaimsStr, computations.TotalDeductionsStr, computations.TotalPayment, contract?.ContractNo ?? "-",
fines, loanInstallments, salaryAids, rewards, computations.LateToWorkValue, computations.SettingSalary, computations.DailyWage, computations.ShiftStatus, computations.IrregularShift,
computations.CustomizeRotatingShifts, regularShift);
_customizeCheckoutRepository.Create(entity);
_customizeCheckoutRepository.RemoveEmployeeCustomizeCheckoutInDates(command.WorkshopId, employeeId, command.ContractStart, command.ContractEnd);
}
_customizeCheckoutRepository.SaveChanges();
return op.Succcedded();
}
public OperationResult GroupRemove(long workshopId, List<long> idList)
{
OperationResult op = new();
var entities = _customizeCheckoutRepository.GetRange(workshopId, idList);
if (entities == null)
return op.Succcedded();
_customizeCheckoutRepository.RemoveRange(entities);
_customizeCheckoutRepository.SaveChanges();
return op.Succcedded();
}
public List<CustomizeCheckoutViewModel> PrintAll(long workshopId, List<long> checkoutIds)
{
if (checkoutIds == null || checkoutIds.Count == 0)
return new();
//var start = new DateTime(yearFa, monthFa, 1, new PersianCalendar());
//var end = start.AddMonthsFa(1, out _).ToGeorgianDateTime().Date.AddTicks(-1);
//var allCheckouts = Search(new SearchCustomizeCheckout()
//{
// WorkshopId = workshopId,
//});
//if (checkoutIds.Any(x => !allCheckouts.Any(y => y.Id == x)))
//{
// return new();
//}
return _customizeCheckoutRepository.PrintAll(workshopId, checkoutIds);
}
public OperationResult<List<EligibleEmployeesForCustomizeCheckoutViewModel>> GetWorkshopEmployeesEligibleForCheckoutInDates
(long workshopId, int yearFa, int monthFa)
{
OperationResult<List<EligibleEmployeesForCustomizeCheckoutViewModel>> op = new();
//validate month and year
if (yearFa < 1398 || yearFa > 1550 || monthFa < 1 || monthFa > 12)
return op.Failed("خطای سیستمی");
var pc = new PersianCalendar();
var checkoutDate = new DateTime(yearFa, monthFa, 1, pc);
var nextMonth = checkoutDate.AddMonthsFa(1, out _).ToGeorgianDateTime().Date;
var today = DateTime.Today;
if (nextMonth > today)
return op.Failed("امکان ایجاد فیش برای ماه جاری یا آینده وجود ندارد");
//validate parsed datetime
var startOfMonth = new DateTime(yearFa, monthFa, 1, new PersianCalendar()).Date;
// var endOfMonth = startOfMonth.AddMonthsFa(1, out _).ToGeorgianDateTime().Date.AddTicks(-1);
var endOfMonth = $"{yearFa:0000}/{monthFa:00}/01".FindeEndOfMonth().ToGeorgianDateTime();
var workshopLeftWorksInMonth = _leftWorkRepository.GetByWorkshopIdInDates(workshopId, startOfMonth, endOfMonth)
.Select(x => new LeftWorkViewModel
{
WorkshopId = workshopId,
EmployeeId = x.EmployeeId,
LeftWorkDateGr = x.LeftWorkDateGr.AddDays(-1).Date > endOfMonth ? endOfMonth : x.LeftWorkDateGr.AddDays(-1).Date,
StartWorkDateGr = x.StartWorkDateGr.Date < startOfMonth ? startOfMonth : x.StartWorkDateGr.Date
}).ToList();
var statuses = _rollCallEmployeeStatusRepository.GetByWorkshopIdInDates(workshopId, startOfMonth, endOfMonth)
.Select(x => new RollCallEmployeeStatusViewModel
{
EmployeeId = x.EmployeeId,
EmployeeName = x.EmployeeName,
Id = x.Id,
EndDate = x.EndDate,
StartDate = x.StartDate,
EndDateGr = x.EndDateGr > endOfMonth ? endOfMonth : x.EndDateGr.Date,
StartDateGr = x.StartDateGr < startOfMonth ? startOfMonth : x.StartDateGr.Date
}).ToList();
var customizeCheckouts = _customizeCheckoutRepository.GetByWorkshopIdInDates(workshopId, startOfMonth, endOfMonth);
var personnelCodes = _personnelCodeRepository.Search(new PersonnelCodeSearchModel()
{
WorkshopId = workshopId
});
var workshopGroups = _customizeWorkshopSettingsRepository
.GetWorkshopIncludeGroupsByWorkshopId(workshopId)?
.GroupSettings.Where(x => x.MainGroup == false);
var employeeSettings = _customizeWorkshopSettingsRepository.GetEmployeeSettingsByWorkshopId(workshopId);
if (pc.GetYear(today) == yearFa && pc.GetMonth(today) == monthFa)
{
workshopLeftWorksInMonth = workshopLeftWorksInMonth.Where(x => x.LeftWorkDateGr.Date <= today).ToList();
}
var statusesWithActiveLeftWorks = statuses
.Where(status => workshopLeftWorksInMonth.Any(leftWork => leftWork.EmployeeId == status.EmployeeId &&
leftWork.StartWorkDateGr.Date <= status.EndDateGr.Date &&
leftWork.LeftWorkDateGr.Date >= status.StartDateGr.Date)).ToList();
var employeesWithCheckout = statusesWithActiveLeftWorks.Where(x => customizeCheckouts.Any(y => y.EmployeeId == x.EmployeeId));
var eligibleEmloyees = statusesWithActiveLeftWorks.Where(x => !employeesWithCheckout.Any(y => y.EmployeeId == x.EmployeeId));
//var employeesWithoutGroup = employeeSettings.Where(x => statusesWithActiveLeftWorks.Any(y => y.EmployeeId == x.EmployeeId)
//&& (x.GroupSettingsId == 0 || !workshopGroups.Any(y => x.GroupSettingsId == y.Id))).Select(x => x.EmployeeId).ToList();
var employeesWithoutGroup = statusesWithActiveLeftWorks.Where(x => employeeSettings.All(y => y.EmployeeId != x.EmployeeId || y.GroupSettingsId == 0 ||
!workshopGroups.Any(z => y.GroupSettingsId == z.Id))).Select(x => x.EmployeeId).ToList();
eligibleEmloyees = eligibleEmloyees.Where(x => !employeesWithoutGroup.Contains(x.EmployeeId));
var employeesWithoutSalary = employeeSettings.Where(x => statusesWithActiveLeftWorks.Any(y => y.EmployeeId == x.EmployeeId)
&& x.Salary <= 0).ToList();
eligibleEmloyees = eligibleEmloyees.Where(x => !employeesWithoutSalary.Any(y => y.EmployeeId == x.EmployeeId));
#region CustomForKebabMahdi
if (workshopId == 170)
{
var exceptionEmployeeIds = _customizeWorkshopGroupSettingsRepository
.GetEmployeeSettingsByGroupSettingsId(117)
.Select(x => x.EmployeeId)
.Where(x=> workshopLeftWorksInMonth.Select(l=>l.EmployeeId).Contains(x)).ToList();
foreach (var employeesId in exceptionEmployeeIds)
{
var status = new RollCallEmployeeStatusViewModel()
{
EmployeeId = employeesId,
};
statusesWithActiveLeftWorks.Add(status);
}
}
#endregion
if (!statusesWithActiveLeftWorks.Any())
return op.Failed("امکان ایجاد فیش برای تاریخ انتخاب شده وجود ندارد");
var employees = _employeeRepository.SimpleGetRangeByIds(statusesWithActiveLeftWorks.Select(x => x.EmployeeId))
.Select(x =>
{
bool isEligible = eligibleEmloyees.Any(y => x.Id == y.EmployeeId);
string reason = "";
string color = "";
if (isEligible == false)
{
reason = employeesWithCheckout.Any(y => y.EmployeeId == x.Id) ? "دارای فیش غیر رسمی" :
employeesWithoutGroup.Any(y => y == x.Id) ? "فاقد گروهبندی" :
employeesWithoutSalary.Any(y => y.EmployeeId == x.Id) ? "فاقد تعیین حقوق" : "خطای سیستمی";
}
color = reason switch
{
"فاقد تعیین حقوق" => "orange",
"فاقد گروهبندی" => "red",
"خطای سیستمی" => "black",
"دارای فیش غیر رسمی" => "green",
_ => "white"
};
return new EligibleEmployeesForCustomizeCheckoutViewModel()
{
Id = x.Id,
Name = x.Name,
IsEligible = isEligible,
Reason = reason,
Color = color,
PersonnelCode = personnelCodes.FirstOrDefault(y => x.Id == y.EmployeeId)?.PersonnelCode.ToString() ?? "-"
};
}).OrderByDescending(x => x.IsEligible).ThenByDescending(x => x.Reason).ToList();
return op.Succcedded(employees);
}
}
}