LV1_006 - เช็คเวลาต้องลงเวลาเข้าหรือออกงาน (USER)

This commit is contained in:
Suphonchai Phoonsawat 2023-11-10 14:40:53 +07:00
parent c9f68b045b
commit 065314fd6c
20 changed files with 967 additions and 258 deletions

View file

@ -1,7 +1,7 @@
using BMA.EHR.Application.Messaging;
using BMA.EHR.Application.Repositories;
using BMA.EHR.Application.Repositories.Commands;
using BMA.EHR.Application.Repositories.Leaves;
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
using BMA.EHR.Application.Repositories.MessageQueue;
using BMA.EHR.Application.Repositories.Reports;
using Microsoft.Extensions.DependencyInjection;
@ -36,6 +36,7 @@ namespace BMA.EHR.Application
services.AddTransient<MinIOExamService>();
services.AddTransient<DutyTimeRepository>();
services.AddTransient<UserTimeStampRepository>();
return services;
}

View file

@ -1,11 +1,11 @@
using BMA.EHR.Application.Common.Interfaces;
using BMA.EHR.Application.Messaging;
using BMA.EHR.Domain.Models.Leave;
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace BMA.EHR.Application.Repositories.Leaves
namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
{
public class DutyTimeRepository : GenericRepository<Guid, DutyTime>
{
@ -61,6 +61,11 @@ namespace BMA.EHR.Application.Repositories.Leaves
return await _dbContext.Set<DutyTime>().Where(x => x.IsActive).ToListAsync();
}
public async Task<DutyTime?> GetDefaultAsync()
{
return await _dbContext.Set<DutyTime>().Where(x => x.IsDefault).FirstOrDefaultAsync();
}
#endregion
}
}

View file

@ -0,0 +1,71 @@
using BMA.EHR.Application.Common.Interfaces;
using BMA.EHR.Application.Messaging;
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
{
public class UserTimeStampRepository : GenericRepository<Guid, UserTimeStamp>
{
#region " Fields "
private readonly IApplicationDBContext _dbContext;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly OrganizationCommonRepository _organizationCommonRepository;
private readonly UserProfileRepository _userProfileRepository;
private readonly IConfiguration _configuration;
private readonly EmailSenderService _emailSenderService;
#endregion
#region " Constructor and Destuctor "
public UserTimeStampRepository(IApplicationDBContext dbContext,
IHttpContextAccessor httpContextAccessor,
OrganizationCommonRepository organizationCommonRepository,
UserProfileRepository userProfileRepository,
IConfiguration configuration,
EmailSenderService emailSenderService) : base(dbContext, httpContextAccessor)
{
_dbContext = dbContext;
_httpContextAccessor = httpContextAccessor;
_organizationCommonRepository = organizationCommonRepository;
_userProfileRepository = userProfileRepository;
_configuration = configuration;
_emailSenderService = emailSenderService;
}
#endregion
#region " Properties "
protected Guid UserOrganizationId
{
get
{
if (UserId != null || UserId != "")
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
else
return Guid.Empty;
}
}
#endregion
#region " Methods "
public async Task<UserTimeStamp?> GetLastRecord(Guid keycloakId)
{
var data = await _dbContext.Set<UserTimeStamp>()
.Where(u => u.KeycloakUserId == keycloakId)
.OrderByDescending(u => u.CheckIn)
.FirstOrDefaultAsync();
return data;
}
#endregion
}
}

View file

