using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application; using _0_Framework_b.Application; using Company.Domain.CheckoutAgg; using Company.Domain.ContractAgg; using Company.Domain.EmployeeAgg; using Company.Domain.JobAgg; using Company.Domain.LeftWorkAgg; using Company.Domain.LeftWorkTempAgg; using Company.Domain.RollCallEmployeeAgg; using Company.Domain.RollCallEmployeeStatusAgg; using Company.Domain.WorkshopAgg; using CompanyManagment.App.Contracts.Checkout; using CompanyManagment.App.Contracts.Contract; using CompanyManagment.App.Contracts.LeftWork; using CompanyManagment.App.Contracts.LeftWorkTemp; using CompanyManagment.App.Contracts.ReportClient; using CompanyManagment.App.Contracts.RollCallEmployee; using CompanyManagment.EFCore.Migrations; using OperationResult = _0_Framework.Application.OperationResult; using Tools = _0_Framework.Application.Tools; namespace CompanyManagment.Application; public class LeftWorkTempApplication : ILeftWorkTempApplication { private readonly ILeftWorkTempRepository _leftWorkTempRepository; private readonly ILeftWorkRepository _leftWorkRepository; private readonly IWorkshopRepository _workshopRepository; private readonly IEmployeeRepository _employeeRepository; private readonly IJobRepository _jobRepository; private readonly ICheckoutRepository _checkoutRepository; private readonly IContractRepository _contractRepository; private readonly IRollCallEmployeeRepository _rollCallEmployeeRepository; private readonly IRollCallEmployeeStatusRepository _rollCallEmployeeStatusRepository; public LeftWorkTempApplication(ILeftWorkTempRepository leftWorkTempRepository, ILeftWorkRepository leftWorkRepository, IWorkshopRepository workshopRepository, IEmployeeRepository employeeRepository, IJobRepository jobRepository, ICheckoutRepository checkoutRepository, IContractRepository contractRepository, IRollCallEmployeeStatusRepository rollCallEmployeeStatusRepository, IRollCallEmployeeRepository rollCallEmployeeRepository) { _leftWorkTempRepository = leftWorkTempRepository; _leftWorkRepository = leftWorkRepository; _workshopRepository = workshopRepository; _employeeRepository = employeeRepository; _jobRepository = jobRepository; _checkoutRepository = checkoutRepository; _contractRepository = contractRepository; _rollCallEmployeeStatusRepository = rollCallEmployeeStatusRepository; _rollCallEmployeeRepository = rollCallEmployeeRepository; } public async Task Create(CreateLeftWorkTemp command) { var op = new OperationResult(); foreach (var employeeId in command.EmployeeIds) { #region Validation if (_leftWorkTempRepository.Exists(x => x.WorkshopId == command.WorkshopId && x.EmployeeId == employeeId)) { return op.Failed("برای پرسنل وارد شده قبلا درخواست ترک کار ثبت کرده اید"); } if (command.LeftWorkTime.TryToGeorgianDateTime(out var leftWorkDateGr) == false) { return op.Failed("تاریخ شروع به کار وارد شده نامعتبر است"); } if (command.LastDayStanding.TryToGeorgianDateTime(out var lastDayStandingDateGr) == false) { return op.Failed("تاریخ شروع به کار وارد شده نامعتبر است"); } var leftWork = await _leftWorkRepository.GetLastLeftWork(employeeId, command.WorkshopId); if (lastDayStandingDateGr.AddDays(1).Date != leftWorkDateGr) { return op.Failed("تاریخ آخرین روز کاری با تاریخ ترک کار یک روز اختلاف ندارند"); } if (leftWork == null) { return op.Failed("شروع به کار پرسنل یافت نشد"); } if (leftWork.HasLeft) { return op.Failed("پرسنل وارد شده قبلا ترک کار ثبت شده است"); } if (leftWork.StartWorkDate > lastDayStandingDateGr) { return op.Failed("تاریخ ثبت شده قبل از شروع به کار است"); } if (leftWork.WorkshopId != command.WorkshopId || leftWork.EmployeeId != employeeId) { return op.Failed("اطلاعات وارد شده نامعتبر است"); } //if (leftWork.StartWorkDate >= leftWorkDateGr) //{ // return op.Failed("ترک کار نمیتواند کوچک تر یا مساوی شروع به کار باشد"); //} //if (_checkoutRepository.Exists(x => x.EmployeeId == leftWorkTemp.EmployeeId && // x.WorkshopId == leftWorkTemp.WorkshopId && // x.ContractStart <= lastDayStandingGr && x.ContractEnd >= lastDayStandingGr)) //{ // return op.Failed("این پرسنل در تاریخ ترک کار وارد شده دارای فیش حقوقی میباشد. ابتدا فیش حقوقی پرسنل را حذف کنید "); //} //if (_contractRepository.Exists(x => x.EmployeeId == leftWorkTemp.EmployeeId && // x.WorkshopIds == leftWorkTemp.WorkshopId && // x.ContarctStart <= lastDayStandingGr && x.ContractEnd >= lastDayStandingGr)) //{ // return op.Failed("این پرسنل در تاریخ ترک کار وارد شده دارای قرارداد میباشد"); //} #endregion var leftWorkTemp = LeftWorkTemp.CreateLeftWork(leftWork.id, leftWork.StartWorkDate, leftWorkDateGr, lastDayStandingDateGr, command.WorkshopId, employeeId, leftWork.JobId); await _leftWorkTempRepository.CreateAsync(leftWorkTemp); } await _leftWorkTempRepository.SaveChangesAsync(); return op.Succcedded(); } public Task GetStartAndLeftWorkDetails(long employeeId, long workshopId) { return _leftWorkTempRepository.GetStartAndLeftWorkDetails(employeeId, workshopId); } public async Task AcceptStartWork(AcceptStartWorkTemp command) { var op = new OperationResult(); if (command.StartDateTime.TryToGeorgianDateTime(out var startDateGr) == false) { return op.Failed("تاریخ شروع به کار وارد شده نامعتبر است"); } var leftWorkTemp = _leftWorkTempRepository.Get(command.LeftWorkTempId); if (leftWorkTemp.LeftWorkType != LeftWorkTempType.StartWork) { return op.Failed("اطلاعات وارد شده نامعتبر است"); } if (_leftWorkRepository.Exists(x => x.WorkshopId == leftWorkTemp.WorkshopId && x.EmployeeId == leftWorkTemp.EmployeeId && x.LeftWorkDate >= startDateGr)) { return op.Failed("شروع به کار وارد شده با ترک کار های قبلی تداخل دارد"); } if (_jobRepository.Exists(x => x.id == command.JobId) == false) { return op.Failed("سمت وارد شده نامعتبر است"); } var defaultTime = new DateTime(2121, 03, 21); var workshop = _workshopRepository.Get(leftWorkTemp.WorkshopId); var employee = _employeeRepository.Get(leftWorkTemp.EmployeeId); var newLeftWork = new LeftWork(defaultTime, startDateGr, leftWorkTemp.WorkshopId, leftWorkTemp.EmployeeId, employee.FullName, workshop.WorkshopFullName, command.JobId, false, false, false, false, "", ""); await _leftWorkRepository.CreateAsync(newLeftWork); _leftWorkTempRepository.Remove(leftWorkTemp); var rollCallEmployee = _rollCallEmployeeRepository.GetBy(leftWorkTemp.EmployeeId, leftWorkTemp.WorkshopId); var rollCallStatus = rollCallEmployee?.EmployeesStatus.MaxBy(x => x.StartDate); if (rollCallStatus != null) { var startWork = newLeftWork.StartWorkDate; rollCallStatus.Edit(startWork, rollCallStatus.EndDate); } await _leftWorkRepository.SaveChangesAsync(); await _leftWorkTempRepository.SaveChangesAsync(); return op.Succcedded(); } public async Task AcceptLeftWork(AcceptLeftWorkTemp command) { var op = new OperationResult(); if (command.LeftWorkTime.TryToGeorgianDateTime(out var leftWorkDateGr) == false) { return op.Failed("تاریخ ترک کار وارد شده نامعتبر است"); } if (command.LastDayStanding.TryToGeorgianDateTime(out var lastDayStandingGr) == false) { return op.Failed("تاریخ آخرین روز کاری وارد شده نامعتبر است"); } if (lastDayStandingGr.AddDays(1).Date != leftWorkDateGr) { return op.Failed("تاریخ آخرین روز کاری با تاریخ ترک کار یک روز اختلاف ندارند"); } var leftWorkTemp = _leftWorkTempRepository.Get(command.LeftWorkTempId); if (leftWorkTemp == null) { return op.Failed("ترک کار وارد شده یافت نشد"); } if (leftWorkTemp.LeftWorkType != LeftWorkTempType.LeftWork) { return op.Failed("اطلاعات وارد شده نامعتبر است"); } var leftWork = _leftWorkRepository.Get(leftWorkTemp.LeftWorkId); if (leftWork == null) return op.Failed("شروع به کار پرسنل یافت نشد"); if (leftWork.StartWorkDate >= leftWorkDateGr) { return op.Failed("ترک کار نمیتواند کوچک تر یا مساوی شروع به کار باشد"); } if (_checkoutRepository.Exists(x => x.EmployeeId == leftWorkTemp.EmployeeId && x.WorkshopId == leftWorkTemp.WorkshopId && x.ContractStart <= lastDayStandingGr && x.ContractEnd >= lastDayStandingGr)) { return op.Failed( "این پرسنل در تاریخ ترک کار وارد شده دارای فیش حقوقی میباشد. ابتدا فیش حقوقی پرسنل را حذف کنید "); } var transaction = await _rollCallEmployeeStatusRepository.BeginTransactionAsync(); leftWork.Edit(leftWorkDateGr, leftWork.StartWorkDate, leftWork.WorkshopId, leftWork.EmployeeId, leftWork.JobId, leftWork.IncludeStatus, leftWork.AddBonusesPay, leftWork.AddYearsPay, leftWork.AddLeavePay); _leftWorkTempRepository.Remove(leftWorkTemp); await _leftWorkRepository.SaveChangesAsync(); await _leftWorkTempRepository.SaveChangesAsync(); IfEmployeeHasNewLeftWorkDateAddEndDateToRollCallStatus(leftWork.EmployeeId, leftWork.WorkshopId); await transaction.CommitAsync(); return op.Succcedded(); } public async Task> GetLeftWorkTempsByEmployeeId(long employeeId) { return await _leftWorkTempRepository.GetLeftWorkTempsByEmployeeId(employeeId); } public List GetLeftWorksByWorkshopId(long workshopId) { return _leftWorkTempRepository.GetLeftWorksByWorkshopId(workshopId); } //این متد ترک کار های کارمند را با فعالیت حضور غیاب یکپارچه می کند private void IfEmployeeHasNewLeftWorkDateAddEndDateToRollCallStatus(long employeeId, long workshopId) { //get last leftworks for employee in all workshops var leftWorks = _leftWorkRepository.search(new LeftWorkSearchModel() { EmployeeId = employeeId, WorkshopId = workshopId }) .Select(x => new LeftWorkViewModel() { EmployeeId = employeeId, WorkshopId = x.WorkshopId, LeftWorkDateGr = x.LeftWorkDateGr.Date.AddDays(-1), StartWorkDateGr = x.StartWorkDateGr }).ToList(); var maxLeftWork = leftWorks.MaxBy(y => y.StartWorkDateGr); //get rollCallEmployee associated with those leftworks which have a higher end date than leftworkDate var rollCallsEmployee = _rollCallEmployeeRepository.GetBy(employeeId, workshopId); if (rollCallsEmployee != null) { var status = rollCallsEmployee.EmployeesStatus.OrderByDescending(z => z.StartDate) .FirstOrDefault(rollCallEmployeeStatus => rollCallEmployeeStatus.StartDate.Date < maxLeftWork.LeftWorkDateGr && rollCallEmployeeStatus.EndDate.Date > maxLeftWork.LeftWorkDateGr); if (status != null) { var adjust = new AdjustRollCallEmployeesWithEmployeeLeftWork() { LeaveDate = maxLeftWork.LeftWorkDateGr, RollCallStatusId = status.id }; _rollCallEmployeeStatusRepository.AdjustRollCallStatusEndDates([adjust]); } var rollCallEmployeeStatusList = rollCallsEmployee.EmployeesStatus .Where(x => x.StartDate >= maxLeftWork.LeftWorkDateGr).ToList(); if (rollCallEmployeeStatusList.Any()) { _rollCallEmployeeStatusRepository.RemoveRange(rollCallEmployeeStatusList); _rollCallEmployeeStatusRepository.SaveChanges(); } } // var joinedList = rollCallsEmployee.Join(leftWorks, x => x.WorkshopId, y => y.WorkshopId, (x, y) => new // { // x.WorkshopId, // x.EmployeeId, // y.LeftWorkDateGr, // Status = x.Statuses.OrderByDescending(z => z.StartDate).FirstOrDefault(z => z.StartDateGr.Date < y.LeftWorkDateGr && z.EndDateGr.Date > y.LeftWorkDateGr) // }); } }