Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/api/HRIS.Api/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

public DbSet<User> Users => Set<User>();
public DbSet<Role> Roles => Set<Role>();
public DbSet<DailyReport> DailyReports => Set<DailyReport>();
public DbSet<DailyReportTask> DailyReportTasks => Set<DailyReportTask>();
public DbSet<Permission> Permissions => Set<Permission>();
public DbSet<ActivityLog> ActivityLogs => Set<ActivityLog>();
public DbSet<Employee> Employees => Set<Employee>();
Expand Down
50 changes: 50 additions & 0 deletions apps/api/HRIS.Api/Data/Configurations/DailyReportConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using HRIS.Api.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace HRIS.Api.Data.Configurations;

public class DailyReportConfiguration : IEntityTypeConfiguration<DailyReport>
{
public void Configure(EntityTypeBuilder<DailyReport> builder)
{
builder.ToTable("daily_reports");
builder.HasKey(x => x.Id);
builder.Property(x => x.WorkArrangement).HasMaxLength(50).IsRequired();
builder.Property(x => x.Project).HasMaxLength(200).IsRequired();
builder.Property(x => x.SprintIteration).HasMaxLength(100);
builder.Property(x => x.TeamUnit).HasMaxLength(100);
builder.Property(x => x.AvgResponseTime).HasMaxLength(50);
builder.Property(x => x.ConnectivityIssues).HasMaxLength(500);
builder.Property(x => x.CollaborationLog).HasMaxLength(1000);

builder.Property(x => x.KeyAccomplishments).HasMaxLength(2000);
builder.Property(x => x.BlockersIssues).HasMaxLength(1000);
builder.Property(x => x.RisksEarlyWarnings).HasMaxLength(1000);
builder.Property(x => x.PlanForTomorrow).HasMaxLength(1000);
builder.Property(x => x.SupportEscalationNeeded).HasMaxLength(500);
builder.Property(x => x.WorkArrangementTomorrow).HasMaxLength(50);
builder.Property(x => x.LeaveAbsenceNotice).HasMaxLength(500);
builder.Property(x => x.SupervisorNotes).HasMaxLength(2000);
builder.Property(x => x.PerformanceRating).HasMaxLength(50);
builder.Property(x => x.ManagerActionItems).HasMaxLength(1000);
builder.Property(x => x.ReviewedBy).HasMaxLength(200);

builder.HasOne(x => x.Employee)
.WithMany()
.HasForeignKey(x => x.EmployeeId)
.OnDelete(DeleteBehavior.Restrict);

builder.HasOne(x => x.SubmittedTo)
.WithMany()
.HasForeignKey(x => x.SubmittedToUserId)
.OnDelete(DeleteBehavior.Restrict);

builder.HasMany(x => x.Tasks)
.WithOne(x => x.DailyReport)
.HasForeignKey(x => x.DailyReportId)
.OnDelete(DeleteBehavior.Cascade);

builder.HasIndex(x => new { x.EmployeeId, x.ReportDate }).IsUnique();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using HRIS.Api.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace HRIS.Api.Data.Configurations;

public class DailyReportTaskConfiguration : IEntityTypeConfiguration<DailyReportTask>
{
public void Configure(EntityTypeBuilder<DailyReportTask> builder)
{
builder.ToTable("daily_report_tasks");
builder.HasKey(x => x.Id);
builder.Property(x => x.Priority).HasMaxLength(20).IsRequired();
builder.Property(x => x.TaskType).HasMaxLength(50).IsRequired();
builder.Property(x => x.TicketRefNo).HasMaxLength(100);
builder.Property(x => x.Description).HasMaxLength(500).IsRequired();
builder.Property(x => x.Module).HasMaxLength(100);
builder.Property(x => x.Status).HasMaxLength(50).IsRequired();
builder.Property(x => x.EstimatedHours).HasPrecision(4, 2);
builder.Property(x => x.ActualHours).HasPrecision(4, 2);
builder.Property(x => x.OutputDeliverable).HasMaxLength(500);
builder.Property(x => x.CommitPrLink).HasMaxLength(500);
builder.Property(x => x.BlockedByRemarks).HasMaxLength(500);
builder.HasIndex(x => new { x.DailyReportId, x.TaskNumber }).IsUnique();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using HRIS.Api.Features.Attendance.DTOs;
using HRIS.Api.Features.Attendance.Services;
using HRIS.Api.Features.IAM.Controllers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace HRIS.Api.Features.Attendance.Controllers;

[ApiController]
[Route("api/daily-reports")]
[Authorize]
public class DailyReportsController : ControllerBase
{
private readonly IDailyReportsService _service;

public DailyReportsController(IDailyReportsService service) => _service = service;

[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateDailyReportRequest request)
{
var result = await _service.CreateAsync(User, request);
return StatusCode(StatusCodes.Status201Created, result);
}

[HttpPatch("{id}")]
public async Task<IActionResult> Update(int id, [FromBody] UpdateDailyReportRequest request)
{
var result = await _service.UpdateAsync(id, User, request);
return Ok(result);
}

[HttpPatch("{id}/supervisor-remarks")]
[PermissionAuthorize("ATTENDANCE", "Update")]
public async Task<IActionResult> AddSupervisorRemarks(int id, [FromBody] SupervisorRemarksRequest request)
{
var result = await _service.AddSupervisorRemarksAsync(id, User, request);
return Ok(result);
}

[HttpGet("me")]
public async Task<IActionResult> GetMine([FromQuery] GetDailyReportsQuery query)
{
var result = await _service.GetMineAsync(User, query);
return Ok(result);
}

[HttpGet("{id}")]
[PermissionAuthorize("ATTENDANCE", "View")]
public async Task<IActionResult> GetById(int id)
{
var result = await _service.GetByIdAsync(id);
return result is null ? NotFound() : Ok(result);
}

[HttpGet]
[PermissionAuthorize("ATTENDANCE", "View")]
public async Task<IActionResult> GetAll([FromQuery] GetDailyReportsQuery query)
{
var result = await _service.GetAllAsync(query);
return Ok(result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace HRIS.Api.Features.Attendance.DTOs;

public class CreateDailyReportRequest
{
public DateOnly ReportDate { get; set; }
public string WorkArrangement { get; set; } = string.Empty;
public string Project { get; set; } = string.Empty;
public string? SprintIteration { get; set; }
public string? TeamUnit { get; set; }
public long? SubmittedToUserId { get; set; }
public TimeOnly? TimeIn { get; set; }
public TimeOnly? TimeOut { get; set; }
[System.ComponentModel.DataAnnotations.Range(0, 1440)]
public int BreakDurationMinutes { get; set; } = 60;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
public bool AttendedStandup { get; set; }
public bool ReachableViaComms { get; set; }
public string? AvgResponseTime { get; set; }
public string? ConnectivityIssues { get; set; }
public string? CollaborationLog { get; set; }
public List<CreateDailyReportTaskRequest> Tasks { get; set; } = new();
}

public class CreateDailyReportTaskRequest
{
public int TaskNumber { get; set; }
public bool IsCarryOver { get; set; }
public string Priority { get; set; } = string.Empty;
public string TaskType { get; set; } = string.Empty;
public string? TicketRefNo { get; set; }
public string Description { get; set; } = string.Empty;
public string? Module { get; set; }
public string Status { get; set; } = string.Empty;

[System.ComponentModel.DataAnnotations.Range(0, 100)]
public int PercentDone { get; set; }

[System.ComponentModel.DataAnnotations.Range(0, double.MaxValue)]
public decimal EstimatedHours { get; set; }

[System.ComponentModel.DataAnnotations.Range(0, double.MaxValue)]
public decimal ActualHours { get; set; }

public string? OutputDeliverable { get; set; }
public string? CommitPrLink { get; set; }
public string? BlockedByRemarks { get; set; }
}
76 changes: 76 additions & 0 deletions apps/api/HRIS.Api/Features/Attendance/DTOs/DailyReportDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
namespace HRIS.Api.Features.Attendance.DTOs;

public class DailyReportDto
{
public int Id { get; set; }
public Guid EmployeeId { get; set; }
public string EmployeeName { get; set; } = string.Empty;
public DateOnly ReportDate { get; set; }
public string WorkArrangement { get; set; } = string.Empty;
public DateTime SubmissionTime { get; set; }
public string Project { get; set; } = string.Empty;
public string? SprintIteration { get; set; }
public string? TeamUnit { get; set; }
public long? SubmittedToUserId { get; set; }
public TimeOnly? TimeIn { get; set; }
public TimeOnly? TimeOut { get; set; }
public int BreakDurationMinutes { get; set; }
public bool AttendedStandup { get; set; }
public bool ReachableViaComms { get; set; }
public string? AvgResponseTime { get; set; }
public string? ConnectivityIssues { get; set; }
public string? CollaborationLog { get; set; }

// Section 4
public string? KeyAccomplishments { get; set; }
public string? BlockersIssues { get; set; }
public string? RisksEarlyWarnings { get; set; }
public string? PlanForTomorrow { get; set; }
public string? SupportEscalationNeeded { get; set; }

// Section 5
public bool CodeCommitted { get; set; }
public bool TicketsUpdated { get; set; }
public bool PullRequestCreated { get; set; }
public bool DocumentationUpdated { get; set; }
public bool TestsPassing { get; set; }
public bool ReportSubmittedOnTime { get; set; }
public int ChecklistCompletedCount { get; set; }

// Section 6
public string? WorkArrangementTomorrow { get; set; }
public TimeOnly? ExpectedTimeIn { get; set; }
public string? LeaveAbsenceNotice { get; set; }

// Section 7
public string? SupervisorNotes { get; set; }
public string? PerformanceRating { get; set; }
public bool FollowUpRequired { get; set; }
public DateOnly? ReviewDate { get; set; }
public string? ManagerActionItems { get; set; }

// Section 8
public string? ReviewedBy { get; set; }
public DateOnly? DateReviewed { get; set; }

public List<DailyReportTaskDto> Tasks { get; set; } = new();
}

public class DailyReportTaskDto
{
public int Id { get; set; }
public int TaskNumber { get; set; }
public bool IsCarryOver { get; set; }
public string Priority { get; set; } = string.Empty;
public string TaskType { get; set; } = string.Empty;
public string? TicketRefNo { get; set; }
public string Description { get; set; } = string.Empty;
public string? Module { get; set; }
public string Status { get; set; } = string.Empty;
public int PercentDone { get; set; }
public decimal EstimatedHours { get; set; }
public decimal ActualHours { get; set; }
public string? OutputDeliverable { get; set; }
public string? CommitPrLink { get; set; }
public string? BlockedByRemarks { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace HRIS.Api.Features.Attendance.DTOs;

public class GetDailyReportsQuery
{
public Guid? EmployeeId { get; set; }
public DateOnly? Date { get; set; }
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 20;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace HRIS.Api.Features.Attendance.DTOs;

public class SupervisorRemarksRequest
{
public string? SupervisorNotes { get; set; }
public string? PerformanceRating { get; set; }
public bool? FollowUpRequired { get; set; }
public DateOnly? ReviewDate { get; set; }
public string? ManagerActionItems { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace HRIS.Api.Features.Attendance.DTOs;

public class UpdateDailyReportRequest
{
// Section 4
public string? KeyAccomplishments { get; set; }
public string? BlockersIssues { get; set; }
public string? RisksEarlyWarnings { get; set; }
public string? PlanForTomorrow { get; set; }
public string? SupportEscalationNeeded { get; set; }

// Section 5
public bool? CodeCommitted { get; set; }
public bool? TicketsUpdated { get; set; }
public bool? PullRequestCreated { get; set; }
public bool? DocumentationUpdated { get; set; }
public bool? TestsPassing { get; set; }
public bool? ReportSubmittedOnTime { get; set; }

// Section 6
public string? WorkArrangementTomorrow { get; set; }
public TimeOnly? ExpectedTimeIn { get; set; }
Comment thread
coderabbitai[bot] marked this conversation as resolved.
public string? LeaveAbsenceNotice { get; set; }
}
Loading
Loading