@ -315,6 +315,40 @@ namespace BMA.EHR.Application.Repositories
}
}
public async Task UploadFileAsync(string fileName, string subFolder)
{
try
{
var fileContents = File.ReadAllBytes(fileName);
System.IO.MemoryStream filestream = new System.IO.MemoryStream(fileContents);
//var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
var fileExt = Path.GetExtension(fileName);
var fileType = MimeTypeMap.GetMimeType(fileExt);
var file_name = Path.GetFileName(fileName);
Console.WriteLine($"{_bucketName}{subFolder}");
Console.WriteLine(fileName);
Console.WriteLine(file_name);
Console.WriteLine(filestream);
Console.WriteLine(fileType);
var request = new PutObjectRequest
{
//BucketName = $"{_bucketName}",
BucketName = $"{_bucketName}{subFolder}",
Key = file_name,
InputStream = filestream,
ContentType = fileType,
CannedACL = S3CannedACL.PublicRead
};
await _s3Client.PutObjectAsync(request);
}
catch
{
throw;
}
}
public async Task GenerateJsonFile(string json, string path, string fileName)
{
var tmpDir = Path.Combine("tmp");

View file

@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
namespace BMA.EHR.Domain.Models.Leave
namespace BMA.EHR.Domain.Models.Leave.TimeAttendants
{
public class DutyTime : EntityBase
{

View file

@ -0,0 +1,44 @@
using BMA.EHR.Domain.Models.Base;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
namespace BMA.EHR.Domain.Models.Leave.TimeAttendants
{
public class UserTimeStamp : EntityBase
{
[Required, Comment("รหัส User ของ Keycloak")]
public Guid KeycloakUserId { get; set; } = Guid.Empty;
[Required, Comment("วัน เวลา เข้างาน")]
public DateTime CheckIn { get; set; } = DateTime.MinValue;
[Comment("วัน เวลา ออกงาน")]
public DateTime? CheckOut { get; set; }
[Required, Comment("นำไปประมวลผลแล้วหรือยัง")]
public bool IsProcess { get; set; } = false;
[Required, Comment("พิกัดละติจูด")]
public double Lat { get; set; } = 0;
[Required, Comment("พิกัดลองจิจูด")]
public double Lon { get; set; } = 0;
[Required, Comment("ชื่อสถานที่ ได้มาจากระบบ ArcGis ของกองสารสนเทศภูมิศาสตร์")]
public string POI { get; set; } = string.Empty;
[Required, Comment("true คือ ณ สถานที่ตั้ง, false คือ นอกสถานที่ตั้ง")]
public bool IsLocation { get; set; } = true;
[Comment("กรณีเลือกนอกสถานที่ตั้ง ต้องระบุข้อมูลชื่อสถานะที่")]
public string? LocationName { get; set; } = string.Empty;
[Required, Comment("รูปถ่ายสถานที่ checkin/checkout")]
public string ImageUrl { get; set; } = string.Empty;
[Comment("ข้อความหมายเหตุที่ต้องการระบุเพิ่ม(มีเผื่อไว้อาจไม่ได้ใช้)")]
public string? Remark { get; set; } = string.Empty;
}
}

View file

@ -9,6 +9,30 @@ namespace BMA.EHR.Infrastructure
{
public static class InfrastructureServiceRegistration
{
public static IServiceCollection AddLeavePersistence(this IServiceCollection services,
IConfiguration configuration)
{
services.AddScoped<IApplicationDBExamContext>(provider => provider.GetService<ApplicationDBExamContext>());
// leave db context
var connectionStringLeave = configuration.GetConnectionString("LeaveConnection");
services.AddDbContext<LeaveDbContext>(options =>
options.UseMySql(connectionStringLeave, ServerVersion.AutoDetect(connectionStringLeave),
b =>
{
b.MigrationsAssembly(typeof(LeaveDbContext).Assembly.FullName);
b.MigrationsHistoryTable("__LeaveMigrationsHistory");
}),
ServiceLifetime.Transient);
services.AddScoped<IApplicationDBContext>(provider => provider.GetService<LeaveDbContext>());
return services;
}
public static IServiceCollection AddPersistence(this IServiceCollection services,
IConfiguration configuration)
{
@ -41,22 +65,7 @@ namespace BMA.EHR.Infrastructure
}),
ServiceLifetime.Transient);
services.AddScoped<IApplicationDBExamContext>(provider => provider.GetService<ApplicationDBExamContext>());
// leave db context
var connectionStringLeave = configuration.GetConnectionString("LeaveConnection");
services.AddDbContext<LeaveDbContext>(options =>
options.UseMySql(connectionStringLeave, ServerVersion.AutoDetect(connectionStringLeave),
b =>
{
b.MigrationsAssembly(typeof(LeaveDbContext).Assembly.FullName);
b.MigrationsHistoryTable("__LeaveMigrationsHistory");
}),
ServiceLifetime.Transient);
services.AddScoped<IApplicationDBContext>(provider => provider.GetService<LeaveDbContext>());
return services;
}

View file

@ -0,0 +1,180 @@
// <auto-generated />
using System;
using BMA.EHR.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
{
[DbContext(typeof(LeaveDbContext))]
[Migration("20231110034258_ Add user timestamps ")]
partial class Addusertimestamps
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.DutyTime", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)")
.HasColumnOrder(0)
.HasComment("PrimaryKey")
.HasAnnotation("Relational:JsonPropertyName", "id");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(100)
.HasComment("สร้างข้อมูลเมื่อ");
b.Property<string>("CreatedFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(104)
.HasComment("ชื่อ User ที่สร้างข้อมูล");
b.Property<string>("CreatedUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(101)
.HasComment("User Id ที่สร้างข้อมูล");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext")
.HasComment("คำอธิบาย");
b.Property<string>("EndTimeAfternoon")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาออกงานช่วงบ่าย");
b.Property<string>("EndTimeMorning")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาออกงานช่วงเช้า");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)")
.HasComment("สถานะการเปิดใช้งาน (เปิด/ปิด)");
b.Property<bool>("IsDefault")
.HasColumnType("tinyint(1)")
.HasComment("สถานะว่ารอบใดเป็นค่า Default ของข้าราชการ (สำหรับทุกคนที่ยังไม่ได้ทำการเลือกรอบ)");
b.Property<string>("LastUpdateFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(105)
.HasComment("ชื่อ User ที่แก้ไขข้อมูลล่าสุด");
b.Property<string>("LastUpdateUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(103)
.HasComment("User Id ที่แก้ไขข้อมูลล่าสุด");
b.Property<DateTime?>("LastUpdatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(102)
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
b.Property<string>("StartTimeAfternoon")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาเข้างานช่วงบ่าย");
b.Property<string>("StartTimeMorning")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาเข้างานช่วงเช้า");
b.HasKey("Id");
b.ToTable("DutyTimes");
});
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.UserTimeStamp", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)")
.HasColumnOrder(0)
.HasComment("PrimaryKey")
.HasAnnotation("Relational:JsonPropertyName", "id");
b.Property<DateTime>("CheckIn")
.HasColumnType("datetime(6)")
.HasComment("วัน เวลา เข้างาน");
b.Property<DateTime?>("CheckOut")
.HasColumnType("datetime(6)")
.HasComment("วัน เวลา ออกงาน");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(100)
.HasComment("สร้างข้อมูลเมื่อ");
b.Property<string>("CreatedFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(104)
.HasComment("ชื่อ User ที่สร้างข้อมูล");
b.Property<string>("CreatedUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(101)
.HasComment("User Id ที่สร้างข้อมูล");
b.Property<bool>("IsProcess")
.HasColumnType("tinyint(1)")
.HasComment("นำไปประมวลผลแล้วหรือยัง");
b.Property<Guid>("KeycloakUserId")
.HasColumnType("char(36)")
.HasComment("รหัส User ของ Keycloak");
b.Property<string>("LastUpdateFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(105)
.HasComment("ชื่อ User ที่แก้ไขข้อมูลล่าสุด");
b.Property<string>("LastUpdateUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(103)
.HasComment("User Id ที่แก้ไขข้อมูลล่าสุด");
b.Property<DateTime?>("LastUpdatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(102)
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
b.HasKey("Id");
b.ToTable("UserTimeStamps");
});
#pragma warning restore 612, 618
}
}
}

View file

@ -0,0 +1,48 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
{
/// <inheritdoc />
public partial class Addusertimestamps : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "UserTimeStamps",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, comment: "PrimaryKey", collation: "ascii_general_ci"),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false, comment: "สร้างข้อมูลเมื่อ"),
CreatedUserId = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false, comment: "User Id ที่สร้างข้อมูล")
.Annotation("MySql:CharSet", "utf8mb4"),
LastUpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true, comment: "แก้ไขข้อมูลล่าสุดเมื่อ"),
LastUpdateUserId = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false, comment: "User Id ที่แก้ไขข้อมูลล่าสุด")
.Annotation("MySql:CharSet", "utf8mb4"),
CreatedFullName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false, comment: "ชื่อ User ที่สร้างข้อมูล")
.Annotation("MySql:CharSet", "utf8mb4"),
LastUpdateFullName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false, comment: "ชื่อ User ที่แก้ไขข้อมูลล่าสุด")
.Annotation("MySql:CharSet", "utf8mb4"),
KeycloakUserId = table.Column<Guid>(type: "char(36)", nullable: false, comment: "รหัส User ของ Keycloak", collation: "ascii_general_ci"),
CheckIn = table.Column<DateTime>(type: "datetime(6)", nullable: false, comment: "วัน เวลา เข้างาน"),
CheckOut = table.Column<DateTime>(type: "datetime(6)", nullable: true, comment: "วัน เวลา ออกงาน"),
IsProcess = table.Column<bool>(type: "tinyint(1)", nullable: false, comment: "นำไปประมวลผลแล้วหรือยัง")
},
constraints: table =>
{
table.PrimaryKey("PK_UserTimeStamps", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserTimeStamps");
}
}
}

