using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using _0_Framework.Application; using _0_Framework.Domain.CustomizeCheckoutShared.Enums; using _0_Framework.Exceptions; using Company.Domain.CheckoutAgg; using Company.Domain.CustomizeCheckoutAgg; using Company.Domain.CustomizeCheckoutTempAgg; using Company.Domain.CustomizeWorkshopEmployeeSettingsAgg; using Company.Domain.CustomizeWorkshopSettingsAgg; using Company.Domain.EmployeeAgg; using Company.Domain.LeaveAgg; using Company.Domain.RollCallAgg; using Company.Domain.RollCallAgg.DomainService; using Company.Domain.RollCallEmployeeAgg; using Company.Domain.WorkshopAgg; using CompanyManagement.Infrastructure.Excel.RollCall; using CompanyManagment.App.Contracts.Checkout; using CompanyManagment.App.Contracts.Employee; using CompanyManagment.App.Contracts.RollCall; namespace CompanyManagment.Application; public class RollCallApplication : IRollCallApplication { private readonly IRollCallRepository _rollCallRepository; private readonly IRollCallEmployeeRepository _rollCallEmployeeRepository; private readonly IEmployeeRepository _employeeRepository; private readonly ILeaveRepository _leaveRepository; private readonly ICustomizeCheckoutRepository _customizeCheckoutRepository; private readonly ICheckoutRepository _checkoutRepository; private readonly IRollCallDomainService _rollCallDomainService; private readonly ICustomizeWorkshopSettingsRepository _customizeWorkshopSettingsRepository; private readonly ICustomizeWorkshopEmployeeSettingsRepository _customizeWorkshopEmployeeSettingsRepository; private readonly ICustomizeCheckoutTempRepository _customizeCheckoutTempRepository; private readonly IWorkshopRepository _workshopRepository; public RollCallApplication(IRollCallRepository rollCallRepository, IRollCallEmployeeRepository rollCallEmployeeRepository, IEmployeeRepository employeeRepository, ILeaveRepository leaveRepository, ICustomizeCheckoutRepository customizeCheckoutRepository, ICheckoutRepository checkoutRepository, IRollCallDomainService rollCallDomainService, ICustomizeWorkshopSettingsRepository customizeWorkshopSettingsRepository, ICustomizeWorkshopEmployeeSettingsRepository customizeWorkshopEmployeeSettingsRepository, ICustomizeCheckoutTempRepository customizeCheckoutTempRepository, IWorkshopRepository workshopRepository) { _rollCallRepository = rollCallRepository; _rollCallEmployeeRepository = rollCallEmployeeRepository; _employeeRepository = employeeRepository; _leaveRepository = leaveRepository; _customizeCheckoutRepository = customizeCheckoutRepository; _checkoutRepository = checkoutRepository; _rollCallDomainService = rollCallDomainService; _customizeWorkshopSettingsRepository = customizeWorkshopSettingsRepository; _customizeWorkshopEmployeeSettingsRepository = customizeWorkshopEmployeeSettingsRepository; _customizeCheckoutTempRepository = customizeCheckoutTempRepository; _workshopRepository = workshopRepository; } public OperationResult Create(CreateRollCall command) { var opration = new OperationResult(); var startDateFa = command.StartDate.ToFarsi(); var yearFa = Convert.ToInt32(startDateFa.Substring(0, 4)); var monthFa = Convert.ToInt32(startDateFa.Substring(5, 2)); var employeeName = _employeeRepository.GetDetails(command.EmployeeId).EmployeeFullName; var create = new RollCall(command.WorkshopId, command.EmployeeId, employeeName, command.StartDate.Value, null, yearFa, monthFa, _rollCallDomainService); _rollCallRepository.Create(create); _rollCallRepository.SaveChanges(); return opration.Succcedded(); } public OperationResult Edit(long id) { var opration = new OperationResult(); var personRollCall = _rollCallRepository.Get(id); if (personRollCall == null) opration.Failed("رکورد مورد نظر وجود ندارد"); var now = DateTime.Now; personRollCall.SetEndDateTime(now, _rollCallDomainService); _rollCallRepository.SaveChanges(); return opration.Succcedded(); } public EditRollCall GetByEmployeeIdAndWorkshopId(long employeeId, long workshopId) { return _rollCallRepository.GetByEmployeeIdAndWorkshopId(employeeId, workshopId); } public EditRollCall GetById(long id) { return _rollCallRepository.GetById(id); } public EmployeeRollCallsByMonthViewModel GetEmployeeRollCallsHistoryForPrint(long employeeId, long workshopId, string firstRollCallDateFa, string lastRollCallDateFa) { if (firstRollCallDateFa.TryToGeorgianDateTime(out var firstRollCallDate) == false || lastRollCallDateFa.TryToGeorgianDateTime(out var lastRollCallDate) == false) return new(); if (firstRollCallDate > lastRollCallDate) return new(); if (lastRollCallDate.Date >= DateTime.Now.Date) return new(); return _rollCallRepository.GetEmployeeRollCallsHistoryForPrint(employeeId, workshopId, firstRollCallDate, lastRollCallDate); } #region Pooya public TimeSpan GetEmployeeRollCallTimeSpanForDuration(long employeeId, long workshopId, string startFa, string endFa) { if (startFa.TryToGeorgianDateTime(out DateTime startDateTime) == false) return TimeSpan.Zero; if (endFa.TryToGeorgianDateTime(out DateTime endDateTime) == false) return TimeSpan.Zero; if (startDateTime > endDateTime) return TimeSpan.Zero; return _rollCallRepository.GetEmployeeRollCallTimeSpanForDuration(employeeId, workshopId, startDateTime, endDateTime); } public List GetOverlappedRollCallsWithLeaveInDates(long workshopId, DateTime start, DateTime end) { return _rollCallRepository.GetOverlappedRollCallsWithLeaveInDates(workshopId, start, end); } public List GetUndefinedRollCallWorkFlowsService(long workshopId, DateTime durationStart, DateTime durationEnd) { return _rollCallRepository.GetUndefinedRollCallWorkFlowsInDates(workshopId, durationStart, durationEnd); } public OperationResult RemoveEmployeeRollCallsInDate(long workshopId, long employeeId, string dateFa) { OperationResult op = new(); var date = dateFa.ToGeorgianDateTime(); if (date == Tools.GetUndefinedDateTime()) return op.Failed("خطای سیستمی"); _rollCallRepository.RemoveEmployeeRollCallsInDate(workshopId, employeeId, date); _rollCallRepository.SaveChanges(); return op.Succcedded(); } public RollCallsByDateViewModel GetWorkshopRollCallHistory(RollCallSearchModel searchModel) { return _rollCallRepository.GetWorkshopRollCallHistory(searchModel); } public CurrentDayRollCall GetWorkshopCurrentDayRollCalls(long workshopId) { return _rollCallRepository.GetWorkshopCurrentDayRollCalls(workshopId); } public List GetActiveEmployeeRollCallsForDuration(long employeeId, long workshopId, string startDate, string endDate) { if (!string.IsNullOrWhiteSpace(startDate) || !string.IsNullOrWhiteSpace(endDate)) return new(); var startDateGr = startDate.ToGeorgianDateTime(); var endDateGr = endDate.ToGeorgianDateTime(); if (startDateGr >= endDateGr) return new(); //if (!_rollCallEmployeeRepository.Exists(x => x.EmployeeId == employeeId && // x.WorkshopId == workshopId && x.IsActiveString == "true")) // return new(); return _rollCallRepository.GetEmployeeRollCallsForMonth(employeeId, workshopId, startDateGr, endDateGr); } public EmployeeRollCallsByMonthViewModel GetEmployeeRollCallsHistory(long employeeId, long workshopId, string startDateTime, string endDateTime, string exactDateTime, string dateIndex) { DateTime? startDateTimeGr = null; DateTime? endDateTimeGr = null; if (!string.IsNullOrWhiteSpace(startDateTime) && !string.IsNullOrWhiteSpace(endDateTime)) { startDateTimeGr = startDateTime.ToGeorgianDateTime(); endDateTimeGr = endDateTime.ToGeorgianDateTime(); if (endDateTimeGr < startDateTimeGr) { return new(); } } DateTime? exactDateTimeGr = !string.IsNullOrWhiteSpace(exactDateTime) ? exactDateTime.ToGeorgianDateTime() : null; DateTime? index = null; if (!string.IsNullOrWhiteSpace(dateIndex)) { index = dateIndex.ToGeorgianDateTime(); index = (index.Value.Date >= DateTime.Now) || (index.Value == new DateTime(3000, 12, 20, new PersianCalendar())) ? null : index; } return _rollCallRepository.GetEmployeeRollCallsHistory(employeeId, workshopId, startDateTimeGr, endDateTimeGr, exactDateTimeGr, index); } /// /// افزودن حضور غیاب به صورت دستی. اگر آیدی رکورد صفر باشد رکورد جدید، در غیر این صورت ویرایش می کند /// /// #region ManualEditWithDates //public OperationResult ManualEdit(CreateOrEditEmployeeRollCall command) //{ // var operation = new OperationResult(); // DateTime date = command.DateFa.ToGeorgianDateTime(); // if (date == Tools.GetUndefinedDateTime()) // return operation.Failed("فرمت تاریخ وارد شده صحیح نمی باشد"); // if (date >= DateTime.Now.Date) // { // return operation.Failed("امکان اضافه کردن حضور غیاب برای روز جاری و روز های آینده وجود ندارد"); // } // var twoDaysEarlier = date.AddDays(-2).Date; // var twoDaysLater = date.AddDays(2).Date >= DateTime.Today // ? (date.AddDays(1).Date >= DateTime.Today ? DateTime.Today : date.AddDays(1).Date) // : date.AddDays(2).Date; // if (command.WorkshopId < 1) // { // return operation.Failed("خطای سیستمی"); // } // if (command.RollCallRecords == null || command.RollCallRecords.Count == 0) // return operation.Failed("خطای سیستمی"); // if (_leaveRepository.HasDailyLeave(command.EmployeeId, command.WorkshopId, date)) // return operation.Failed("در روز مرخصی کارمند نمی توانید حضور غیاب ثبت کنید"); // var employeeStatuses = _rollCallEmployeeRepository.GetByEmployeeIdWithStatuses(command.EmployeeId) // .FirstOrDefault(x => x.WorkshopId == command.WorkshopId)?.Statuses; // var employeeRollCalls = _rollCallRepository.GetEmployeeRollCallsHistoryAllInDates(command.WorkshopId, command.EmployeeId, twoDaysEarlier, twoDaysLater); // //if (employeeRollCalls.Any(x => x.StartDate.Value.Date== x.EndDate == null)) // // return operation.Failed("به دلیل عدم ثبت خروج پرسنل در این تاریخ، شما قادر به افزودن رکورد جدید نمی باشید"); // if (command.RollCallRecords.Any(x => string.IsNullOrWhiteSpace(x.StartTime) || string.IsNullOrWhiteSpace(x.EndTime))) // return operation.Failed("ساعات شروع و پایان نمیتوانند خالی باشد"); // DateTime day = command.DateFa.ToGeorgianDateTime(); // if (day == Tools.GetUndefinedDateTime()) // return operation.Failed("خطای سیستمی"); // List newRollCallDates = new(); // foreach (var record in command.RollCallRecords) // { // if (record.StartDate.TryToGeorgianDateTime(out var startDateGr) == false || record.EndDate.TryToGeorgianDateTime(out var endDateGr) == false) // return operation.Failed("فرمت تاریخ صحیح نمی باشد"); // if (TimeOnly.TryParse(record.StartTime, out var startTimeOnly) == false || TimeOnly.TryParse(record.EndTime, out var endTimeOnly) == false) // return operation.Failed("فرمت ساعت صحیح نمی باشد"); // DateTime startDateTime = startDateGr + startTimeOnly.ToTimeSpan(); // DateTime endDateTime = endDateGr + endTimeOnly.ToTimeSpan(); // if (startDateTime >= endDateTime) // return operation.Failed("زمان ورود نمی تواند بعد یا مساوی زمان خروج باشد"); // if (endDateTime.Date >= DateTime.Today) // return operation.Failed("نمی توانید برای روز جاری یا روز های آینده حضور غیاب ثبت کنید"); // var rollCall = new EditRollCall // { // StartDate = startDateTime, // EndDate = endDateTime, // Id = record.RollCallId // }; // newRollCallDates.Add(rollCall); // } // if (newRollCallDates.Any(x => newRollCallDates.Any(y => x != y && x.EndDate >= y.StartDate && x.StartDate <= y.EndDate))) // return operation.Failed("بازه های وارد شده با هم تداخل دارند"); // foreach (var activity in newRollCallDates) // { // //مرخصی روزانه در بالا چک شده است // var leave = _leaveRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, command.EmployeeId, activity.StartDate.Value, activity.EndDate.Value) // .Where(x => x.PaidLeaveType == "ساعتی"); // if (leave.Any()) // return operation.Failed("کارمند در بازه انتخاب شده مرخصی ساعتی دارد"); // } // if (newRollCallDates == null || !newRollCallDates.All(x => employeeStatuses.Any(y => x.StartDate >= y.StartDateGr && x.EndDate <= y.EndDateGr))) // return operation.Failed("کارمند در بازه وارد شده غیر فعال است"); // if (newRollCallDates.Any(x => // x.StartDate.Value.Date < date.Date.AddDays(-1) || // x.EndDate.Value.Date > date.Date.AddDays(1))) // { // return operation.Failed("حضور غیاب در حال ویرایش را نمیتوانید بیشتر از یک روز از ثبت حضور غیاب عقب تر یا جلو تر ببرید"); // } // if (newRollCallDates.Any(x => employeeRollCalls.Any(y => // y.StartDate.Value.Date != command.DateFa.ToGeorgianDateTime().Date && // x.EndDate >= y.StartDate.Value && x.StartDate <= y.EndDate.Value))) // return operation.Failed("بازه های وارد شده با حضور غیاب های مربوط به روز های قبل و بعد تداخل زمانی دارد"); // var checkoutViewModels = _checkoutRepository.SimpleSearch(new CheckoutSearchModel() { WorkshopId = command.WorkshopId, EmployeeId = command.EmployeeId }); // if (checkoutViewModels.Any(x => x.HasRollCall && x.WorkshopId == command.WorkshopId && x.EmployeeId == command.EmployeeId && // newRollCallDates.Any(y => (y.StartDate.Value.Date >= x.ContractStartGr.Date) // && (y.StartDate.Value.Date <= x.ContractEndGr.Date)))) // return operation.Failed("برای بازه های وارد شده فیش حقوقی ثبت شده است"); // var name = _rollCallEmployeeRepository.GetByEmployeeIdAndWorkshopId(command.EmployeeId, command.WorkshopId).EmployeeFullName; // var rollCallsAsEntityModels = newRollCallDates.Select(x => new RollCall(command.WorkshopId, command.EmployeeId, name, x.StartDate, x.EndDate, // Convert.ToInt32(x.StartDate.Value.ToFarsi().Substring(0, 4)), Convert.ToInt32(x.StartDate.ToFarsi().Substring(5, 2)), RollCallModifyType.EditByEmployer)).ToList(); // _rollCallRepository.RemoveEmployeeRollCallsInDate(command.WorkshopId, command.EmployeeId, date); // _rollCallRepository.AddRange(rollCallsAsEntityModels); // _rollCallRepository.SaveChanges(); // return operation.Succcedded(); //} #endregion #region ManualEditWithDates public OperationResult ManualEdit(CreateOrEditEmployeeRollCall command) { var operation = new OperationResult(); var now = DateTime.Now; DateTime date = command.DateFa.ToGeorgianDateTime(); if (date == Tools.GetUndefinedDateTime()) return operation.Failed("فرمت تاریخ وارد شده صحیح نمی باشد"); //if (date >= DateTime.Now.Date) //{ // return operation.Failed("امکان اضافه کردن حضور غیاب برای روز جاری و روز های آینده وجود ندارد"); //} var twoDaysEarlier = date.AddDays(-2).Date; var twoDaysLater = date.AddDays(2).Date >= DateTime.Today ? (date.AddDays(1).Date >= DateTime.Today ? DateTime.Today : date.AddDays(1).Date) : date.AddDays(2).Date; if (command.WorkshopId < 1) { return operation.Failed("خطای سیستمی"); } if (command.RollCallRecords == null || command.RollCallRecords.Count == 0) return operation.Failed("خطای سیستمی"); if (_leaveRepository.HasDailyLeave(command.EmployeeId, command.WorkshopId, date)) return operation.Failed("در روز مرخصی کارمند نمی توانید حضور غیاب ثبت کنید"); var employeeStatuses = _rollCallEmployeeRepository.GetByEmployeeIdWithStatuses(command.EmployeeId) .FirstOrDefault(x => x.WorkshopId == command.WorkshopId)?.Statuses; var employeeRollCalls = _rollCallRepository.GetEmployeeRollCallsHistoryAllInDates(command.WorkshopId, command.EmployeeId, twoDaysEarlier, twoDaysLater); //if (employeeRollCalls.Any(x => x.StartDate.Value.Date== x.EndDate == null)) // return operation.Failed("به دلیل عدم ثبت خروج پرسنل در این تاریخ، شما قادر به افزودن رکورد جدید نمی باشید"); if (command.RollCallRecords.Any(x => string.IsNullOrWhiteSpace(x.StartTime) || string.IsNullOrWhiteSpace(x.EndTime))) return operation.Failed("ساعات شروع و پایان نمیتوانند خالی باشد"); DateTime day = command.DateFa.ToGeorgianDateTime(); var workshopSettings = _customizeWorkshopSettingsRepository.GetBy(command.WorkshopId); var employeeSettings = _customizeWorkshopEmployeeSettingsRepository.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings( command.WorkshopId, command.EmployeeId)?.WorkshopShiftStatus; if (employeeSettings == null && workshopSettings.WorkshopShiftStatus != WorkshopShiftStatus.Regular) { return operation.Failed("لطفا ابتدا برای این پرسنل گروهبندی انجام دهید "); } if (day == Tools.GetUndefinedDateTime()) return operation.Failed("خطای سیستمی"); List newRollCallDates = new(); foreach (var record in command.RollCallRecords) { if (record.StartDate.TryToGeorgianDateTime(out var startDateGr) == false || record.EndDate.TryToGeorgianDateTime(out var endDateGr) == false) return operation.Failed("فرمت تاریخ صحیح نمی باشد"); if (TimeOnly.TryParse(record.StartTime, out var startTimeOnly) == false || TimeOnly.TryParse(record.EndTime, out var endTimeOnly) == false) return operation.Failed("فرمت ساعت صحیح نمی باشد"); DateTime startDateTime = startDateGr + startTimeOnly.ToTimeSpan(); DateTime endDateTime = endDateGr + endTimeOnly.ToTimeSpan(); if (startDateTime >= endDateTime) return operation.Failed("زمان ورود نمی تواند بعد یا مساوی زمان خروج باشد"); //if (endDateTime.Date >= DateTime.Today) // return operation.Failed("نمی توانید برای روز جاری یا روز های آینده حضور غیاب ثبت کنید"); var rollCall = new EditRollCall { StartDate = startDateTime, EndDate = endDateTime, Id = record.RollCallId }; newRollCallDates.Add(rollCall); } if (newRollCallDates.Any(x => x.StartDate >= now || x.EndDate >= now)) { return operation.Failed("حضورغیاب وارد شده نمیتواند در آینده باشد"); } if (newRollCallDates.Any(x => newRollCallDates.Any(y => x != y && x.EndDate >= y.StartDate && x.StartDate <= y.EndDate))) return operation.Failed("بازه های وارد شده با هم تداخل دارند"); foreach (var activity in newRollCallDates) { //مرخصی روزانه در بالا چک شده است var leave = _leaveRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, command.EmployeeId, activity.StartDate.Value, activity.EndDate.Value) .Where(x => x.PaidLeaveType == "ساعتی"); if (leave.Any()) return operation.Failed("کارمند در بازه انتخاب شده مرخصی ساعتی دارد"); } newRollCallDates.ForEach(x => { x.ShiftDate = _rollCallDomainService.GetEmployeeShiftDateByRollCallStartDate(command.WorkshopId, command.EmployeeId, x.StartDate!.Value,x.EndDate.Value); }); if (newRollCallDates == null || !newRollCallDates.All(x => employeeStatuses.Any(y => x.ShiftDate.Date >= y.StartDateGr.Date && x.ShiftDate.Date <= y.EndDateGr.Date))) return operation.Failed("کارمند در بازه وارد شده غیر فعال است"); if (newRollCallDates.Any(x => x.ShiftDate.Date != date.Date)) { return operation.Failed("حضور غیاب در حال ویرایش را نمیتوانید از تاریخ شیفت عقب تر یا جلو تر ببرید"); } if (new TimeSpan(newRollCallDates.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks)) > TimeSpan.FromHours(26)) { return operation.Failed("بازه حضور پرسنل نمی تواند بیشتر از 26 ساعت باشد"); } if (newRollCallDates.Any(x => employeeRollCalls.Any(y => y.ShiftDate.Date != command.DateFa.ToGeorgianDateTime().Date && x.EndDate >= y.StartDate.Value && x.StartDate <= y.EndDate.Value))) return operation.Failed("بازه های وارد شده با حضور غیاب های مربوط به روز های قبل و بعد تداخل زمانی دارد"); var checkoutViewModels = _checkoutRepository.SimpleSearch(new CheckoutSearchModel() { WorkshopId = command.WorkshopId, EmployeeId = command.EmployeeId }); if (checkoutViewModels.Any(x => x.HasRollCall && x.WorkshopId == command.WorkshopId && x.EmployeeId == command.EmployeeId && newRollCallDates.Any(y => (y.StartDate.Value.Date >= x.ContractStartGr.Date) && (y.StartDate.Value.Date <= x.ContractEndGr.Date)))) return operation.Failed("برای بازه های وارد شده فیش حقوقی ثبت شده است"); if (newRollCallDates == null || !newRollCallDates.All(x => employeeStatuses.Any(y => x.ShiftDate.Date >= y.StartDateGr.Date && x.ShiftDate.Date <= y.EndDateGr.Date))) return operation.Failed("کارمند در بازه وارد شده غیر فعال است"); var currentDayRollCall = employeeRollCalls.FirstOrDefault(x => x.EndDate == null); if (currentDayRollCall != null && newRollCallDates.Any(x => x.EndDate!.Value >= currentDayRollCall.StartDate)) return operation.Failed("بازه های وارد شده با حضور غیاب جاری تداخل زمانی دارد"); var name = _rollCallEmployeeRepository.GetByEmployeeIdAndWorkshopId(command.EmployeeId, command.WorkshopId).EmployeeFullName; var rollCallsAsEntityModels = newRollCallDates.Select(x => new RollCall(command.WorkshopId, command.EmployeeId, name, x.StartDate!.Value, x.EndDate, Convert.ToInt32(x.StartDate.Value.ToFarsi().Substring(0, 4)), Convert.ToInt32(x.StartDate.ToFarsi().Substring(5, 2)), _rollCallDomainService, RollCallModifyType.EditByEmployer)).ToList(); _rollCallRepository.RemoveEmployeeRollCallsInDate(command.WorkshopId, command.EmployeeId, date); _rollCallRepository.AddRange(rollCallsAsEntityModels); _rollCallRepository.SaveChanges(); foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) { rollCallsAsEntityModel.ClearTimeDiff(); rollCallsAsEntityModel.SetShiftDate(_rollCallDomainService); } _rollCallRepository.SaveChanges(); foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) { rollCallsAsEntityModel.Edit(rollCallsAsEntityModel.StartDate.Value, rollCallsAsEntityModel.EndDate.Value, _rollCallDomainService); } _rollCallRepository.SaveChanges(); return operation.Succcedded(); } public OperationResult ManualEditForUndefined(CreateOrEditEmployeeRollCall command) { var operation = new OperationResult(); var now = DateTime.Now; DateTime date = command.DateFa.ToGeorgianDateTime(); if (date == Tools.GetUndefinedDateTime()) return operation.Failed("فرمت تاریخ وارد شده صحیح نمی باشد"); //if (date >= DateTime.Now.Date) //{ // return operation.Failed("امکان اضافه کردن حضور غیاب برای روز جاری و روز های آینده وجود ندارد"); //} var twoDaysEarlier = date.AddDays(-2).Date; var twoDaysLater = date.AddDays(2).Date >= DateTime.Today ? (date.AddDays(1).Date >= DateTime.Today ? DateTime.Today : date.AddDays(1).Date) : date.AddDays(2).Date; if (command.WorkshopId < 1) { return operation.Failed("خطای سیستمی"); } if (command.RollCallRecords == null || command.RollCallRecords.Count == 0) return operation.Failed("خطای سیستمی"); if (_leaveRepository.HasDailyLeave(command.EmployeeId, command.WorkshopId, date)) return operation.Failed("در روز مرخصی کارمند نمی توانید حضور غیاب ثبت کنید"); var employeeStatuses = _rollCallEmployeeRepository.GetByEmployeeIdWithStatuses(command.EmployeeId) .FirstOrDefault(x => x.WorkshopId == command.WorkshopId)?.Statuses; var employeeRollCalls = _rollCallRepository.GetEmployeeRollCallsHistoryAllInDates(command.WorkshopId, command.EmployeeId, twoDaysEarlier, twoDaysLater); //if (employeeRollCalls.Any(x => x.StartDate.Value.Date== x.EndDate == null)) // return operation.Failed("به دلیل عدم ثبت خروج پرسنل در این تاریخ، شما قادر به افزودن رکورد جدید نمی باشید"); if (command.RollCallRecords.Any(x => string.IsNullOrWhiteSpace(x.StartTime) || string.IsNullOrWhiteSpace(x.EndTime))) return operation.Failed("ساعات شروع و پایان نمیتوانند خالی باشد"); DateTime day = command.DateFa.ToGeorgianDateTime(); var workshopSettings = _customizeWorkshopSettingsRepository.GetBy(command.WorkshopId); var employeeSettings = _customizeWorkshopEmployeeSettingsRepository.GetByEmployeeIdAndWorkshopIdIncludeGroupSettings( command.WorkshopId, command.EmployeeId)?.WorkshopShiftStatus; if (employeeSettings == null && workshopSettings.WorkshopShiftStatus != WorkshopShiftStatus.Regular) { return operation.Failed("لطفا ابتدا برای این پرسنل گروهبندی انجام دهید "); } if (day == Tools.GetUndefinedDateTime()) return operation.Failed("خطای سیستمی"); List newRollCallDates = new(); foreach (var record in command.RollCallRecords) { if (record.StartDate.TryToGeorgianDateTime(out var startDateGr) == false || record.EndDate.TryToGeorgianDateTime(out var endDateGr) == false) return operation.Failed("فرمت تاریخ صحیح نمی باشد"); if (TimeOnly.TryParse(record.StartTime, out var startTimeOnly) == false || TimeOnly.TryParse(record.EndTime, out var endTimeOnly) == false) return operation.Failed("فرمت ساعت صحیح نمی باشد"); DateTime startDateTime = startDateGr + startTimeOnly.ToTimeSpan(); DateTime endDateTime = endDateGr + endTimeOnly.ToTimeSpan(); if (startDateTime >= endDateTime) return operation.Failed("زمان ورود نمی تواند بعد یا مساوی زمان خروج باشد"); //if (endDateTime.Date >= DateTime.Today) // return operation.Failed("نمی توانید برای روز جاری یا روز های آینده حضور غیاب ثبت کنید"); var rollCall = new EditRollCall { StartDate = startDateTime, EndDate = endDateTime, Id = record.RollCallId, }; newRollCallDates.Add(rollCall); } newRollCallDates.ForEach(x => { }); if (newRollCallDates.Any(x => x.StartDate >= now || x.EndDate >= now)) { return operation.Failed("حضورغیاب وارد شده نمیتواند در آینده باشد"); } if (newRollCallDates.Any(x => newRollCallDates.Any(y => x != y && x.EndDate >= y.StartDate && x.StartDate <= y.EndDate))) return operation.Failed("بازه های وارد شده با هم تداخل دارند"); foreach (var activity in newRollCallDates) { //مرخصی روزانه در بالا چک شده است var leave = _leaveRepository.GetByWorkshopIdEmployeeIdInDates(command.WorkshopId, command.EmployeeId, activity.StartDate.Value, activity.EndDate.Value) .Where(x => x.PaidLeaveType == "ساعتی"); if (leave.Any()) return operation.Failed("کارمند در بازه انتخاب شده مرخصی ساعتی دارد"); } newRollCallDates.ForEach(x => { x.ShiftDate = _rollCallDomainService.GetEmployeeShiftDateByRollCallStartDate(command.WorkshopId, command.EmployeeId, x.StartDate!.Value,x.EndDate.Value); }); if (newRollCallDates == null || !newRollCallDates.All(x => employeeStatuses.Any(y => x.ShiftDate.Date >= y.StartDateGr.Date && x.ShiftDate.Date <= y.EndDateGr.Date))) return operation.Failed("کارمند در بازه وارد شده غیر فعال است"); if (newRollCallDates.Any(x => x.ShiftDate.Date != date.Date)) { return operation.Failed("حضور غیاب در حال ویرایش را نمیتوانید از تاریخ شیفت عقب تر یا جلو تر ببرید"); } if (new TimeSpan(newRollCallDates.Sum(x => (x.EndDate.Value - x.StartDate.Value).Ticks)) > TimeSpan.FromHours(26)) { return operation.Failed("بازه حضور پرسنل نمی تواند بیشتر از 26 ساعت باشد"); } if (newRollCallDates.Any(x => employeeRollCalls.Any(y => y.ShiftDate.Date != command.DateFa.ToGeorgianDateTime().Date && x.EndDate >= y.StartDate.Value && x.StartDate <= y.EndDate.Value))) return operation.Failed("بازه های وارد شده با حضور غیاب های مربوط به روز های قبل و بعد تداخل زمانی دارد"); var checkoutViewModels = _checkoutRepository.SimpleSearch(new CheckoutSearchModel() { WorkshopId = command.WorkshopId, EmployeeId = command.EmployeeId }); if (checkoutViewModels.Any(x => x.HasRollCall && x.WorkshopId == command.WorkshopId && x.EmployeeId == command.EmployeeId && newRollCallDates.Any(y => (y.StartDate.Value.Date >= x.ContractStartGr.Date) && (y.StartDate.Value.Date <= x.ContractEndGr.Date)))) return operation.Failed("برای بازه های وارد شده فیش حقوقی ثبت شده است"); if (newRollCallDates == null || !newRollCallDates.All(x => employeeStatuses.Any(y => x.ShiftDate.Date >= y.StartDateGr.Date && x.ShiftDate.Date <= y.EndDateGr.Date))) return operation.Failed("کارمند در بازه وارد شده غیر فعال است"); var currentDayRollCall = employeeRollCalls.FirstOrDefault(x => x.EndDate == null); if (currentDayRollCall != null && newRollCallDates.Any(x => x.EndDate!.Value >= currentDayRollCall.StartDate)) return operation.Failed("بازه های وارد شده با حضور غیاب جاری تداخل زمانی دارد"); var name = _rollCallEmployeeRepository.GetByEmployeeIdAndWorkshopId(command.EmployeeId, command.WorkshopId).EmployeeFullName; var rollCallsAsEntityModels = newRollCallDates.Select(x => new RollCall(command.WorkshopId, command.EmployeeId, name, x.StartDate!.Value, x.EndDate, Convert.ToInt32(x.StartDate.Value.ToFarsi().Substring(0, 4)), Convert.ToInt32(x.StartDate.ToFarsi().Substring(5, 2)), _rollCallDomainService, RollCallModifyType.EditByEmployer)).ToList(); _rollCallRepository.RemoveEmployeeRollCallsWithUndefinedInDate(command.WorkshopId, command.EmployeeId, date); _rollCallRepository.AddRange(rollCallsAsEntityModels); _rollCallRepository.SaveChanges(); foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) { rollCallsAsEntityModel.ClearTimeDiff(); rollCallsAsEntityModel.SetShiftDate(_rollCallDomainService); } _rollCallRepository.SaveChanges(); foreach (var rollCallsAsEntityModel in rollCallsAsEntityModels) { rollCallsAsEntityModel.Edit(rollCallsAsEntityModel.StartDate.Value, rollCallsAsEntityModel.EndDate.Value, _rollCallDomainService); } _rollCallRepository.SaveChanges(); return operation.Succcedded(); } #endregion public List GetWorkshopEmployeeRollCallsForDate(long workshopId, long employeeId, string dateFa) { DateTime date = Tools.ToGeorgianDateTime(dateFa); if (date == Tools.GetUndefinedDateTime()) return new(); var res = _rollCallRepository.GetWorkshopEmployeeRollCallsForDate(workshopId, employeeId, date); return res; } public IEnumerable GetNotSlicedRollCallsByWorkshopId(long workshopId, DateTime durationStart, DateTime durationEnd) { return _rollCallRepository.GetNotSlicedRollCallsByWorkshopId(workshopId, durationStart, durationEnd); } public List GetWorkshopAbsentHistory(long workshopId, DateTime startSearch, DateTime endSearch) { return _rollCallRepository.GetWorkshopAbsentHistory(workshopId, startSearch, endSearch); } public OperationResult SetModifyTypeToNone(long rollCallId) { var operation = new OperationResult(); var rollCall = _rollCallRepository.Get(rollCallId); if (rollCall == null) return operation.Failed("چنین آیتمی یافت نشد"); rollCall.SetModifyType(RollCallModifyType.None); _rollCallRepository.SaveChanges(); return operation.Succcedded(); } //استفاده شده در تایید حضور و غیاب های قطع شده توسط سیستم public OperationResult SetModifyTypeToEditByEmployerForRollCallsInDate(long workshopId, long employeeId, string absenceDateFa) { var operation = new OperationResult(); if (absenceDateFa.TryToGeorgianDateTime(out var absenceDate) == false) return operation.Failed("تاریخ به درستی وارد نشده است"); var rollCalls = _rollCallRepository.GetRangeByWorkshopIdEmployeeIdForDate(workshopId, employeeId, absenceDate); if (rollCalls == null) return operation.Failed("چنین آیتمی یافت نشد"); foreach (var item in rollCalls) { item.Edit(item.StartDate.Value,item.EndDate.Value,_rollCallDomainService); item.SetModifyType(RollCallModifyType.EditByEmployer); } _rollCallRepository.SaveChanges(); return operation.Succcedded(); } public List GetWorkshopEmployeeRollCallsWithUndefinedForDate(long workshopId, long employeeId, string dateFa) { if (dateFa.TryToGeorgianDateTime(out var date) == false) return new(); return _rollCallRepository.GetWorkshopEmployeeRollCallsWithUndefinedForDate(workshopId, employeeId, date); } public List GetRollCallWorkFlowsCutByBgService(long workshopId, DateTime start, DateTime end) { return _rollCallRepository.GetRollCallWorkFlowsCutByBgService(workshopId, start, end); } public RollCallViewModel GetDetails(long rollCallId) { return _rollCallRepository.GetDetails(rollCallId); } #endregion public long Flag(long employeeId, long workshopId) { return _rollCallRepository.Flag(employeeId, workshopId); } public string CheckRepeat(long employeeId, long workshopId) { return _rollCallRepository.CheckRepeat(employeeId, workshopId); } public async Task RecalculateValues(long workshopId, List commands) { var operationResult = new OperationResult(); try { List fromDates = commands.Select(x => x.FromDate.ToGeorgianDateTime()).ToList(); var employeeIds = commands.Select(x => x.EmployeeId).ToList(); if (_checkoutRepository.Exists(x => x.WorkshopId == workshopId && employeeIds.Contains(x.EmployeeId) && fromDates.Any(a => a <= x.ContractEnd))) { return operationResult.Failed("پرسنل بعد از تاریخ وارد شده دارای فیش رسمی است"); } if (_customizeCheckoutRepository.Exists(x => x.WorkshopId == workshopId && employeeIds.Contains(x.EmployeeId) && fromDates.Any(a => a <= x.ContractEnd))) { return operationResult.Failed("پرسنل بعد از تاریخ وارد شده دارای فیش غیررسمی نهایی است"); } if (_customizeCheckoutTempRepository.Exists(x => x.WorkshopId == workshopId && employeeIds.Contains(x.EmployeeId) && fromDates.Any(a => a <= x.ContractEnd))) { return operationResult.Failed("پرسنل بعد از تاریخ وارد شده دارای فیش غیررسمی موقت است"); } var oldestDate = commands.MinBy(x => x.FromDate).FromDate.ToGeorgianDateTime(); var allRollCalls = await _rollCallRepository .GetRollCallsUntilNowWithWorkshopIdEmployeeIds(workshopId, commands.Select(x => x.EmployeeId).ToList(), oldestDate); var rollCalls = commands.SelectMany(command => allRollCalls.Where(x => x.EmployeeId == command.EmployeeId && x.ShiftDate >= command.FromDate.ToGeorgianDateTime() ) ); foreach (var rollCall in rollCalls) { rollCall.ClearTimeDiff(); await _rollCallRepository.SaveChangesAsync(); rollCall.SetEndDateTime( rollCall.EndDate!.Value, _rollCallDomainService ); } // foreach (var command in commands) // { // var rollCalls = allRollCalls // .Where(x => x.EmployeeId == command.EmployeeId && x.ShiftDate >= command.FromDate.ToGeorgianDateTime()).ToList(); // // foreach (var rollCall in rollCalls) // { // rollCall.ClearTimeDiff(); // await _rollCallRepository.SaveChangesAsync(); // rollCall.SetEndDateTime(rollCall.EndDate!.Value, _rollCallDomainService); // } // } await _rollCallRepository.SaveChangesAsync(); return operationResult.Succcedded(); } catch (Exception e) { return operationResult.Failed(e.Message); } } public async Task> GetCaseHistoryTitles(long workshopId, RollCallCaseHistorySearchModel searchModel) { return await _rollCallRepository.GetCaseHistoryTitles(workshopId,searchModel); } public async Task> GetCaseHistoryDetails(long workshopId, string titleId, RollCallCaseHistorySearchModel searchModel) { return await _rollCallRepository.GetCaseHistoryDetails(workshopId, titleId, searchModel); } public async Task DownloadCaseHistoryExcel(long workshopId, string titleId, RollCallCaseHistorySearchModel searchModel) { var data = await _rollCallRepository .GetCaseHistoryDetails(workshopId, titleId, searchModel); string nameSecondPart = ""; byte[] excelBytes; if (Regex.IsMatch(titleId, @"^\d{4}_\d{2}$")) { var splitDate = titleId.Split("_"); var year = Convert.ToInt32(splitDate.First()); var month = Convert.ToInt32(splitDate.Last()); var monthName = Convert.ToInt32(month).ToFarsiMonthByIntNumber(); nameSecondPart = $"{year}/{monthName}"; excelBytes = RollCallExcelGenerator.CaseHistoryExcelForEmployee(data, titleId); } else if (Regex.IsMatch(titleId, @"^\d{4}/\d{2}/\d{2}$")) { var oneDayDate = titleId.ToGeorgianDateTime(); nameSecondPart = $" {oneDayDate.DayOfWeek.DayOfWeeKToPersian()}،{titleId}"; excelBytes = RollCallExcelGenerator.CaseHistoryExcelForOneDay(data, titleId); } else { throw new BadRequestException("شناسه سر تیتر وارد شده نامعتبر است"); } var workshopFullName = _workshopRepository.Get(workshopId)?.WorkshopFullName ?? "بدون کارگاه"; var fileName = $"{workshopFullName} - {nameSecondPart}.xlsx"; var res = new RollCallCaseHistoryExcelDto() { Bytes = excelBytes, MimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = fileName }; return res; } }