2026-01-15 16:59:56 +01:00
|
|
|
using System.Text.Json;
|
2026-01-12 22:10:57 +01:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using PlanTempus.Application.Features.Localization.Services;
|
|
|
|
|
|
|
|
|
|
namespace PlanTempus.Application.Features.Employees.Components;
|
|
|
|
|
|
|
|
|
|
public class EmployeeDetailHoursViewComponent : ViewComponent
|
|
|
|
|
{
|
|
|
|
|
private readonly ILocalizationService _localization;
|
2026-01-15 16:59:56 +01:00
|
|
|
private readonly IWebHostEnvironment _environment;
|
2026-01-12 22:10:57 +01:00
|
|
|
|
2026-01-15 16:59:56 +01:00
|
|
|
public EmployeeDetailHoursViewComponent(ILocalizationService localization, IWebHostEnvironment environment)
|
2026-01-12 22:10:57 +01:00
|
|
|
{
|
|
|
|
|
_localization = localization;
|
2026-01-15 16:59:56 +01:00
|
|
|
_environment = environment;
|
2026-01-12 22:10:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IViewComponentResult Invoke(string key)
|
|
|
|
|
{
|
2026-01-15 16:59:56 +01:00
|
|
|
var weekSchedule = LoadMockData();
|
|
|
|
|
var employee = weekSchedule.Employees.FirstOrDefault(e => e.EmployeeId == key);
|
|
|
|
|
var weeks = GenerateWeeks(weekSchedule, employee);
|
|
|
|
|
|
2026-01-12 22:10:57 +01:00
|
|
|
var model = new EmployeeDetailHoursViewModel
|
|
|
|
|
{
|
2026-01-15 16:59:56 +01:00
|
|
|
EmployeeId = key,
|
|
|
|
|
Weeks = weeks,
|
|
|
|
|
DayNames = new[] { "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag" },
|
|
|
|
|
LabelHours = _localization.Get("employees.detail.hours.label")
|
2026-01-12 22:10:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return View(model);
|
|
|
|
|
}
|
2026-01-15 16:59:56 +01:00
|
|
|
|
|
|
|
|
private WeekScheduleData LoadMockData()
|
|
|
|
|
{
|
|
|
|
|
var jsonPath = Path.Combine(_environment.ContentRootPath, "Features", "Employees", "Data", "workScheduleMock.json");
|
|
|
|
|
var json = System.IO.File.ReadAllText(jsonPath);
|
|
|
|
|
return JsonSerializer.Deserialize<WeekScheduleData>(json, new JsonSerializerOptions
|
|
|
|
|
{
|
|
|
|
|
PropertyNameCaseInsensitive = true
|
|
|
|
|
})!;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<WeekHoursData> GenerateWeeks(WeekScheduleData weekSchedule, EmployeeScheduleData? employee)
|
|
|
|
|
{
|
|
|
|
|
var weeks = new List<WeekHoursData>();
|
|
|
|
|
var startDate = DateTime.Parse(weekSchedule.StartDate);
|
|
|
|
|
|
|
|
|
|
// Generate 6 weeks of data (current week + 5 more)
|
|
|
|
|
for (int w = 0; w < 6; w++)
|
|
|
|
|
{
|
|
|
|
|
var weekStart = startDate.AddDays(w * 7);
|
|
|
|
|
var weekNumber = GetWeekNumber(weekStart);
|
|
|
|
|
var days = new List<DayHoursData>();
|
|
|
|
|
var totalMinutes = 0;
|
|
|
|
|
|
|
|
|
|
for (int d = 0; d < 7; d++)
|
|
|
|
|
{
|
|
|
|
|
var date = weekStart.AddDays(d);
|
|
|
|
|
var dateKey = date.ToString("yyyy-MM-dd");
|
|
|
|
|
var shift = employee?.Schedule.GetValueOrDefault(dateKey);
|
|
|
|
|
|
|
|
|
|
string status = "off";
|
|
|
|
|
string display = "—";
|
|
|
|
|
|
|
|
|
|
if (shift != null)
|
|
|
|
|
{
|
|
|
|
|
status = shift.Status;
|
|
|
|
|
if (shift.Status == "work" && shift.Start != null && shift.End != null)
|
|
|
|
|
{
|
|
|
|
|
display = $"{shift.Start} - {shift.End}";
|
|
|
|
|
totalMinutes += CalculateMinutes(shift.Start, shift.End);
|
|
|
|
|
}
|
|
|
|
|
else if (shift.Status == "vacation")
|
|
|
|
|
{
|
|
|
|
|
display = "Ferie";
|
|
|
|
|
}
|
|
|
|
|
else if (shift.Status == "sick")
|
|
|
|
|
{
|
|
|
|
|
display = "Syg";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
days.Add(new DayHoursData
|
|
|
|
|
{
|
|
|
|
|
Date = dateKey,
|
|
|
|
|
Status = status,
|
|
|
|
|
Display = display
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
weeks.Add(new WeekHoursData
|
|
|
|
|
{
|
|
|
|
|
WeekNumber = weekNumber,
|
|
|
|
|
TotalHours = totalMinutes / 60,
|
|
|
|
|
Days = days
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return weeks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetWeekNumber(DateTime date)
|
|
|
|
|
{
|
|
|
|
|
var cal = System.Globalization.CultureInfo.CurrentCulture.Calendar;
|
|
|
|
|
return cal.GetWeekOfYear(date, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int CalculateMinutes(string start, string end)
|
|
|
|
|
{
|
|
|
|
|
var startTime = TimeSpan.Parse(start);
|
|
|
|
|
var endTime = TimeSpan.Parse(end);
|
|
|
|
|
return (int)(endTime - startTime).TotalMinutes;
|
|
|
|
|
}
|
2026-01-12 22:10:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class EmployeeDetailHoursViewModel
|
|
|
|
|
{
|
2026-01-15 16:59:56 +01:00
|
|
|
public required string EmployeeId { get; init; }
|
|
|
|
|
public required List<WeekHoursData> Weeks { get; init; }
|
|
|
|
|
public required string[] DayNames { get; init; }
|
|
|
|
|
public required string LabelHours { get; init; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class WeekHoursData
|
|
|
|
|
{
|
|
|
|
|
public int WeekNumber { get; init; }
|
|
|
|
|
public int TotalHours { get; init; }
|
|
|
|
|
public required List<DayHoursData> Days { get; init; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class DayHoursData
|
|
|
|
|
{
|
|
|
|
|
public required string Date { get; init; }
|
|
|
|
|
public required string Status { get; init; }
|
|
|
|
|
public required string Display { get; init; }
|
2026-01-12 22:10:57 +01:00
|
|
|
}
|