View file

@ -0,0 +1,210 @@
// <auto-generated />
using System;
using BMA.EHR.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
{
[DbContext(typeof(LeaveDbContext))]
[Migration("20231110064104_ update field user timestamps ")]
partial class updatefieldusertimestamps
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.DutyTime", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)")
.HasColumnOrder(0)
.HasComment("PrimaryKey")
.HasAnnotation("Relational:JsonPropertyName", "id");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(100)
.HasComment("สร้างข้อมูลเมื่อ");
b.Property<string>("CreatedFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(104)
.HasComment("ชื่อ User ที่สร้างข้อมูล");
b.Property<string>("CreatedUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(101)
.HasComment("User Id ที่สร้างข้อมูล");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext")
.HasComment("คำอธิบาย");
b.Property<string>("EndTimeAfternoon")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาออกงานช่วงบ่าย");
b.Property<string>("EndTimeMorning")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาออกงานช่วงเช้า");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)")
.HasComment("สถานะการเปิดใช้งาน (เปิด/ปิด)");
b.Property<bool>("IsDefault")
.HasColumnType("tinyint(1)")
.HasComment("สถานะว่ารอบใดเป็นค่า Default ของข้าราชการ (สำหรับทุกคนที่ยังไม่ได้ทำการเลือกรอบ)");
b.Property<string>("LastUpdateFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(105)
.HasComment("ชื่อ User ที่แก้ไขข้อมูลล่าสุด");
b.Property<string>("LastUpdateUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(103)
.HasComment("User Id ที่แก้ไขข้อมูลล่าสุด");
b.Property<DateTime?>("LastUpdatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(102)
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
b.Property<string>("StartTimeAfternoon")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาเข้างานช่วงบ่าย");
b.Property<string>("StartTimeMorning")
.IsRequired()
.HasColumnType("longtext")
.HasComment("เวลาเข้างานช่วงเช้า");
b.HasKey("Id");
b.ToTable("DutyTimes");
});
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.UserTimeStamp", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)")
.HasColumnOrder(0)
.HasComment("PrimaryKey")
.HasAnnotation("Relational:JsonPropertyName", "id");
b.Property<DateTime>("CheckIn")
.HasColumnType("datetime(6)")
.HasComment("วัน เวลา เข้างาน");
b.Property<DateTime?>("CheckOut")
.HasColumnType("datetime(6)")
.HasComment("วัน เวลา ออกงาน");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(100)
.HasComment("สร้างข้อมูลเมื่อ");
b.Property<string>("CreatedFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(104)
.HasComment("ชื่อ User ที่สร้างข้อมูล");
b.Property<string>("CreatedUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(101)
.HasComment("User Id ที่สร้างข้อมูล");
b.Property<string>("ImageUrl")
.IsRequired()
.HasColumnType("longtext")
.HasComment("รูปถ่ายสถานที่ checkin/checkout");
b.Property<bool>("IsLocation")
.HasColumnType("tinyint(1)")
.HasComment("true คือ ณ สถานที่ตั้ง, false คือ นอกสถานที่ตั้ง");
b.Property<bool>("IsProcess")
.HasColumnType("tinyint(1)")
.HasComment("นำไปประมวลผลแล้วหรือยัง");
b.Property<Guid>("KeycloakUserId")
.HasColumnType("char(36)")
.HasComment("รหัส User ของ Keycloak");
b.Property<string>("LastUpdateFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(105)
.HasComment("ชื่อ User ที่แก้ไขข้อมูลล่าสุด");
b.Property<string>("LastUpdateUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(103)
.HasComment("User Id ที่แก้ไขข้อมูลล่าสุด");
b.Property<DateTime?>("LastUpdatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(102)
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
b.Property<double>("Lat")
.HasColumnType("double")
.HasComment("พิกัดละติจูด");
b.Property<string>("LocationName")
.HasColumnType("longtext")
.HasComment("กรณีเลือกนอกสถานที่ตั้ง ต้องระบุข้อมูลชื่อสถานะที่");
b.Property<double>("Lon")
.HasColumnType("double")
.HasComment("พิกัดลองจิจูด");
b.Property<string>("POI")
.IsRequired()
.HasColumnType("longtext")
.HasComment("ชื่อสถานที่ ได้มาจากระบบ ArcGis ของกองสารสนเทศภูมิศาสตร์");
b.Property<string>("Remark")
.HasColumnType("longtext")
.HasComment("ข้อความหมายเหตุที่ต้องการระบุเพิ่ม(มีเผื่อไว้อาจไม่ได้ใช้)");
b.HasKey("Id");
b.ToTable("UserTimeStamps");
});
#pragma warning restore 612, 618
}
}
}

View file

@ -0,0 +1,102 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
{
/// <inheritdoc />
public partial class updatefieldusertimestamps : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ImageUrl",
table: "UserTimeStamps",
type: "longtext",
nullable: false,
comment: "รูปถ่ายสถานที่ checkin/checkout")
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<bool>(
name: "IsLocation",
table: "UserTimeStamps",
type: "tinyint(1)",
nullable: false,
defaultValue: false,
comment: "true คือ ณ สถานที่ตั้ง, false คือ นอกสถานที่ตั้ง");
migrationBuilder.AddColumn<double>(
name: "Lat",
table: "UserTimeStamps",
type: "double",
nullable: false,
defaultValue: 0.0,
comment: "พิกัดละติจูด");
migrationBuilder.AddColumn<string>(
name: "LocationName",
table: "UserTimeStamps",
type: "longtext",
nullable: true,
comment: "กรณีเลือกนอกสถานที่ตั้ง ต้องระบุข้อมูลชื่อสถานะที่")
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<double>(
name: "Lon",
table: "UserTimeStamps",
type: "double",
nullable: false,
defaultValue: 0.0,
comment: "พิกัดลองจิจูด");
migrationBuilder.AddColumn<string>(
name: "POI",
table: "UserTimeStamps",
type: "longtext",
nullable: false,
comment: "ชื่อสถานที่ ได้มาจากระบบ ArcGis ของกองสารสนเทศภูมิศาสตร์")
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<string>(
name: "Remark",
table: "UserTimeStamps",
type: "longtext",
nullable: true,
comment: "ข้อความหมายเหตุที่ต้องการระบุเพิ่ม(มีเผื่อไว้อาจไม่ได้ใช้)")
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ImageUrl",
table: "UserTimeStamps");
migrationBuilder.DropColumn(
name: "IsLocation",
table: "UserTimeStamps");
migrationBuilder.DropColumn(
name: "Lat",
table: "UserTimeStamps");
migrationBuilder.DropColumn(
name: "LocationName",
table: "UserTimeStamps");
migrationBuilder.DropColumn(
name: "Lon",
table: "UserTimeStamps");
migrationBuilder.DropColumn(
name: "POI",
table: "UserTimeStamps");
migrationBuilder.DropColumn(
name: "Remark",
table: "UserTimeStamps");
}
}
}

