diff --git a/BMA.EHR.Leave/Controllers/HolidayController.cs b/BMA.EHR.Leave/Controllers/HolidayController.cs new file mode 100644 index 00000000..9e2b2de1 --- /dev/null +++ b/BMA.EHR.Leave/Controllers/HolidayController.cs @@ -0,0 +1,310 @@ +using BMA.EHR.Domain.Common; +using BMA.EHR.Domain.Models.MetaData; +using BMA.EHR.Leave.Service.Request; +using BMA.EHR.Leave.Service.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; + +namespace BMA.EHR.Leave.Service.Controllers +{ + [Route("api/v{version:apiVersion}/leave/metadata/holiday")] + [ApiVersion("1.0")] + [ApiController] + [Produces("application/json")] + [Authorize] + [SwaggerTag("จัดการข้อมูลปฏิทินวันหยุด")] + public class HolidayController : BaseController + { + #region " Fields " + + private readonly HolidayService _holidayService; + + #endregion + + #region " Constructor and Destructor " + + public HolidayController(HolidayService holidayService) + { + _holidayService = holidayService; + } + + #endregion + + #region " Methods " + + /// + /// อ่านข้อมูลจาก Relational Db โดยแสดงเฉพาะข้อมูลที่ Active เท่านั้น ตามปี + /// + /// ปี่ที่ต้องการ + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("{year:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetsAsync(int year) + { + try + { + var items1 = await _holidayService.GetNormalAsync(year); + var items2 = await _holidayService.Get6DayAsync(year); + + return Success(new { Normal = items1, SixDays = items2 }); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// อ่านข้อมูลจาก Relational Db โดยแสดงเฉพาะข้อมูลที่ Active เท่านั้น ตามเดือน + /// + /// ปี่ที่ต้องการ + /// เดือนที่ต้องการ + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("{year:int}/{month:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetsAsyncByMonth(int year, int month) + { + try + { + var items1 = await _holidayService.GetNormalByMonthAsync(year, month); + var items2 = await _holidayService.Get6DayByMonthAsync(year, month); + + return Success(new { Normal = items1, SixDays = items2 }); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// สร้างรายการวันหยุดใหม่แบบรายการเดียว + /// + /// + /// ทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> CreateAsync(Holiday inserted) + { + try + { + // create normal + await _holidayService.CreateAsync(inserted); + + // create 6days + await _holidayService.Create6DayAsync(inserted); + + //save database + await _holidayService.SaveDatabase(); + + return Success(inserted); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// สร้างรายการวันหยุดใหม่แบบหลายรายการ + /// + /// ช่วงวันที่ที่ต้องการเพิ่ม + /// ประเภทวันหยุด ส่งค่ามาเป็น normal / 6day + /// + /// ทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("range/add/{category}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> CreateRangeAsync(List inserted, string category) + { + try + { + await _holidayService.CreateRangeAsync(inserted, category); + + return Success(inserted); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// แก้ไขรายการวันหยุด + /// + /// รหัส + /// ข้อมูลที่ต้องการแก้ไข + /// + /// ทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPut("{category}/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> UpdateAsync(string id, Holiday updated) + { + try + { + await _holidayService.UpdateAsync(Guid.Parse(id), updated); + + return Success(updated); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// แก้ไขรายการวันหยุด + /// + /// Group ข่อมูลที่แก้ไข + /// ประเภทวันหยุด ส่งค่ามาเป็น normal / 6day + /// + /// ทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("range/edit/{category}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> UpdateRangeAsync(HolidayUpdateRequest data, string category) + { + try + { + var isNormal = category.ToUpper() == "NORMAL"; + await _holidayService.UpdateRangeAsync(data.history, data.updated, isNormal); + + return Success(data.updated); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// ลบรายการวันหยุด + /// + /// รหัส + /// + /// ทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpDelete("{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DeleteAsync(string id) + { + try + { + await _holidayService.DeleteAsync(Guid.Parse(id)); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// ลบรายการวันหยุด + /// + /// ช่วงวันที่ที่ต้องการลบ + /// ประเภทวันหยุด ส่งค่ามาเป็น normal / 6day + /// + /// ทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("range/delete/{category}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DeleteRangeAsync(List delete, string category) + { + try + { + var isNormal = category.ToUpper() == "NORMAL"; + await _holidayService.DeleteRangeAsync(delete, isNormal); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// คัดลอกข้อมูลวันหยุด โดยระบุปีที่ต้องการคัดลอก และ ปีที่ต้องการบันทึก + /// + /// Request Body + /// + [HttpPost("copy")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> CopyAsync([FromBody] HolidayCopyRequest request) + { + try + { + await _holidayService.CopyAsync(request.FromYear, request.ToYear); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// สรุปวันหยุดในแต่ละปี + /// + /// ปี่ที่ต้องการ + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("summary/{year:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetDataGroupMonthAsync(int year) + { + try + { + var items = await _holidayService.GetDataGroupMonthAsync(year); + + return Success(items); + } + catch (Exception ex) + { + return Error(ex); + } + } + + #endregion + } +} diff --git a/BMA.EHR.Leave/Request/HolidayCopyRequest.cs b/BMA.EHR.Leave/Request/HolidayCopyRequest.cs new file mode 100644 index 00000000..21b04204 --- /dev/null +++ b/BMA.EHR.Leave/Request/HolidayCopyRequest.cs @@ -0,0 +1,10 @@ + +namespace BMA.EHR.Leave.Service.Request +{ + public class HolidayCopyRequest + { + public int FromYear { get; set; } = DateTime.Now.Year; + + public int ToYear { get; set; } = DateTime.Now.Year; + } +} diff --git a/BMA.EHR.Leave/Request/HolidayRequest.cs b/BMA.EHR.Leave/Request/HolidayRequest.cs new file mode 100644 index 00000000..7ce9f895 --- /dev/null +++ b/BMA.EHR.Leave/Request/HolidayRequest.cs @@ -0,0 +1,15 @@ + +namespace BMA.EHR.Leave.Service.Request +{ + public class HolidayRequest + { + public DateTime dateStart { get; set; } = DateTime.Now; + + public DateTime dateEnd { get; set; } = DateTime.Now; + + public int Year { get; set; } = DateTime.Now.Year; + + public string Name { get; set; } = string.Empty; + + } +} diff --git a/BMA.EHR.Leave/Request/HolidayUpdateRequest.cs b/BMA.EHR.Leave/Request/HolidayUpdateRequest.cs new file mode 100644 index 00000000..91251c96 --- /dev/null +++ b/BMA.EHR.Leave/Request/HolidayUpdateRequest.cs @@ -0,0 +1,13 @@ + +using BMA.EHR.Domain.Models.MetaData; + +namespace BMA.EHR.Leave.Service.Request +{ + public class HolidayUpdateRequest + { + public List history { get; set; } + + public List updated { get; set; } + + } +} diff --git a/BMA.EHR.Leave/Response/SummaryHolidayByMonthResponseItem.cs b/BMA.EHR.Leave/Response/SummaryHolidayByMonthResponseItem.cs new file mode 100644 index 00000000..925779f2 --- /dev/null +++ b/BMA.EHR.Leave/Response/SummaryHolidayByMonthResponseItem.cs @@ -0,0 +1,14 @@ +namespace BMA.EHR.Leave.Service.Response +{ + public class SummaryHolidayByMonthResponseItem + { + public int? Id { get; set; } + + public int? Count { get; set; } + + public string? Month { get; set; } + + public string? MonthFull { get; set; } + + } +} diff --git a/BMA.EHR.Leave/Services/HolidayService.cs b/BMA.EHR.Leave/Services/HolidayService.cs new file mode 100644 index 00000000..b7fd99ff --- /dev/null +++ b/BMA.EHR.Leave/Services/HolidayService.cs @@ -0,0 +1,678 @@ +using System.Security.Claims; +using BMA.EHR.Domain.Models.MetaData; +using BMA.EHR.Domain.Shared; +using BMA.EHR.Infrastructure.Persistence; +using Microsoft.EntityFrameworkCore; +using BMA.EHR.Domain.Extensions; +using BMA.EHR.Leave.Service.Response; + +namespace BMA.EHR.Leave.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 + } +} diff --git a/BMA.EHR.Placement.Service/Controllers/MessageController.cs b/BMA.EHR.Placement.Service/Controllers/MessageController.cs new file mode 100644 index 00000000..c4434eb1 --- /dev/null +++ b/BMA.EHR.Placement.Service/Controllers/MessageController.cs @@ -0,0 +1,190 @@ +using BMA.EHR.Application.Repositories.MessageQueue; +using BMA.EHR.Domain.Common; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; + +namespace BMA.EHR.Placement.Service.Controllers +{ + [Route("api/v{version:apiVersion}/placement/message")] + [ApiVersion("1.0")] + [ApiController] + [Produces("application/json")] + [Authorize] + [SwaggerTag("API ระบบ Inbox และ Notification")] + public class MessageController : BaseController + { + #region " Fields " + + private readonly InboxRepository _inboxRepository; + private readonly NotificationRepository _notificationRepository; + + #endregion + + #region " Constuctor and Destructor " + + public MessageController(InboxRepository inboxRepository, + NotificationRepository notificationRepository) + { + _inboxRepository = inboxRepository; + _notificationRepository = notificationRepository; + } + + #endregion + + #region " Methods " + + /// + /// แสดงข้อมูล Inbox ของ user ที่ Login + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("my-inboxes")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetMyInboxAsync(int page = 1, int pageSize = 20) + { + try + { + var inboxes = await _inboxRepository.GetMyInboxAsync(page, pageSize); + + return Success(inboxes); + } + catch + { + throw; + } + } + + /// + /// ดูข้อมูล Inbox ของ user ที่ Login + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("my-inboxes/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetByIdMyInboxAsync(Guid id) + { + try + { + await _inboxRepository.GetByIdMyInboxAsync(id); + + return Success(); + } + catch + { + throw; + } + } + + /// + /// ลบข้อมูล Inbox ของ user ที่ Login + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpDelete("my-inboxes/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DeleteMyInboxAsync(Guid id) + { + try + { + await _inboxRepository.DeleteMyInboxAsync(id); + + return Success(); + } + catch + { + throw; + } + } + + /// + /// แสดงข้อมูล Notification ของ user ที่ Login + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("my-notifications")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetMyNotificationAsync(int page = 1, int pageSize = 20) + { + try + { + var noti = await _notificationRepository.GetMyNotificationAsync(page, pageSize); + + return Success(noti); + } + catch + { + throw; + } + } + + /// + /// แสดงข้อมูล Notification ของ user ที่ Login ที่ยังไม่ได้อ่าน + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("my-notifications/noread")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetMyNotificationAsyncNoread() + { + try + { + var noti = await _notificationRepository.GetMyNotificationAsyncNoread(); + + return Success(noti); + } + catch + { + throw; + } + } + + /// + /// ลบข้อมูล Notification ของ user ที่ Login + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpDelete("my-notifications/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DeleteMyNotificationAsync(Guid id) + { + try + { + await _notificationRepository.DeleteMyNotificationAsync(id); + + return Success(); + } + catch + { + throw; + } + } + + + #endregion + } +} diff --git a/BMA.EHR.Placement.Service/Controllers/NotifyController.cs b/BMA.EHR.Placement.Service/Controllers/NotifyController.cs index 8ef642fa..cfead6d4 100644 --- a/BMA.EHR.Placement.Service/Controllers/NotifyController.cs +++ b/BMA.EHR.Placement.Service/Controllers/NotifyController.cs @@ -1,10 +1,6 @@ using BMA.EHR.Application.Repositories; using BMA.EHR.Application.Repositories.MessageQueue; using BMA.EHR.Domain.Common; -using BMA.EHR.Domain.Extensions; -using BMA.EHR.Domain.Models.MetaData; -using BMA.EHR.Domain.Models.Notifications; -using BMA.EHR.Domain.Models.Placement; using BMA.EHR.Domain.Models.Probation; using BMA.EHR.Domain.Shared; using BMA.EHR.Infrastructure.Persistence; @@ -18,7 +14,6 @@ using RabbitMQ.Client; using Swashbuckle.AspNetCore.Annotations; using System.Net.Http.Headers; using System.Security.Claims; -using System.Security.Cryptography; using System.Text; namespace BMA.EHR.Placement.Service.Controllers