LSFE/LSFE.Domain/Services/TimeKeeping/AttendanceRepo.cs
2026-07-30 10:31:04 +08:00

109 lines
4.2 KiB
C#

using LSFE.Domain.Contracts.Planning;
using LSFE.Domain.Contracts.TimeKeeping;
using LSFE.Infrastructure.Database;
using LSFE.Infrastructure.Dto;
using LSFE.Infrastructure.Dto.TimeKeeping;
using LSFE.Infrastructure.Entities.Planning;
using LSFE.Infrastructure.Entities.TimeKeeping;
using LSFE.Infrastructure.Model;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace LSFE.Domain.Services.TimeKeeping
{
public class AttendanceRepo : GenericRepository<Attendance>, IAttendanceRepo
{
private readonly LSFEDbContext _context;
public AttendanceRepo(LSFEDbContext context) : base(context)
{
_context = context;
}
public async Task<List<Infrastructure.Entities.TimeKeeping.AttendanceDto>>
GetAttendance(Infrastructure.Dto.TimeKeeping.AttendanceDto dto)
{
var now = DateTime.UtcNow;
var startDate = new DateTime(now.Year,now.Month,1,0, 0, 0,DateTimeKind.Utc);
var endDate = startDate.AddMonths(1);
var attendance = await _context.AttendanceDto
.FromSqlRaw(
"EXEC GetAttendance @UserId,@StartDate,@EndDate,@Period",
new SqlParameter("@UserId", dto.UserId),
new SqlParameter("@StartDate", dto.StartDate ?? startDate),
new SqlParameter("@EndDate", dto.EndDate ?? endDate),
new SqlParameter("@Period", dto.Period ?? "monthly")).ToListAsync();
return attendance ?? new List<Infrastructure.Entities.TimeKeeping.AttendanceDto>();
}
public async Task<List<Attendance>> GetAttendanceToday(CredentialDto dto)
{
var attendance = await _context.Attendances
.FromSqlRaw("EXEC GetAttendanceToday @UserId",
new SqlParameter("@UserId", dto.UserId))
.ToListAsync();
return attendance ?? new List<Attendance>();
}
public async Task<Response> PostPutAttendance(Infrastructure.Dto.TimeKeeping.AttendanceDto dto)
{
try
{
// Query by AppAttendanceId (the mobile app's ID), not AttendanceId (the DB auto-increment)
var logs = await _context.Attendances
.FirstOrDefaultAsync(a => a.UserId == dto.UserId &&
a.AppAttendanceId == dto.AppAttendanceId);
if (logs == null)
{
// Create new record - don't set AttendanceId, let the DB auto-increment it
var attendance = new Attendance
{
AppAttendanceId = dto.AppAttendanceId,
TimeIn = dto.TimeIn,
UserId = dto.UserId,
TimeOut = dto.TimeOut,
TimeInLocation = dto.TimeInLocation,
TimeOutLocation = dto.TimeOutLocation,
SignatureFileNameIn = dto.SignatureFileNameIn,
};
await _context.AddAsync(attendance);
await _context.SaveChangesAsync(); // MUST SAVE!
}
else
{
// Update existing record
logs.TimeIn = dto.TimeIn;
logs.TimeOut = dto.TimeOut;
logs.TimeInLocation = dto.TimeInLocation;
logs.TimeOutLocation = dto.TimeOutLocation;
logs.SignatureFileNameOut = dto.SignatureFileNameOut;
await _context.SaveChangesAsync();
}
return new Response
{
Message = "Sync Successfully",
MessCode = 1,
Success = true
};
}
catch (Exception ex)
{
// Log the actual error
Debug.WriteLine($"PostPutAttendance Error: {ex.ToString()}");
throw; // Re-throw so the controller can log it
}
}
}
}