View file

@ -19,7 +19,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.DutyTime", b =>
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.DutyTime", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
@ -103,6 +103,104 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
b.ToTable("DutyTimes");
});
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.UserTimeStamp", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)")
.HasColumnOrder(0)
.HasComment("PrimaryKey")
.HasAnnotation("Relational:JsonPropertyName", "id");
b.Property<DateTime>("CheckIn")
.HasColumnType("datetime(6)")
.HasComment("วัน เวลา เข้างาน");
b.Property<DateTime?>("CheckOut")
.HasColumnType("datetime(6)")
.HasComment("วัน เวลา ออกงาน");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(100)
.HasComment("สร้างข้อมูลเมื่อ");
b.Property<string>("CreatedFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(104)
.HasComment("ชื่อ User ที่สร้างข้อมูล");
b.Property<string>("CreatedUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(101)
.HasComment("User Id ที่สร้างข้อมูล");
b.Property<string>("ImageUrl")
.IsRequired()
.HasColumnType("longtext")
.HasComment("รูปถ่ายสถานที่ checkin/checkout");
b.Property<bool>("IsLocation")
.HasColumnType("tinyint(1)")
.HasComment("true คือ ณ สถานที่ตั้ง, false คือ นอกสถานที่ตั้ง");
b.Property<bool>("IsProcess")
.HasColumnType("tinyint(1)")
.HasComment("นำไปประมวลผลแล้วหรือยัง");
b.Property<Guid>("KeycloakUserId")
.HasColumnType("char(36)")
.HasComment("รหัส User ของ Keycloak");
b.Property<string>("LastUpdateFullName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)")
.HasColumnOrder(105)
.HasComment("ชื่อ User ที่แก้ไขข้อมูลล่าสุด");
b.Property<string>("LastUpdateUserId")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnOrder(103)
.HasComment("User Id ที่แก้ไขข้อมูลล่าสุด");
b.Property<DateTime?>("LastUpdatedAt")
.HasColumnType("datetime(6)")
.HasColumnOrder(102)
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
b.Property<double>("Lat")
.HasColumnType("double")
.HasComment("พิกัดละติจูด");
b.Property<string>("LocationName")
.HasColumnType("longtext")
.HasComment("กรณีเลือกนอกสถานที่ตั้ง ต้องระบุข้อมูลชื่อสถานะที่");
b.Property<double>("Lon")
.HasColumnType("double")
.HasComment("พิกัดลองจิจูด");
b.Property<string>("POI")
.IsRequired()
.HasColumnType("longtext")
.HasComment("ชื่อสถานที่ ได้มาจากระบบ ArcGis ของกองสารสนเทศภูมิศาสตร์");
b.Property<string>("Remark")
.HasColumnType("longtext")
.HasComment("ข้อความหมายเหตุที่ต้องการระบุเพิ่ม(มีเผื่อไว้อาจไม่ได้ใช้)");
b.HasKey("Id");
b.ToTable("UserTimeStamps");
});
#pragma warning restore 612, 618
}
}

