fix leave
This commit is contained in:
parent
f827ed558c
commit
f0fe68d851
9 changed files with 554 additions and 63 deletions
25
BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj
Normal file
25
BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
28
BMA.EHR.CheckInConsumer/Dockerfile
Normal file
28
BMA.EHR.CheckInConsumer/Dockerfile
Normal file
|
|
@ -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"]
|
||||
140
BMA.EHR.CheckInConsumer/Program.cs
Normal file
140
BMA.EHR.CheckInConsumer/Program.cs
Normal file
|
|
@ -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<CheckInRequest>(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<ResponseObject>(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; }
|
||||
}
|
||||
10
BMA.EHR.CheckInConsumer/Properties/launchSettings.json
Normal file
10
BMA.EHR.CheckInConsumer/Properties/launchSettings.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"profiles": {
|
||||
"BMA.EHR.CheckInConsumer": {
|
||||
"commandName": "Project"
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker"
|
||||
}
|
||||
}
|
||||
}
|
||||
8
BMA.EHR.CheckInConsumer/appsettings.json
Normal file
8
BMA.EHR.CheckInConsumer/appsettings.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Rabbit": {
|
||||
"Host": "192.168.1.40",
|
||||
"User": "admin",
|
||||
"Password": "Test123456"
|
||||
},
|
||||
"API": "https://localhost:7283/api/v1"
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// LV1_005 - ลงเวลาเข้า-ออกงาน (USER)
|
||||
/// </summary>
|
||||
|
|
@ -421,6 +427,239 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> 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 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check in Processing
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// </returns>
|
||||
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpPost("process-check-in"), DisableRequestSizeLimit]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult<ResponseObject>> 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 }); ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LV1_005 - ลงเวลาเข้า-ออกงาน (USER)
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// </returns>
|
||||
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpPost("check-in-old"), DisableRequestSizeLimit]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> 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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue