168 lines
7.3 KiB
C#
168 lines
7.3 KiB
C#
using ClosedXML.Excel;
|
|
using System.IO;
|
|
using PSTW_CentralSystem.Models;
|
|
using PSTW_CentralSystem.Areas.OTcalculate.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace PSTW_CentralSystem.Areas.OTcalculate.Services
|
|
{
|
|
public class OvertimeExcelService
|
|
{
|
|
public MemoryStream GenerateOvertimeExcel(
|
|
List<OtRegisterModel> records,
|
|
int departmentId,
|
|
string userFullName,
|
|
string departmentName,
|
|
int userStateId,
|
|
int weekendId,
|
|
List<CalendarModel> publicHolidays,
|
|
bool isAdminUser = false,
|
|
byte[]? logoImage = null // This parameter is missing in the call
|
|
)
|
|
{
|
|
var workbook = new XLWorkbook();
|
|
var worksheet = workbook.Worksheets.Add("Overtime Records");
|
|
int currentRow = 1;
|
|
|
|
// Add Header Information
|
|
if (!string.IsNullOrEmpty(userFullName))
|
|
{
|
|
worksheet.Cell(currentRow, 1).Value = $"Name: {userFullName}";
|
|
currentRow++;
|
|
}
|
|
if (!string.IsNullOrEmpty(departmentName))
|
|
{
|
|
worksheet.Cell(currentRow, 1).Value = $"Department: {departmentName}";
|
|
currentRow++;
|
|
}
|
|
currentRow++; // Add an empty row after header
|
|
|
|
// Header titles
|
|
var headers = new List<string>
|
|
{
|
|
"Day", "Date", "Office From", "Office To", "Office Break",
|
|
"After From", "After To", "After Break",
|
|
"Total OT", "Break Minutes", "Net OT"
|
|
};
|
|
|
|
if (departmentId == 2 || isAdminUser)
|
|
headers.Add("Station");
|
|
|
|
headers.Add("Description");
|
|
|
|
// Set header row
|
|
int headerRow = currentRow;
|
|
for (int i = 0; i < headers.Count; i++)
|
|
{
|
|
var cell = worksheet.Cell(headerRow, i + 1);
|
|
cell.Value = headers[i];
|
|
cell.Style.Font.Bold = true;
|
|
cell.Style.Fill.BackgroundColor = XLColor.LightGray;
|
|
cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
|
|
cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
|
|
cell.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
|
|
}
|
|
currentRow++;
|
|
|
|
// Fill data rows
|
|
foreach (var r in records)
|
|
{
|
|
TimeSpan totalOT = CalculateTotalOT(r);
|
|
int totalBreak = (r.OfficeBreak ?? 0) + (r.AfterBreak ?? 0);
|
|
TimeSpan netOT = totalOT - TimeSpan.FromMinutes(totalBreak);
|
|
|
|
int col = 1;
|
|
var dayCell = worksheet.Cell(currentRow, col++);
|
|
dayCell.Value = r.OtDate.ToString("ddd");
|
|
dayCell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
|
|
dayCell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
|
|
dayCell.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
|
|
|
|
var dateCell = worksheet.Cell(currentRow, col++);
|
|
dateCell.Value = r.OtDate.ToString("yyyy-MM-dd");
|
|
dateCell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
|
|
dateCell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
|
|
dateCell.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
|
|
|
|
// Apply background color for weekends and public holidays
|
|
var dayOfWeek = r.OtDate.DayOfWeek;
|
|
bool isWeekend = (weekendId == 1 && (dayOfWeek == DayOfWeek.Friday || dayOfWeek == DayOfWeek.Saturday)) ||
|
|
(weekendId == 2 && (dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunday));
|
|
bool isPublicHoliday = publicHolidays.Any(h => h.HolidayDate.Date == r.OtDate.Date);
|
|
|
|
if (isPublicHoliday)
|
|
{
|
|
dayCell.Style.Fill.BackgroundColor = XLColor.Pink;
|
|
dateCell.Style.Fill.BackgroundColor = XLColor.Pink;
|
|
}
|
|
else if (isWeekend)
|
|
{
|
|
dayCell.Style.Fill.BackgroundColor = XLColor.LightBlue;
|
|
dateCell.Style.Fill.BackgroundColor = XLColor.LightBlue;
|
|
}
|
|
|
|
worksheet.Cell(currentRow, col++).Value = FormatTime(r.OfficeFrom);
|
|
worksheet.Cell(currentRow, col++).Value = FormatTime(r.OfficeTo);
|
|
worksheet.Cell(currentRow, col++).Value = r.OfficeBreak;
|
|
|
|
worksheet.Cell(currentRow, col++).Value = FormatTime(r.AfterFrom);
|
|
worksheet.Cell(currentRow, col++).Value = FormatTime(r.AfterTo);
|
|
worksheet.Cell(currentRow, col++).Value = r.AfterBreak;
|
|
|
|
worksheet.Cell(currentRow, col++).Value = totalOT.ToString(@"hh\:mm");
|
|
worksheet.Cell(currentRow, col++).Value = totalBreak;
|
|
worksheet.Cell(currentRow, col++).Value = netOT.ToString(@"hh\:mm");
|
|
|
|
if (departmentId == 2 || isAdminUser)
|
|
worksheet.Cell(currentRow, col++).Value = r.Stations?.StationName ?? "";
|
|
|
|
worksheet.Cell(currentRow, col++).Value = r.OtDescription ?? "";
|
|
|
|
// Apply border and alignment for the rest of the row
|
|
for (int i = headers.IndexOf("Office From") + 1; i <= headers.Count; i++)
|
|
{
|
|
var cell = worksheet.Cell(currentRow, i);
|
|
cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
|
|
cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
|
|
cell.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
|
|
}
|
|
|
|
currentRow++;
|
|
}
|
|
|
|
// Add Total row
|
|
int totalRow = currentRow;
|
|
worksheet.Cell(totalRow, 1).Value = "TOTAL";
|
|
worksheet.Cell(totalRow, 1).Style.Font.Bold = true;
|
|
worksheet.Cell(totalRow, headers.IndexOf("Total OT") + 1).Value = $"=SUM(I{headerRow + 1}:I{totalRow - 1})";
|
|
worksheet.Cell(totalRow, headers.IndexOf("Total OT") + 1).Style.Font.Bold = true;
|
|
worksheet.Cell(totalRow, headers.IndexOf("Break Minutes") + 1).Value = $"=SUM(J{headerRow + 1}:J{totalRow - 1})";
|
|
worksheet.Cell(totalRow, headers.IndexOf("Break Minutes") + 1).Style.Font.Bold = true;
|
|
worksheet.Cell(totalRow, headers.IndexOf("Net OT") + 1).Value = $"=SUM(K{headerRow + 1}:K{totalRow - 1})";
|
|
worksheet.Cell(totalRow, headers.IndexOf("Net OT") + 1).Style.Font.Bold = true;
|
|
|
|
worksheet.Columns().AdjustToContents();
|
|
|
|
var stream = new MemoryStream();
|
|
workbook.SaveAs(stream);
|
|
stream.Position = 0;
|
|
return stream;
|
|
}
|
|
|
|
private TimeSpan CalculateTotalOT(OtRegisterModel r)
|
|
{
|
|
TimeSpan office = (r.OfficeTo ?? TimeSpan.Zero) - (r.OfficeFrom ?? TimeSpan.Zero);
|
|
TimeSpan after = (r.AfterTo ?? TimeSpan.Zero) - (r.AfterFrom ?? TimeSpan.Zero);
|
|
if (after < TimeSpan.Zero)
|
|
after += TimeSpan.FromHours(24);
|
|
return office + after;
|
|
}
|
|
|
|
private string FormatTime(TimeSpan? time)
|
|
{
|
|
return time == null || time == TimeSpan.Zero ? "" : time.Value.ToString(@"hh\:mm");
|
|
}
|
|
}
|
|
} |