View file

@ -1,15 +1,17 @@
using BMA.EHR.Application.Common.Interfaces;
using BMA.EHR.Domain.Models.Leave;
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
using Microsoft.EntityFrameworkCore;
namespace BMA.EHR.Infrastructure.Persistence
{
public class LeaveDbContext : DbContext, IApplicationDBContext
{
#region " Leave "
#region " Check-In "
public DbSet<DutyTime> DutyTimes { get; set; }
public DbSet<UserTimeStamp> UserTimeStamps { get; set; }
#endregion

View file

@ -9,8 +9,13 @@
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DockerfileContext>.</DockerfileContext>
<RootNamespace>BMA.EHR.Command.Service</RootNamespace>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Controllers\CheckInController.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\.dockerignore" Link=".dockerignore">
<DependentUpon>$(DockerDefaultDockerfile)</DependentUpon>

View file

@ -1,114 +0,0 @@
using BMA.EHR.Application.Repositories;
using BMA.EHR.Application.Repositories.Leaves;
using BMA.EHR.Command.Service.DTOs.POI;
using BMA.EHR.Domain.Common;
using BMA.EHR.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Swashbuckle.AspNetCore.Annotations;
using System.Security.Claims;
namespace BMA.EHR.Command.Service.Controllers
{
[Route("api/v{version:apiVersion}/leave/check-in")]
[ApiVersion("1.0")]
[ApiController]
[Produces("application/json")]
[Authorize]
[SwaggerTag("API ระบบลงเวลาทำงาน")]
public class CheckInController : BaseController
{
#region " Fields "
private readonly DutyTimeRepository _repository;
private readonly LeaveDbContext _context;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly IConfiguration _configuration;
private readonly UserProfileRepository _userProfileRepository;
#endregion
#region " Constuctor and Destructor "
public CheckInController(DutyTimeRepository repository,
LeaveDbContext context,
IHttpContextAccessor httpContextAccessor,
IWebHostEnvironment hostingEnvironment,
IConfiguration configuration,
UserProfileRepository userProfileRepository)
{
_repository = repository;
_context = context;
_httpContextAccessor = httpContextAccessor;
_hostingEnvironment = hostingEnvironment;
_configuration = configuration;
_userProfileRepository = userProfileRepository;
}
#endregion
#region " Properties "
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
private bool? PlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
private Guid OcId
{
get
{
if (UserId != null || UserId != "")
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
else
return Guid.Empty;
}
}
#endregion
#region " Methods "
[HttpPost("locations")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[AllowAnonymous]
public async Task<ActionResult<ResponseObject>> ListPOIAsync([FromBody] GetPOIDto data)
{
var api_url = $"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={data.Lat},{data.Lon}&types=point_of_interest&radius=100&sensor=false&language=th&key=AIzaSyDXKvpU4hinlCKGOEJUgLDbx9yCSZe3woc";
using (var client = new HttpClient())
{
var req = new HttpRequestMessage(HttpMethod.Get, api_url);
var res = await client.SendAsync(req);
var result = await res.Content.ReadAsStringAsync();
var poi_result = JsonConvert.DeserializeObject<GetPOIResultDto>(result);
var poi_data = new List<POIResultDto>();
if (poi_result != null)
{
foreach (var r in poi_result.results.Take(5))
{
poi_data.Add(new POIResultDto
{
Id = r.place_id,
Name = r.name,
Latitude = r.geometry.location.lat,
Longitude = r.geometry.location.lng,
});
}
}
return Success(poi_data);
}
}
#endregion
}
}

View file

@ -1,8 +1,10 @@
using BMA.EHR.Application.Repositories;
using BMA.EHR.Application.Repositories.Leaves;
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
using BMA.EHR.Command.Service.DTOs.CheckIn;
using BMA.EHR.Command.Service.DTOs.DutyTime;
using BMA.EHR.Domain.Common;
using BMA.EHR.Domain.Models.Leave;
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
using BMA.EHR.Domain.Shared;
using BMA.EHR.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
@ -12,40 +14,43 @@ using System.Security.Claims;
namespace BMA.EHR.Command.Service.Controllers
{
[Route("api/v{version:apiVersion}/leave/duty-time")]
[Route("api/v{version:apiVersion}/leave")]
[ApiVersion("1.0")]
[ApiController]
[Produces("application/json")]
[Authorize]
[SwaggerTag("API ระบบจัดการรอบการลงเวลาทำงาน")]
public class DutyTimeController : BaseController
[SwaggerTag("API ระบบลงเวลาและการลา")]
public class LeaveController : BaseController
{
#region " Fields "
private readonly DutyTimeRepository _repository;
private readonly DutyTimeRepository _dutyTimeRepository;
private readonly LeaveDbContext _context;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly IConfiguration _configuration;
private readonly UserProfileRepository _userProfileRepository;
private readonly UserTimeStampRepository _userTimeStampRepository;
#endregion
#region " Constuctor and Destructor "
public DutyTimeController(DutyTimeRepository repository,
public LeaveController(DutyTimeRepository dutyTimeRepository,
LeaveDbContext context,
IHttpContextAccessor httpContextAccessor,
IWebHostEnvironment hostingEnvironment,
IConfiguration configuration,
UserProfileRepository userProfileRepository)
UserProfileRepository userProfileRepository,
UserTimeStampRepository userTimeStampRepository)
{
_repository = repository;
_dutyTimeRepository = dutyTimeRepository;
_context = context;
_httpContextAccessor = httpContextAccessor;
_hostingEnvironment = hostingEnvironment;
_configuration = configuration;
_userProfileRepository = userProfileRepository;
_userTimeStampRepository = userTimeStampRepository;
}
#endregion
@ -73,6 +78,8 @@ namespace BMA.EHR.Command.Service.Controllers
#region " Methods "
#region " Duty Time รอบการทำงาน "
/// <summary>
/// LV1_004 - ข้อมูลทั้งหมดของรอบการปฏิบัติงาน (ADMIN)
/// </summary>
@ -81,13 +88,13 @@ namespace BMA.EHR.Command.Service.Controllers
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet]
[HttpGet("duty-time")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetAllAsync()
{
var data = await _repository.GetAllAsync();
var data = await _dutyTimeRepository.GetAllAsync();
return Success(data);
}
@ -100,13 +107,13 @@ namespace BMA.EHR.Command.Service.Controllers
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("{id:guid}")]
[HttpGet("duty-time/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetByIdAsync(Guid id)
{
var data = await _repository.GetByIdAsync(id);
var data = await _dutyTimeRepository.GetByIdAsync(id);
return Success(data);
}
@ -119,7 +126,7 @@ namespace BMA.EHR.Command.Service.Controllers
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPost]
[HttpPost("duty-time")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
@ -141,7 +148,7 @@ namespace BMA.EHR.Command.Service.Controllers
throw new Exception(GlobalMessages.StartTimeGreaterEnd);
}
var oldData = await _repository.GetAllAsync();
var oldData = await _dutyTimeRepository.GetAllAsync();
if (oldData == null || oldData.Count == 0)
{
var inserted = new DutyTime
@ -156,7 +163,7 @@ namespace BMA.EHR.Command.Service.Controllers
IsDefault = true,
};
var ret = await _repository.AddAsync(inserted);
var ret = await _dutyTimeRepository.AddAsync(inserted);
return Success(ret);
}
@ -167,7 +174,7 @@ namespace BMA.EHR.Command.Service.Controllers
foreach (var d in oldData)
{
d.IsDefault = false;
await _repository.UpdateAsync(d);
await _dutyTimeRepository.UpdateAsync(d);
}
}
@ -183,7 +190,7 @@ namespace BMA.EHR.Command.Service.Controllers
IsDefault = data.IsDefault,
};
var ret = await _repository.AddAsync(inserted);
var ret = await _dutyTimeRepository.AddAsync(inserted);
return Success(ret);
}
@ -198,26 +205,26 @@ namespace BMA.EHR.Command.Service.Controllers
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpPut("{id:guid}")]
[HttpPut("duty-time/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> PutAsync(Guid id, [FromBody] UpdateDutyTimeDto data)
{
var oldData = await _repository.GetByIdAsync(id);
var oldData = await _dutyTimeRepository.GetByIdAsync(id);
if (oldData == null)
{
throw new Exception(GlobalMessages.DataNotFound);
}
else
{
var oldDataList = await _repository.GetAllAsync();
{
var oldDataList = await _dutyTimeRepository.GetAllAsync();
if (data.IsDefault)
{
foreach (var d in oldDataList)
{
d.IsDefault = false;
await _repository.UpdateAsync(d);
await _dutyTimeRepository.UpdateAsync(d);
}
}
@ -225,7 +232,7 @@ namespace BMA.EHR.Command.Service.Controllers
oldData.IsDefault = data.IsDefault;
oldData.IsActive = data.IsActive;
await _repository.UpdateAsync(oldData);
await _dutyTimeRepository.UpdateAsync(oldData);
return Success(oldData);
@ -241,13 +248,13 @@ namespace BMA.EHR.Command.Service.Controllers
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpDelete("{id:guid}")]
[HttpDelete("duty-time/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> DeleteAsync(Guid id)
{
var oldData = await _repository.GetByIdAsync(id);
var oldData = await _dutyTimeRepository.GetByIdAsync(id);
if (oldData == null)
{
throw new Exception(GlobalMessages.DataNotFound);
@ -259,11 +266,87 @@ namespace BMA.EHR.Command.Service.Controllers
throw new Exception("ไม่สามารถลบรอบการปฏิบัติงานที่ยังใช้งานอยู่ได้");
}
await _repository.DeleteAsync(oldData);
await _dutyTimeRepository.DeleteAsync(oldData);
return Success();
}
}
/// <summary>
/// LV1_012 - ข้อมูลทั้งหมดของรอบการปฏิบัติงานที่ active (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("round")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetAllActiveAsync()
{
var data = await _dutyTimeRepository.GetAllActiveAsync();
return Success(data);
}
#endregion
#region " Check-In Check-Out ลงเวลา "
/// <summary>
/// LV1_006 - เช็คเวลาต้องลงเวลาเข้าหรือออกงาน (USER)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet("check-time")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> CheckTimeAsync()
{
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
var data = await _userTimeStampRepository.GetLastRecord(userId);
// TODO : รอดุึงรอบที่ผูกกับ user
var duty = await _dutyTimeRepository.GetDefaultAsync();
CheckInResultDto ret;
if (data == null)
{
ret = new CheckInResultDto
{
StartTimeMorning = duty == null ? "00:00" : duty.StartTimeMorning,
EndTimeMorning = duty == null ? "00:00" : duty.EndTimeMorning,
StartTimeAfternoon = duty == null ? "00:00" : duty.StartTimeAfternoon,
EndTimeAfternoon = duty == null ? "00:00" : duty.EndTimeAfternoon,
Description = duty == null ? "-" : duty.Description,
CheckInTime = null,
CheckInId = null,
};
}
else
{
ret = new CheckInResultDto
{
StartTimeMorning = duty == null ? "00:00" : duty.StartTimeMorning,
EndTimeMorning = duty == null ? "00:00" : duty.EndTimeMorning,
StartTimeAfternoon = duty == null ? "00:00" : duty.StartTimeAfternoon,
EndTimeAfternoon = duty == null ? "00:00" : duty.EndTimeAfternoon,
Description = duty == null ? "-" : duty.Description,
CheckInTime = data.CheckIn,
CheckInId = data.CheckOut == null ? null : data.Id,
};
}
return Success(ret);
}
#endregion
#endregion
}
}

View file

@ -1,94 +0,0 @@
using BMA.EHR.Application.Repositories;
using BMA.EHR.Application.Repositories.Leaves;
using BMA.EHR.Domain.Common;
using BMA.EHR.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Security.Claims;
namespace BMA.EHR.Command.Service.Controllers
{
[Route("api/v{version:apiVersion}/leave/round")]
[ApiVersion("1.0")]
[ApiController]
[Produces("application/json")]
[Authorize]
[SwaggerTag("API ระบบจัดการรอบการลงเวลาทำงาน")]
public class RoundController : BaseController
{
#region " Fields "
private readonly DutyTimeRepository _repository;
private readonly LeaveDbContext _context;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly IConfiguration _configuration;
private readonly UserProfileRepository _userProfileRepository;
#endregion
#region " Constuctor and Destructor "
public RoundController(DutyTimeRepository repository,
LeaveDbContext context,
IHttpContextAccessor httpContextAccessor,
IWebHostEnvironment hostingEnvironment,
IConfiguration configuration,
UserProfileRepository userProfileRepository)
{
_repository = repository;
_context = context;
_httpContextAccessor = httpContextAccessor;
_hostingEnvironment = hostingEnvironment;
_configuration = configuration;
_userProfileRepository = userProfileRepository;
}
#endregion
#region " Properties "
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
private bool? PlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
private Guid OcId
{
get
{
if (UserId != null || UserId != "")
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
else
return Guid.Empty;
}
}
#endregion
#region " Methods "
/// <summary>
/// LV1_012 - ข้อมูลทั้งหมดของรอบการปฏิบัติงานที่ active (ADMIN)
/// </summary>
/// <returns>
/// </returns>
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<ResponseObject>> GetAllActiveAsync()
{
var data = await _repository.GetAllActiveAsync();
return Success(data);
}
#endregion
}
}

View file

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
namespace BMA.EHR.Command.Service.DTOs.CheckIn
{
public class CheckInResultDto
{
public Guid? CheckInId { get; set; }
public DateTime? CheckInTime { get; set; }
public string Description { get; set; } = string.Empty;
public string StartTimeMorning { get; set; } = "00:00";
public string EndTimeMorning { get; set; } = "00:00";
public string StartTimeAfternoon { get; set; } = "00:00";
public string EndTimeAfternoon { get; set; } = "00:00";
}
}

View file

@ -80,6 +80,7 @@ var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddApplication();
builder.Services.AddPersistence(builder.Configuration);
builder.Services.AddLeavePersistence(builder.Configuration);
builder.Services.AddControllers(options =>
{

View file

@ -16,7 +16,9 @@
//"DefaultConnection": "User Id=sys;Password=P@ssw0rd;DBA Privilege=SYSDBA;Data Source=localhost:1521/ORCLCDB",
"DefaultConnection": "server=192.168.1.9;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.9;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.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.9;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",