using System.Security.Claims; using BMA.EHR.Domain.Models.MetaData; using BMA.EHR.Domain.Shared; using BMA.EHR.Infrastructure.Persistence; using BMA.EHR.MetaData.Service.Response; using Microsoft.EntityFrameworkCore; using BMA.EHR.Domain.Extensions; namespace BMA.EHR.MetaData.Service.Services { public class HolidayService { #region " Fields " private readonly ApplicationDBContext _context; private readonly IHttpContextAccessor _httpContextAccessor; #endregion #region " Constructor and Destructor " public HolidayService(ApplicationDBContext context, IHttpContextAccessor httpContextAccessor) { _context = context; _httpContextAccessor = httpContextAccessor; } #endregion #region " Properties " private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value; private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value; #endregion #region " Methods " #region " Private " private async Task IsHoliday(DateTime date) { var holidays = (await GetsAsync(date.Date.Year)) .Where(d => d.Category.ToUpper() == "NORMAL") .Select(d => d.HolidayDate.Date).ToList(); if (holidays.Any()) { return holidays.Contains(date); } else return false; } private async Task IsHoliday6Days(DateTime date) { var holidays = (await GetsAsync(date.Date.Year)) .Where(d => d.Category.ToUpper() != "NORMAL") .Select(d => d.HolidayDate.Date).ToList(); if (holidays.Any()) { return holidays.Contains(date); } else return false; } private async Task IsWeekend(DateTime date) { var res = date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday; return await Task.FromResult(res); } private async Task IsWeekend6Days(DateTime date) { var res = date.DayOfWeek == DayOfWeek.Sunday; return await Task.FromResult(res); } private async Task GetNextWorkingDay(DateTime date) { while ((await IsHoliday(date)) || (await IsWeekend(date))) { date = date.AddDays(1); } return date; } private async Task GetNextWorkingDay6Days(DateTime date) { while ((await IsHoliday6Days(date)) || (await IsWeekend6Days(date))) { date = date.AddDays(1); } return date; } private async Task CheckWorkingDay(DateTime date) { while ((await IsHoliday(date)) || (await IsWeekend(date))) { return true; } return false; } private async Task CheckWorkingDay6Days(DateTime date) { while ((await IsHoliday6Days(date)) || (await IsWeekend6Days(date))) { return true; } return false; } #endregion public async Task> GetsAsync(int year, bool showSpecial = true) { var holidays = _context.Holidays.AsQueryable() .Where(x => x.Year == year.ToCeYear()); if (!showSpecial) { holidays = holidays.Where(x => !x.IsSpecial); } return await holidays.OrderBy(d => d.HolidayDate.Date).ToListAsync(); } public async Task> GetNormalAsync(int year, bool showSpecial = true) { var holidays = _context.Holidays.AsQueryable() .Where(x => x.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()); if (!showSpecial) { holidays = holidays.Where(x => !x.IsSpecial); } return await holidays.OrderBy(d => d.HolidayDate.Date).ToListAsync(); } public async Task> Get6DayAsync(int year, bool showSpecial = true) { var holidays = _context.Holidays.AsQueryable() .Where(x => x.Category.ToUpper() != "NORMAL") .Where(x => x.Year == year.ToCeYear()); if (!showSpecial) { holidays = holidays.Where(x => !x.IsSpecial); } return await holidays.OrderBy(d => d.HolidayDate.Date).ToListAsync(); } public async Task> GetsAsyncByMonth(int year, int month) { return await _context.Holidays.AsQueryable() .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == month) .OrderBy(d => d.HolidayDate.Date) .ToListAsync(); } public async Task> GetNormalByMonthAsync(int year, int month) { return await _context.Holidays.AsQueryable() .Where(x => x.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == month) .OrderBy(d => d.HolidayDate.Date) .ToListAsync(); } public async Task> Get6DayByMonthAsync(int year, int month) { return await _context.Holidays.AsQueryable() .Where(x => x.Category.ToUpper() != "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == month) .OrderBy(d => d.HolidayDate.Date) .ToListAsync(); } public async Task GetByIdAsync(Guid id) { return await _context.Holidays.FirstOrDefaultAsync(x => x.Id == id); } public async Task DeleteAsync(Guid id) { var existData = await _context.Holidays.FirstOrDefaultAsync(x => x.Id == id); if (existData != null) { _context.Holidays.Remove(existData); await _context.SaveChangesAsync(); } } public async Task DeleteRangeAsync(List holidays, bool isNormal = true) { foreach (var holiday in holidays) { if (isNormal) { var existData = await _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .FirstOrDefaultAsync(x => DateTime.Compare(x.HolidayDate.Date, holiday.HolidayDate.Date) == 0); if (existData != null) { _context.Holidays.Remove(existData); await _context.SaveChangesAsync(); } } else { var existData = await _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() != "NORMAL") .FirstOrDefaultAsync(x => DateTime.Compare(x.HolidayDate.Date, holiday.HolidayDate.Date) == 0); if (existData != null) { _context.Holidays.Remove(existData); await _context.SaveChangesAsync(); } } } } public async Task UpdateAsync(Guid id, Holiday updated) { var existData = await _context.Holidays.FirstOrDefaultAsync(x => x.Id == id); if (existData != null) { // if (!existData.Compare(updated)) if (existData.Name != updated.Name) { existData.Name = updated.Name; // existData.Year = updated.Year.ToCeYear(); existData.HolidayDate = updated.HolidayDate.Date; // existData.HolidayDate = await GetNextWorkingDay(updated.HolidayDate.Date); existData.OriginalDate = updated.OriginalDate; existData.LastUpdatedAt = DateTime.Now; existData.LastUpdateUserId = UserId ?? ""; existData.LastUpdateFullName = FullName ?? ""; await _context.SaveChangesAsync(); } } } public async Task UpdateRangeAsync(List historys, List holidays, bool isNormal = true) { if (isNormal) { // foreach (var holiday in holidays) // { // var dupData = await _context.Holidays.AsQueryable() // .Where(h => h.Category.ToUpper() == "NORMAL") // .FirstOrDefaultAsync(h => h.Year == holiday.Year && h.Name == holiday.Name && DateTime.Compare(h.HolidayDate.Date, holiday.HolidayDate.Date) != 0); // if (dupData != null) // throw new Exception(GlobalMessages.NameDupicate); // } foreach (var history in historys) { var existData = await _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .FirstOrDefaultAsync(x => DateTime.Compare(x.HolidayDate.Date, history.HolidayDate.Date) == 0); if (existData != null) { _context.Holidays.Remove(existData); await _context.SaveChangesAsync(); } } foreach (var holiday in holidays) { // if (!(await IsHoliday(holiday.HolidayDate.Date)) && !(await IsWeekend(holiday.HolidayDate.Date))) // { await CreateAsync(holiday); // } } // apply to database await _context.SaveChangesAsync(); } else { // foreach (var holiday in holidays) // { // var dupData = await _context.Holidays.AsQueryable() // .Where(h => h.Category.ToUpper() != "NORMAL") // .FirstOrDefaultAsync(h => h.Year == holiday.Year && h.Name == holiday.Name && DateTime.Compare(h.HolidayDate.Date, holiday.HolidayDate.Date) != 0); // if (dupData != null) // throw new Exception(GlobalMessages.NameDupicate); // } foreach (var history in historys) { var existData = await _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() != "NORMAL") .FirstOrDefaultAsync(x => DateTime.Compare(x.HolidayDate.Date, history.HolidayDate.Date) == 0); if (existData != null) { _context.Holidays.Remove(existData); await _context.SaveChangesAsync(); } } foreach (var holiday in holidays) { // if (!(await IsHoliday6Days(holiday.HolidayDate.Date)) && !(await IsWeekend6Days(holiday.HolidayDate.Date))) // { await Create6DayAsync(holiday); // } } // apply to database await _context.SaveChangesAsync(); } } public async Task CreateAsync(Holiday inserted) { var existData = await _context.Holidays.AsQueryable() .Where(d => d.Category.ToUpper() == "NORMAL") .FirstOrDefaultAsync(h => h.Year == inserted.Year && DateTime.Compare(h.HolidayDate.Date, inserted.HolidayDate.Date) == 0); if (existData != null) throw new Exception(GlobalMessages.DataExist5); // var dupData = await _context.Holidays.AsQueryable() // .Where(d => d.Category.ToUpper() == "NORMAL") // .FirstOrDefaultAsync(h => h.Year == inserted.Year && h.Name == inserted.Name); // if (dupData != null) // throw new Exception(GlobalMessages.NameDupicate); inserted.Id = Guid.NewGuid(); inserted.Year = inserted.Year.ToCeYear(); inserted.HolidayDate = inserted.HolidayDate.Date; // inserted.HolidayDate = await GetNextWorkingDay(inserted.HolidayDate.Date); inserted.OriginalDate = inserted.HolidayDate.Date; inserted.CreatedUserId = UserId ?? ""; inserted.CreatedFullName = FullName ?? "System Administrator"; inserted.CreatedAt = DateTime.Now; inserted.LastUpdatedAt = DateTime.Now; inserted.LastUpdateFullName = FullName ?? "System Administrator"; inserted.LastUpdateUserId = UserId ?? ""; inserted.Category = "NORMAL"; await _context.Holidays.AddAsync(inserted); // apply to database // await _context.SaveChangesAsync(); } public async Task Create6DayAsync(Holiday inserted) { var existData = await _context.Holidays.AsQueryable() .Where(d => d.Category.ToUpper() != "NORMAL") .FirstOrDefaultAsync(h => h.Year == inserted.Year && DateTime.Compare(h.HolidayDate.Date, inserted.HolidayDate.Date) == 0); if (existData != null) throw new Exception(GlobalMessages.DataExist6); // var dupData = await _context.Holidays.AsQueryable() // .Where(d => d.Category.ToUpper() != "NORMAL") // .FirstOrDefaultAsync(h => h.Year == inserted.Year && h.Name == inserted.Name); // if (dupData != null) // throw new Exception(GlobalMessages.NameDupicate); inserted.Id = Guid.NewGuid(); inserted.Year = inserted.Year.ToCeYear(); inserted.HolidayDate = inserted.HolidayDate.Date; // inserted.HolidayDate = await GetNextWorkingDay6Days(inserted.HolidayDate.Date); inserted.OriginalDate = inserted.HolidayDate.Date; inserted.CreatedUserId = UserId ?? ""; inserted.CreatedFullName = FullName ?? "System Administrator"; inserted.CreatedAt = DateTime.Now; inserted.LastUpdatedAt = DateTime.Now; inserted.LastUpdateFullName = FullName ?? "System Administrator"; inserted.LastUpdateUserId = UserId ?? ""; inserted.Category = "6DAYS"; await _context.Holidays.AddAsync(inserted); // apply to database // await _context.SaveChangesAsync(); } public async Task CreateRangeAsync(List holidays, string category) { foreach (var holiday in holidays) { if (category.ToUpper() == "NORMAL" || category.ToUpper() == "ALL") { var existData1 = await _context.Holidays.AsQueryable() .Where(d => d.Category.ToUpper() == "NORMAL") .FirstOrDefaultAsync(h => h.Year == holiday.Year && DateTime.Compare(h.HolidayDate.Date, holiday.HolidayDate.Date) == 0); if (existData1 != null) throw new Exception(GlobalMessages.DataExist5); // var dupData1 = await _context.Holidays.AsQueryable() // .Where(d => d.Category.ToUpper() != "NORMAL") // .FirstOrDefaultAsync(h => h.Year == holiday.Year && h.Name == holiday.Name); // if (dupData1 != null) // throw new Exception(GlobalMessages.NameDupicate); // create for normal var inserted = new Holiday { Id = Guid.NewGuid(), Year = holiday.Year.ToCeYear(), Name = holiday.Name, HolidayDate = holiday.HolidayDate.Date, OriginalDate = holiday.HolidayDate.Date, CreatedUserId = UserId ?? "", CreatedFullName = FullName ?? "System Administrator", CreatedAt = DateTime.Now, LastUpdatedAt = DateTime.Now, LastUpdateFullName = FullName ?? "System Administrator", LastUpdateUserId = UserId ?? "", Category = "NORMAL", }; await _context.Holidays.AddAsync(inserted); } if (category.ToUpper() == "6DAYS" || category.ToUpper() == "ALL") { var existData2 = await _context.Holidays.AsQueryable() .Where(d => d.Category.ToUpper() != "NORMAL") .FirstOrDefaultAsync(h => h.Year == holiday.Year && DateTime.Compare(h.HolidayDate.Date, holiday.HolidayDate.Date) == 0); if (existData2 != null) throw new Exception(GlobalMessages.DataExist6); // var dupData2 = await _context.Holidays.AsQueryable() // .Where(d => d.Category.ToUpper() != "6DAYS") // .FirstOrDefaultAsync(h => h.Year == holiday.Year && h.Name == holiday.Name); // if (dupData2 != null) // throw new Exception(GlobalMessages.NameDupicate); // create for 6days var inserted2 = new Holiday { Id = Guid.NewGuid(), Year = holiday.Year.ToCeYear(), Name = holiday.Name, HolidayDate = holiday.HolidayDate.Date, OriginalDate = holiday.HolidayDate.Date, CreatedUserId = UserId ?? "", CreatedFullName = FullName ?? "System Administrator", CreatedAt = DateTime.Now, LastUpdatedAt = DateTime.Now, LastUpdateFullName = FullName ?? "System Administrator", LastUpdateUserId = UserId ?? "", Category = "6DAYS", }; await _context.Holidays.AddAsync(inserted2); } } // apply to database await _context.SaveChangesAsync(); } public async Task CopyAsync(int fromYear, int toYear) { if (toYear <= fromYear) throw new Exception(GlobalMessages.HolidayOfYearNotCopy); var source = await GetsAsync(fromYear.ToCeYear()); if (source == null) throw new Exception(GlobalMessages.HolidayOfYearNotFound); // JACK EDIT : เพิ่ม Logic การตรวจเช็คว่าปีที่จะ Copy ไปมีในฐานข้อมูลแล้วหรือไม่? var dest = await GetsAsync(toYear.ToCeYear()); if (dest.Count() > 0) throw new Exception(GlobalMessages.DestinationHolidayIsExist); source = source.Where(x => x.Category == "NORMAL"); foreach (var holiday in source) { // create for normal var inserted = new Holiday { Id = Guid.NewGuid(), Year = toYear.ToCeYear(), Name = holiday.Name, HolidayDate = await GetNextWorkingDay(holiday.OriginalDate.AddYears(toYear - fromYear)), OriginalDate = holiday.OriginalDate.AddYears(toYear - fromYear), CreatedUserId = UserId ?? "", CreatedFullName = FullName ?? "", CreatedAt = DateTime.Now, Category = "NORMAL" }; await _context.Holidays.AddAsync(inserted); // create for 6days var inserted2 = new Holiday { Id = Guid.NewGuid(), Year = toYear.ToCeYear(), Name = holiday.Name, HolidayDate = await GetNextWorkingDay6Days(holiday.OriginalDate.AddYears(toYear - fromYear)), OriginalDate = holiday.OriginalDate.AddYears(toYear - fromYear), CreatedUserId = UserId ?? "", CreatedFullName = FullName ?? "", CreatedAt = DateTime.Now, Category = "6DAYS" }; await _context.Holidays.AddAsync(inserted2); // apply to database await _context.SaveChangesAsync(); } } public async Task SaveDatabase() { // apply to database await _context.SaveChangesAsync(); } public async Task> GetDataGroupMonthAsync(int year) { var res = new List {new SummaryHolidayByMonthResponseItem { Id = 1, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 1) .OrderBy(d => d.Name).Count(), Month = "ม.ค.", MonthFull = "มกราคม", },new SummaryHolidayByMonthResponseItem { Id = 2, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 2) .OrderBy(d => d.Name).Count(), Month = "ก.พ.", MonthFull = "กุมภาพันธ์", },new SummaryHolidayByMonthResponseItem { Id = 3, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 3) .OrderBy(d => d.Name).Count(), Month = "มี.ค.", MonthFull = "มีนาคม", },new SummaryHolidayByMonthResponseItem { Id = 4, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 4) .OrderBy(d => d.Name).Count(), Month = "เม.ย.", MonthFull = "เมษายน", },new SummaryHolidayByMonthResponseItem { Id = 5, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 5) .OrderBy(d => d.Name).Count(), Month = "พ.ค.", MonthFull = "พฤษภาคม", },new SummaryHolidayByMonthResponseItem { Id = 6, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 6) .OrderBy(d => d.Name).Count(), Month = "มิ.ย.", MonthFull = "มิถุนายน", },new SummaryHolidayByMonthResponseItem { Id = 7, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 7) .OrderBy(d => d.Name).Count(), Month = "ก.ค.", MonthFull = "กรกฎาคม", },new SummaryHolidayByMonthResponseItem { Id = 8, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 8) .OrderBy(d => d.Name).Count(), Month = "ส.ค.", MonthFull = "สิงหาคม", },new SummaryHolidayByMonthResponseItem { Id = 9, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 9) .OrderBy(d => d.Name).Count(), Month = "ก.ย.", MonthFull = "กันยายน", },new SummaryHolidayByMonthResponseItem { Id = 10, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 10) .OrderBy(d => d.Name).Count(), Month = "ต.ค.", MonthFull = "ตุลาคม", },new SummaryHolidayByMonthResponseItem { Id = 11, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 11) .OrderBy(d => d.Name).Count(), Month = "พ.ย.", MonthFull = "พฤศจิกายน", },new SummaryHolidayByMonthResponseItem { Id = 12, Count = _context.Holidays.AsQueryable() .Where(h => h.Category.ToUpper() == "NORMAL") .Where(x => x.Year == year.ToCeYear()) .Where(x => x.HolidayDate.Month == 12) .OrderBy(d => d.Name).Count(), Month = "ธ.ค.", MonthFull = "ธันวาคม", } }; return await Task.FromResult(res); } #endregion } }