diff --git a/BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj b/BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj new file mode 100644 index 00000000..c59ded2b --- /dev/null +++ b/BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj @@ -0,0 +1,25 @@ + + + + Exe + net8.0 + enable + enable + Linux + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/BMA.EHR.CheckInConsumer/Dockerfile b/BMA.EHR.CheckInConsumer/Dockerfile new file mode 100644 index 00000000..86180496 --- /dev/null +++ b/BMA.EHR.CheckInConsumer/Dockerfile @@ -0,0 +1,28 @@ +# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +# This stage is used when running from VS in fast mode (Default for Debug configuration) +FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base +USER app +WORKDIR /app + + +# This stage is used to build the service project +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj", "BMA.EHR.CheckInConsumer/"] +RUN dotnet restore "./BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj" +COPY . . +WORKDIR "/src/BMA.EHR.CheckInConsumer" +RUN dotnet build "./BMA.EHR.CheckInConsumer.csproj" -c $BUILD_CONFIGURATION -o /app/build + +# This stage is used to publish the service project to be copied to the final stage +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./BMA.EHR.CheckInConsumer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration) +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "BMA.EHR.CheckInConsumer.dll"] \ No newline at end of file diff --git a/BMA.EHR.CheckInConsumer/Program.cs b/BMA.EHR.CheckInConsumer/Program.cs new file mode 100644 index 00000000..1c63bfaa --- /dev/null +++ b/BMA.EHR.CheckInConsumer/Program.cs @@ -0,0 +1,140 @@ +using Microsoft.Extensions.Configuration; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +var basePath = Directory.GetCurrentDirectory(); +var configuration = new ConfigurationBuilder() + .SetBasePath(basePath) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .Build(); + +WriteToConsole("Consumer Start!"); + +var host = configuration["Rabbit:Host"] ?? ""; +var user = configuration["Rabbit:User"] ?? ""; +var pass = configuration["Rabbit:Password"] ?? ""; + +// create connection +var factory = new ConnectionFactory() +{ + //Uri = new Uri("amqp://admin:P@ssw0rd@192.168.4.11:5672") + HostName = host,// หรือ hostname ของ RabbitMQ Server ที่คุณใช้ + UserName = user, // ใส่ชื่อผู้ใช้ของคุณ + Password = pass // ใส่รหัสผ่านของคุณ +}; + +using var connection = factory.CreateConnection(); +using var channel = connection.CreateModel(); + +channel.QueueDeclare(queue: "checkin-queue", durable: false, exclusive: false, autoDelete: false, arguments: null); + +var consumer = new EventingBasicConsumer(channel); + +consumer.Received += async (model, ea) => +{ + var body = ea.Body.ToArray(); + var message = Encoding.UTF8.GetString(body); + await CallRestApi(message); + + // convert string into object + //var request = JsonConvert.DeserializeObject(message); + //using (var db = new ApplicationDbContext()) + //{ + // var item = new AttendantItem + // { + // Name = request.Name, + // CheckInDateTime = request.CheckInDateTime, + // }; + // db.AttendantItems.Add(item); + // db.SaveChanges(); + + // WriteToConsole($"ได้รับคำขอจาก Queue: {message}"); + // WriteToConsole($"ตอบกลับจาก REST API: {JsonConvert.SerializeObject(item)}"); + //} + + WriteToConsole($"ได้รับคำขอจาก Queue: {message}"); + //WriteToConsole($"ตอบกลับจาก REST API: {JsonConvert.SerializeObject(item)}"); +}; + +channel.BasicConsume(queue: "checkin-queue", autoAck: true, consumer: consumer); + +Console.WriteLine("\nPress 'Enter' to exit the process..."); + +// another use of "Console.ReadKey()" method +// here it asks to press the enter key to exit +while (Console.ReadKey().Key != ConsoleKey.Enter) +{ +} + + +static void WriteToConsole(string message) +{ + Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} : {message}"); +} + +async Task CallRestApi(string requestData) +{ + using var client = new HttpClient(); + var apiPath = $"{configuration["API"]}/leave/process-check-in"; + + var content = new StringContent(requestData, Encoding.UTF8, "application/json"); + + var response = await client.PostAsync(apiPath, content); + + if (response.IsSuccessStatusCode) + { + var responseContent = await response.Content.ReadAsStringAsync(); + WriteToConsole(responseContent); + } + else + { + var errorMessage = await response.Content.ReadAsStringAsync(); + var res = JsonSerializer.Deserialize(errorMessage); + WriteToConsole($"Error: {res.Message}"); + } +} + + +public class ResponseObject +{ + [JsonPropertyName("status")] + public int Status { get; set; } + + [JsonPropertyName("message")] + public string? Message { get; set; } + + [JsonPropertyName("result")] + public object? Result { get; set; } +} + +public class CheckTimeDtoRB +{ + public Guid? CheckInId { get; set; } + + + public double Lat { get; set; } = 0; + + + public double Lon { get; set; } = 0; + + + public string POI { get; set; } = string.Empty; + + + public bool IsLocation { get; set; } = true; + + public string? LocationName { get; set; } = string.Empty; + + public string? Remark { get; set; } = string.Empty; + + public Guid? UserId { get; set; } + + public DateTime? CurrentDate { get; set; } + + public string? CheckInFileName { get; set; } + + public byte[]? CheckInFileBytes { get; set; } +} \ No newline at end of file diff --git a/BMA.EHR.CheckInConsumer/Properties/launchSettings.json b/BMA.EHR.CheckInConsumer/Properties/launchSettings.json new file mode 100644 index 00000000..3721415f --- /dev/null +++ b/BMA.EHR.CheckInConsumer/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "BMA.EHR.CheckInConsumer": { + "commandName": "Project" + }, + "Container (Dockerfile)": { + "commandName": "Docker" + } + } +} \ No newline at end of file diff --git a/BMA.EHR.CheckInConsumer/appsettings.json b/BMA.EHR.CheckInConsumer/appsettings.json new file mode 100644 index 00000000..2cb51e69 --- /dev/null +++ b/BMA.EHR.CheckInConsumer/appsettings.json @@ -0,0 +1,8 @@ +{ + "Rabbit": { + "Host": "192.168.1.40", + "User": "admin", + "Password": "Test123456" + }, + "API": "https://localhost:7283/api/v1" +} \ No newline at end of file diff --git a/BMA.EHR.Leave/Controllers/LeaveController.cs b/BMA.EHR.Leave/Controllers/LeaveController.cs index 5f74aa03..ed67d1e0 100644 --- a/BMA.EHR.Leave/Controllers/LeaveController.cs +++ b/BMA.EHR.Leave/Controllers/LeaveController.cs @@ -1,4 +1,5 @@ -using BMA.EHR.Application.Repositories; +using Amazon.S3.Model; +using BMA.EHR.Application.Repositories; using BMA.EHR.Application.Repositories.Commands; using BMA.EHR.Application.Repositories.Leaves.LeaveRequests; using BMA.EHR.Application.Repositories.Leaves.TimeAttendants; @@ -14,10 +15,16 @@ using BMA.EHR.Leave.Service.DTOs.CheckIn; using BMA.EHR.Leave.Service.DTOs.DutyTime; using BMA.EHR.Leave.Service.DTOs.LeaveRequest; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Org.BouncyCastle.Ocsp; +using RabbitMQ.Client; +using Serilog; using Swashbuckle.AspNetCore.Annotations; using System.ComponentModel.DataAnnotations; using System.Security.Claims; +using System.Text; using SearchProfileResultDto = BMA.EHR.Leave.Service.DTOs.ChangeRound.SearchProfileResultDto; namespace BMA.EHR.Leave.Service.Controllers @@ -407,7 +414,6 @@ namespace BMA.EHR.Leave.Service.Controllers return Success(ret); } - /// /// LV1_005 - ลงเวลาเข้า-ออกงาน (USER) /// @@ -421,6 +427,239 @@ namespace BMA.EHR.Leave.Service.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> CheckInAsync([FromForm] CheckTimeDto data) + { + var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId); + var currentDate = DateTime.Now; + var checkFileBytes = new byte[0]; + + if (data.Img != null && data.Img.Length == 0) + { + var formFile = data.Img; + using (var memoryStream = new MemoryStream()) + { + await formFile.CopyToAsync(memoryStream); + checkFileBytes = memoryStream.ToArray(); + } + } + + var checkData = new CheckTimeDtoRB + { + UserId = userId, + CurrentDate = currentDate, + CheckInId = data.CheckInId, + Lat = data.Lat, + Lon = data.Lon, + POI = data.POI, + IsLocation = data.IsLocation, + LocationName = data.LocationName, + Remark = data.Remark, + CheckInFileName = data.Img == null ? "no-file" : data.Img.FileName, + CheckInFileBytes = checkFileBytes, + Token = AccessToken ?? "" + }; + + // create connection + var factory = new ConnectionFactory() + { + HostName = _configuration["Rabbit:Host"], + UserName = _configuration["Rabbit:User"], + Password = _configuration["Rabbit:Password"], + }; + + // create channel + using var connection = factory.CreateConnection(); + using var channel = connection.CreateModel(); + channel.QueueDeclare(queue: "checkin-queue", durable: false, exclusive: false, autoDelete: false, arguments: null); + + // แปลง Object เป็น JSON สตริง + var serializedObject = JsonConvert.SerializeObject(checkData); + + // แปลง JSON สตริงเป็น byte array + var body = Encoding.UTF8.GetBytes(serializedObject); + + channel.BasicPublish(exchange: "", routingKey: "checkin-queue", basicProperties: null, body: body); + Console.WriteLine($"Send to Queue: {serializedObject}"); + + return Success(new { date = currentDate }); + } + + /// + /// Check in Processing + /// + /// + /// + /// เมื่อทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("process-check-in"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [AllowAnonymous] + public async Task> ProcessCheckInAsync([FromBody] CheckTimeDtoRB data) + { + var userId = data.UserId ?? Guid.Empty; + var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, data.Token); + + if (profile == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + if (data.CheckInFileName == "no-file") throw new Exception(GlobalMessages.NoFileToUpload); + var currentDate = data.CurrentDate ?? DateTime.Now; + + var fileName = $"{_bucketName}/{userId}/{currentDate.ToString("dd-MM-yyyy")}/{data.CheckInFileName}"; + using (var ms = new MemoryStream(data.CheckInFileBytes ?? new byte[0])) + { + await _minIOService.UploadFileAsync(fileName, ms); + } + + var defaultRound = await _dutyTimeRepository.GetDefaultAsync(); + if (defaultRound == null) + { + return Error("ไม่พบรอบการลงเวลาทำงาน Default", StatusCodes.Status404NotFound); + } + + var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(profile.Id); + var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty; + var userRound = await _dutyTimeRepository.GetByIdAsync(roundId); + + // TODO : รอดุึงรอบที่ผูกกับ user + var duty = userRound ?? defaultRound; + + // create check in object + if (data.CheckInId == null) + { + // validate duplicate check in + var currentCheckIn = await _userTimeStampRepository.GetTimestampByDateAsync(userId, currentDate); + + + + if (currentCheckIn != null) + { + return Error(new Exception("ไม่สามารถลงเวลาได้ เนื่องจากมีการลงเวลาในวันนี้แล้ว!"), StatusCodes.Status400BadRequest); + } + + + var checkin = new UserTimeStamp + { + KeycloakUserId = userId, + CheckInLat = data.Lat, + CheckInLon = data.Lon, + IsLocationCheckIn = data.IsLocation, + CheckInLocationName = data.LocationName, + CheckInPOI = data.POI, + CheckInRemark = data.Remark, + CheckInImageUrl = fileName, + CheckIn = currentDate, + Prefix = profile.Prefix, + FirstName = profile.FirstName, + LastName = profile.LastName, + }; + + var checkInStatus = DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) > + DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}") ? + + DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) > + DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}") ? + "ABSENT" : + "LATE" : + "NORMAL"; + + // process - รอทำใน queue + var checkin_process = new ProcessUserTimeStamp + { + KeycloakUserId = userId, + CheckInLat = data.Lat, + CheckInLon = data.Lon, + IsLocationCheckIn = data.IsLocation, + CheckInLocationName = data.LocationName, + CheckInPOI = data.POI, + CheckInRemark = data.Remark, + CheckInImageUrl = fileName, + CheckIn = currentDate, + CheckInStatus = checkInStatus, + Prefix = profile.Prefix, + FirstName = profile.FirstName, + LastName = profile.LastName, + }; + + await _userTimeStampRepository.AddAsync(checkin); + await _processUserTimeStampRepository.AddAsync(checkin_process); + } + else + { + + + var checkout = await _userTimeStampRepository.GetByIdAsync(data.CheckInId.Value); + + var currentCheckInProcess = await _processUserTimeStampRepository.GetTimestampByDateAsync(userId, checkout.CheckIn.Date); + + var checkout_process = await _processUserTimeStampRepository.GetByIdAsync(currentCheckInProcess.Id); + + + if (checkout != null) + { + checkout.CheckOutLat = data.Lat; + checkout.CheckOutLon = data.Lon; + checkout.IsLocationCheckOut = data.IsLocation; + checkout.CheckOutLocationName = data.LocationName; + checkout.CheckOutPOI = data.POI; + checkout.CheckOutRemark = data.Remark; + checkout.CheckOutImageUrl = fileName; + checkout.CheckOut = currentDate; + + await _userTimeStampRepository.UpdateAsync(checkout); + } + else + { + return Error(new Exception(GlobalMessages.DataNotFound), StatusCodes.Status404NotFound); + } + + var checkOutStatus = DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) < + DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}") ? + "ABSENT" : + DateTime.Parse(currentDate.ToString("yyyy-MM-dd HH:mm")) < + DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}") ? + "ABSENT" : + "NORMAL"; + + if (checkout_process != null) + { + checkout_process.CheckOutLat = data.Lat; + checkout_process.CheckOutLon = data.Lon; + checkout_process.IsLocationCheckOut = data.IsLocation; + checkout_process.CheckOutLocationName = data.LocationName; + checkout_process.CheckOutPOI = data.POI; + checkout_process.CheckOutRemark = data.Remark; + checkout_process.CheckOutImageUrl = fileName; + checkout_process.CheckOut = currentDate; + checkout_process.CheckOutStatus = checkOutStatus; + + await _processUserTimeStampRepository.UpdateAsync(checkout_process); + } + else + { + return Error(new Exception(GlobalMessages.DataNotFound), StatusCodes.Status404NotFound); + } + + } + var checkInType = data.CheckInId == null ? "check-in" : "check-out"; + return Success(new { user = $"{profile.FirstName} {profile.LastName}", date = currentDate, type = checkInType }); ; + } + + /// + /// LV1_005 - ลงเวลาเข้า-ออกงาน (USER) + /// + /// + /// + /// เมื่อทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("check-in-old"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> CheckInOldAsync([FromForm] CheckTimeDto data) { var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId); var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken); @@ -438,8 +677,6 @@ namespace BMA.EHR.Leave.Service.Controllers await _minIOService.UploadFileAsync(fileName, ms); } - - var defaultRound = await _dutyTimeRepository.GetDefaultAsync(); if (defaultRound == null) { @@ -490,7 +727,6 @@ namespace BMA.EHR.Leave.Service.Controllers DateTime.Parse($"{currentDate.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}") ? "ABSENT" : "LATE" : - "NORMAL"; // process - รอทำใน queue diff --git a/BMA.EHR.Leave/DTOs/CheckIn/CheckTimeDto.cs b/BMA.EHR.Leave/DTOs/CheckIn/CheckTimeDto.cs index 55d0c7d9..f7e03b59 100644 --- a/BMA.EHR.Leave/DTOs/CheckIn/CheckTimeDto.cs +++ b/BMA.EHR.Leave/DTOs/CheckIn/CheckTimeDto.cs @@ -1,13 +1,14 @@ -using System.ComponentModel.DataAnnotations; +using Org.BouncyCastle.Crypto.Paddings; +using System.ComponentModel.DataAnnotations; namespace BMA.EHR.Leave.Service.DTOs.CheckIn { public class CheckTimeDto { - public Guid? CheckInId { get; set; } + public Guid? CheckInId { get; set; } - [Required] - public IFormFile? Img { get; set; } + [Required] + public IFormFile? Img { get; set; } [Required] public double Lat { get; set; } = 0; @@ -21,8 +22,39 @@ namespace BMA.EHR.Leave.Service.DTOs.CheckIn [Required] public bool IsLocation { get; set; } = true; - public string? LocationName { get; set; } = string.Empty; + public string? LocationName { get; set; } = string.Empty; - public string? Remark { get; set;} = string.Empty; + public string? Remark { get; set; } = string.Empty; + } + + public class CheckTimeDtoRB + { + public string Token { get; set; } = ""; + + public Guid? CheckInId { get; set; } + + + public double Lat { get; set; } = 0; + + + public double Lon { get; set; } = 0; + + + public string POI { get; set; } = string.Empty; + + + public bool IsLocation { get; set; } = true; + + public string? LocationName { get; set; } = string.Empty; + + public string? Remark { get; set; } = string.Empty; + + public Guid? UserId { get; set; } + + public DateTime? CurrentDate { get; set; } + + public string CheckInFileName { get; set; } = ""; + + public byte[] CheckInFileBytes { get; set; } = new byte[0]; } } diff --git a/BMA.EHR.Leave/appsettings.json b/BMA.EHR.Leave/appsettings.json index 341ba2d5..70c27f13 100644 --- a/BMA.EHR.Leave/appsettings.json +++ b/BMA.EHR.Leave/appsettings.json @@ -1,51 +1,56 @@ { - "Serilog": { - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Information", - "System": "Warning" - } - } - }, - "ElasticConfiguration": { - "Uri": "http://localhost:9200" - }, - "AllowedHosts": "*", - "ConnectionStrings": { - //"DefaultConnection": "User Id=sys;Password=P@ssw0rd;DBA Privilege=SYSDBA;Data Source=localhost:1521/ORCLCDB", - //"DefaultConnection": "server=192.168.1.81;user=root;password=adminVM123;port=4061;database=bma_ehr;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", - "DefaultConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=bma_ehr_demo;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", - "ExamConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=bma_ehr_exam_demo;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", - //"LeaveConnection": "server=192.168.4.11;user=root;password=P@ssw0rd;port=3306;database=bma_ehr_leave;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" - "LeaveConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=bma_ehr_leave_demo;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" - }, - "Jwt": { - "Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI", - "Issuer": "https://id.frappet.synology.me/realms/bma-ehr" - }, - "EPPlus": { - "ExcelPackage": { - "LicenseContext": "NonCommercial" - } - }, - "MinIO": { - "Endpoint": "https://s3cluster.frappet.com/", - "AccessKey": "frappet", - "SecretKey": "FPTadmin2357", - "BucketName": "bma-ehr-fpt" - }, - "Protocol": "HTTPS", - "Node": { - "API": "https://bma-ehr.frappet.synology.me/api/v1/probation" - }, - "Mail": { - "Server": "mail.bangkok.go.th", - "User": "saraban.csc.rd@bangkok.go.th", - "Password": "Saraban5222", - "MailFrom": "saraban.csc.rd@bangkok.go.th", - "Port": "25" - }, - "API": "https://bma-ehr.frappet.synology.me/api/v1", - "API_KEY": "fKRL16yyEgbyTEJdsMw2h64tGSCmkW685PRtM3CygzX1JOSdptT9UJtpgWwKM8FybRTJups3GTFwj27ZRvlPdIkv3XgCoVJaD5LmR06ozuEPvCCRSdp2WFthg08V5xHc56fTPfZLpr1VmXrhd6dvYhHIqKkQUJR02Rlkss11cLRWEQOssEFVA4xdu2J5DIRO1EM5m7wRRvEwcDB4mYRXD9HH52SMq6iYqUWEWsMwLdbk7QW9yYESUEuzMW5gWrb6vIeWZxJV5bTz1PcWUyR7eO9Fyw1F5DiQYc9JgzTC1mW7cv31fEtTtrfbJYKIb5EbWilqIEUKC6A0UKBDDek35ML0006cqRVm0pvdOH6jeq7VQyYrhdXe59dBEyhYGUIfozoVBvW7Up4QBuOMjyPjSqJPlMBKwaseptfrblxQV1AOOivSBpf1ZcQyOZ8JktRtKUDSuXsmG0lsXwFlI3JCeSHdpVdgZWFYcJPegqfrB6KotR02t9AVkpLs1ZWrixwz" + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Warning" + } + } + }, + "ElasticConfiguration": { + "Uri": "http://localhost:9200" + }, + "AllowedHosts": "*", + "ConnectionStrings": { + //"DefaultConnection": "User Id=sys;Password=P@ssw0rd;DBA Privilege=SYSDBA;Data Source=localhost:1521/ORCLCDB", + //"DefaultConnection": "server=192.168.1.81;user=root;password=adminVM123;port=4061;database=bma_ehr;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", + "DefaultConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=bma_ehr_demo;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", + "ExamConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=bma_ehr_exam_demo;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", + //"LeaveConnection": "server=192.168.4.11;user=root;password=P@ssw0rd;port=3306;database=bma_ehr_leave;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" + "LeaveConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=bma_ehr_leave_demo;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" + }, + "Jwt": { + "Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI", + "Issuer": "https://id.frappet.synology.me/realms/bma-ehr" + }, + "EPPlus": { + "ExcelPackage": { + "LicenseContext": "NonCommercial" + } + }, + "MinIO": { + "Endpoint": "https://s3cluster.frappet.com/", + "AccessKey": "frappet", + "SecretKey": "FPTadmin2357", + "BucketName": "bma-ehr-fpt" + }, + "Protocol": "HTTPS", + "Node": { + "API": "https://bma-ehr.frappet.synology.me/api/v1/probation" + }, + "Rabbit": { + "Host": "192.168.1.40", + "User": "admin", + "Password": "Test123456" + }, + "Mail": { + "Server": "mail.bangkok.go.th", + "User": "saraban.csc.rd@bangkok.go.th", + "Password": "Saraban5222", + "MailFrom": "saraban.csc.rd@bangkok.go.th", + "Port": "25" + }, + "API": "https://bma-ehr.frappet.synology.me/api/v1", + "API_KEY": "fKRL16yyEgbyTEJdsMw2h64tGSCmkW685PRtM3CygzX1JOSdptT9UJtpgWwKM8FybRTJups3GTFwj27ZRvlPdIkv3XgCoVJaD5LmR06ozuEPvCCRSdp2WFthg08V5xHc56fTPfZLpr1VmXrhd6dvYhHIqKkQUJR02Rlkss11cLRWEQOssEFVA4xdu2J5DIRO1EM5m7wRRvEwcDB4mYRXD9HH52SMq6iYqUWEWsMwLdbk7QW9yYESUEuzMW5gWrb6vIeWZxJV5bTz1PcWUyR7eO9Fyw1F5DiQYc9JgzTC1mW7cv31fEtTtrfbJYKIb5EbWilqIEUKC6A0UKBDDek35ML0006cqRVm0pvdOH6jeq7VQyYrhdXe59dBEyhYGUIfozoVBvW7Up4QBuOMjyPjSqJPlMBKwaseptfrblxQV1AOOivSBpf1ZcQyOZ8JktRtKUDSuXsmG0lsXwFlI3JCeSHdpVdgZWFYcJPegqfrB6KotR02t9AVkpLs1ZWrixwz" } \ No newline at end of file diff --git a/BMA.EHR.Solution.sln b/BMA.EHR.Solution.sln index e87d02b9..a65e792b 100644 --- a/BMA.EHR.Solution.sln +++ b/BMA.EHR.Solution.sln @@ -25,11 +25,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BMA.EHR.Retirement.Service" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BMA.EHR.Report.Service", "BMA.EHR.Report.Service\BMA.EHR.Report.Service.csproj", "{26FE7B1C-771B-4940-9F40-326A7AD53F1C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMA.EHR.Discipline.Service", "BMA.EHR.Discipline.Service\BMA.EHR.Discipline.Service.csproj", "{0145A11E-7780-437B-A86F-CBDDB50BC3D1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BMA.EHR.Discipline.Service", "BMA.EHR.Discipline.Service\BMA.EHR.Discipline.Service.csproj", "{0145A11E-7780-437B-A86F-CBDDB50BC3D1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMA.EHR.Insignia", "BMA.EHR.Insignia\BMA.EHR.Insignia.csproj", "{03AB740F-AF31-423E-8546-198B914AF76F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BMA.EHR.Insignia", "BMA.EHR.Insignia\BMA.EHR.Insignia.csproj", "{03AB740F-AF31-423E-8546-198B914AF76F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMA.EHR.Leave", "BMA.EHR.Leave\BMA.EHR.Leave.csproj", "{B06C5612-2346-44B1-9D50-F8373885BD88}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BMA.EHR.Leave", "BMA.EHR.Leave\BMA.EHR.Leave.csproj", "{B06C5612-2346-44B1-9D50-F8373885BD88}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BMA.EHR.CheckInConsumer", "BMA.EHR.CheckInConsumer\BMA.EHR.CheckInConsumer.csproj", "{B36F7E5A-2745-42B5-8493-D648EF8CC43C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -85,6 +87,10 @@ Global {B06C5612-2346-44B1-9D50-F8373885BD88}.Debug|Any CPU.Build.0 = Debug|Any CPU {B06C5612-2346-44B1-9D50-F8373885BD88}.Release|Any CPU.ActiveCfg = Release|Any CPU {B06C5612-2346-44B1-9D50-F8373885BD88}.Release|Any CPU.Build.0 = Release|Any CPU + {B36F7E5A-2745-42B5-8493-D648EF8CC43C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B36F7E5A-2745-42B5-8493-D648EF8CC43C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B36F7E5A-2745-42B5-8493-D648EF8CC43C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B36F7E5A-2745-42B5-8493-D648EF8CC43C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -103,6 +109,7 @@ Global {0145A11E-7780-437B-A86F-CBDDB50BC3D1} = {FA618F0C-1AF5-49AB-AE13-C020B403B64F} {03AB740F-AF31-423E-8546-198B914AF76F} = {FA618F0C-1AF5-49AB-AE13-C020B403B64F} {B06C5612-2346-44B1-9D50-F8373885BD88} = {FA618F0C-1AF5-49AB-AE13-C020B403B64F} + {B36F7E5A-2745-42B5-8493-D648EF8CC43C} = {FA618F0C-1AF5-49AB-AE13-C020B403B64F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3111A492-1818-4438-B718-75199D8E779A}