using _0_Framework.Application; using AccountManagement.Application.Contracts.Task; using AccountManagement.Application.Contracts.TaskSchedule; using AccountManagement.Domain.TaskScheduleAgg; using System; using System.IO; using Company.Domain.HolidayItemAgg; namespace AccountManagement.Application; public class TaskScheduleApplication : ITaskScheduleApplication { private readonly ITaskApplication _taskApplication; private readonly ITaskScheduleRepository _taskScheduleRepository; private readonly IHolidayItemRepository _holidayItemRepository; public TaskScheduleApplication(ITaskApplication taskApplication, ITaskScheduleRepository taskScheduleRepository, IHolidayItemRepository holidayItemRepository) { _taskApplication = taskApplication; _taskScheduleRepository = taskScheduleRepository; _holidayItemRepository = holidayItemRepository; } public OperationResult Create(CreateTask command) { OperationResult operation = new OperationResult(); if (command.HasSchedule) { switch (command.ScheduleType) { case "limited": if (Convert.ToInt32(command.ScheduleCount) > 60) { return operation.Failed("تعداد وارد شده بیشتر از حد مجاز است"); } return CreateLimitedTasks(command); break; case "unlimited": return CreateUnlimitedTasks(command); break; default: return operation.Failed("خطای سیستمی!"); } } else { return operation.Failed("این تسک بصورت زمان بندی شده نمیباشد"); } } public OperationResult CreateLimitedTasks(CreateTask command) { OperationResult operation = new OperationResult(); if (Convert.ToInt32(command.ScheduleCount) < 1 || string.IsNullOrWhiteSpace(command.ScheduleCount)) { return operation.Failed("تعداد وارد شده باید بیشتر از 2 باشد"); } switch (command.ScheduleUnitType) { case "year": if (Convert.ToInt32(command.ScheduleCount) != 1) { return operation.Failed("دوره نمیتواند بیشتر از 1 سال باشد"); } break; case "month": if (Convert.ToInt32(command.ScheduleCount) > 12) { return operation.Failed("بازه وارد شده نا معتبر است"); } break; case "week": if (command.ScheduleUnitNumber != "first" && command.ScheduleUnitNumber != "last") { return operation.Failed("بازه وارد شده نا معتبر است"); } break; case "day": if (Convert.ToInt32(command.ScheduleUnitNumber) > 29) { return operation.Failed("بازه وارد شده نا معتبر است"); } break; default: return operation.Failed("نوع بازه مشخص نمیباشد"); break; } try { DateTime previousDateRaw = command.EndTaskDate.ToGeorgianDateTime2(); DateTime previousDateEdited = command.EndTaskDate.ToGeorgianDateTime2(); int count = Convert.ToInt32(command.ScheduleCount); bool isInt = int.TryParse(command.ScheduleUnitNumber, out int unitNumber); string kindOfWeekUnit = isInt ? "" : command.ScheduleUnitNumber; var taskSchedule = new TaskSchedule(command.ScheduleCount, command.ScheduleType, command.ScheduleUnitType, command.ScheduleUnitNumber, previousDateEdited); _taskScheduleRepository.Create(taskSchedule); _taskScheduleRepository.SaveChanges(); command.TaskScheduleId = taskSchedule.id; switch (command.ScheduleUnitType) { case "year": for (int i = 1; i <= count; i++) { command.EndTaskDate = previousDateEdited.ToFarsi(); operation = _taskApplication.CreateTask(command); taskSchedule.SetLastEndTaskDate(previousDateEdited); bool isHoliday = _holidayItemRepository.GetHoliday(previousDateRaw); while (isHoliday || previousDateEdited.DayOfWeek == DayOfWeek.Friday) { previousDateEdited = previousDateRaw.AddDays(1); isHoliday = _holidayItemRepository.GetHoliday(previousDateEdited); } previousDateRaw = previousDateRaw.AddYears(unitNumber); previousDateEdited = previousDateRaw; } break; case "month": for (int i = 1; i <= count; i++) { command.EndTaskDate = previousDateEdited.ToFarsi(); operation = _taskApplication.CreateTask(command); taskSchedule.SetLastEndTaskDate(previousDateEdited); bool isHoliday = _holidayItemRepository.GetHoliday(previousDateRaw); while (isHoliday || previousDateEdited.DayOfWeek == DayOfWeek.Friday) { previousDateEdited = previousDateRaw.AddDays(1); isHoliday = _holidayItemRepository.GetHoliday(previousDateEdited); } previousDateRaw = previousDateRaw.AddMonths(unitNumber); previousDateEdited = previousDateRaw; } break; case "week": for (int i = 1; i <= count; i++) { if (string.IsNullOrWhiteSpace(kindOfWeekUnit)) { throw new InvalidDataException(); } command.EndTaskDate = kindOfWeekUnit switch { "first" => previousDateRaw.GetNextDayOfWeek(DayOfWeek.Saturday).ToFarsi(), "last" => previousDateRaw.GetNextDayOfWeek(DayOfWeek.Thursday).ToFarsi(), _ => throw new InvalidDataException() }; operation = _taskApplication.CreateTask(command); taskSchedule.SetLastEndTaskDate(previousDateEdited); bool isHoliday = _holidayItemRepository.GetHoliday(previousDateRaw); while (isHoliday || previousDateEdited.DayOfWeek == DayOfWeek.Friday) { previousDateEdited = previousDateRaw.AddDays(1); isHoliday = _holidayItemRepository.GetHoliday(previousDateEdited); } previousDateRaw = command.EndTaskDate.ToGeorgianDateTime(); previousDateEdited = previousDateRaw; } break; case "day": for (int i = 1; i <= count; i++) { command.EndTaskDate = previousDateEdited.ToFarsi(); operation = _taskApplication.CreateTask(command); taskSchedule.SetLastEndTaskDate(previousDateEdited); previousDateRaw = previousDateRaw.AddDays(unitNumber); bool isHoliday = _holidayItemRepository.GetHoliday(previousDateRaw); while (isHoliday || previousDateEdited.DayOfWeek == DayOfWeek.Friday) { previousDateEdited = previousDateRaw.AddDays(1); isHoliday = _holidayItemRepository.GetHoliday(previousDateEdited); } previousDateEdited = previousDateRaw; } break; } _taskScheduleRepository.SaveChanges(); operation = operation.Succcedded(); return operation; } catch (Exception e) { return operation.Failed(e.ToString()); } } public OperationResult CreateUnlimitedTasks(CreateTask command) { var operation = _taskApplication.CreateTask(command); if (!operation.IsSuccedded) return operation; var lastDate = command.EndTaskDate.ToGeorgianDateTime(); var taskSchedule = new TaskSchedule(command.ScheduleCount, command.ScheduleType, command.ScheduleUnitType, command.ScheduleUnitNumber, lastDate); _taskScheduleRepository.Create(taskSchedule); _taskScheduleRepository.SaveChanges(); return operation.Succcedded(); } }