468 lines
22 KiB
C#
468 lines
22 KiB
C#
using _0_Framework.Excel;
|
|
using _0_Framework.Application;
|
|
using CompanyManagment.App.Contracts.RollCall;
|
|
using OfficeOpenXml;
|
|
using OfficeOpenXml.Drawing;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace CompanyManagement.Infrastructure.Excel.RollCall;
|
|
|
|
public class RollCallExcelGenerator : ExcelGenerator
|
|
{
|
|
public static byte[] CaseHistoryExcelForEmployee(CaseHistoryRollCallExcelForEmployeeViewModel data)
|
|
{
|
|
OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
|
|
using var package = new OfficeOpenXml.ExcelPackage();
|
|
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
|
|
var rollCalls = data.RollCalls;
|
|
var row = 6;
|
|
|
|
worksheet.Cells.Style.Locked = false;
|
|
|
|
|
|
// Merge cells from row 1 to 4, covering columns A to G
|
|
worksheet.Cells["A1:H4"].Merge = true;
|
|
|
|
// Add the image to the merged cell
|
|
var headerImagePath = Path.Combine("wwwroot", "Excel", "header", "21.png");
|
|
using (var stream = new FileStream(headerImagePath, FileMode.Open, FileAccess.Read))
|
|
{
|
|
var picture = worksheet.Drawings.AddPicture("HeaderImage", stream);
|
|
picture.SetPosition(0, 0, 0, 0); // Set position to the merged
|
|
picture.ChangeCellAnchor(eEditAs.TwoCell);
|
|
picture.EditAs = eEditAs.Absolute;
|
|
}
|
|
|
|
// Add border to the merged cell
|
|
var mergedCell = worksheet.Cells["A1:H4"];
|
|
mergedCell.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
mergedCell.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
mergedCell.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
mergedCell.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
|
|
// Add merged cells below the image
|
|
worksheet.Cells["A5:C5"].Merge = true; // ماه
|
|
worksheet.Cells["D5:F5"].Merge = true; // نام کارمند
|
|
worksheet.Cells["G5:H5"].Merge = true; // شماره پرسنلی
|
|
|
|
// Add data from ViewModel
|
|
worksheet.Cells["A5"].Value = $"{data.PersianMonthName} {data.PersianYear}"; // ماه و سال
|
|
worksheet.Cells["D5"].Value = data.EmployeeFullName; // نام کارمند
|
|
worksheet.Cells["G5"].Value = $"شماره پرسنلی: {data.PersonnelCode}"; // شماره پرسنلی
|
|
|
|
// Style merged cells
|
|
for (int i = 5; i <= 5; i++)
|
|
{
|
|
worksheet.Cells[$"A{i}:B{i}"].Style.Font.Bold = true;
|
|
worksheet.Cells[$"A{i}:B{i}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
worksheet.Cells[$"A{i}:B{i}"].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
|
|
worksheet.Cells[$"A{i}:B{i}"].Style.Font.Size = 14; // Larger font size
|
|
|
|
worksheet.Cells[$"C{i}:E{i}"].Style.Font.Bold = true;
|
|
worksheet.Cells[$"C{i}:E{i}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
worksheet.Cells[$"C{i}:E{i}"].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
|
|
worksheet.Cells[$"C{i}:E{i}"].Style.Font.Size = 14; // Larger font size
|
|
|
|
worksheet.Cells[$"F{i}:G{i}"].Style.Font.Bold = true;
|
|
worksheet.Cells[$"F{i}:G{i}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
worksheet.Cells[$"F{i}:G{i}"].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
|
|
worksheet.Cells[$"F{i}:G{i}"].Style.Font.Size = 14; // Larger font size
|
|
}
|
|
|
|
//add border to headers
|
|
worksheet.Cells["A5"].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells["H5"].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
|
|
worksheet.Cells["A6"].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells["H6"].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
|
|
worksheet.Cells["B6:C6"].Merge = true;
|
|
|
|
// Lock cells A1 to H6
|
|
worksheet.Cells["A1:H6"].Style.Locked = true;
|
|
// Set worksheet protection with password
|
|
|
|
worksheet.Protection.IsProtected = true;
|
|
worksheet.Protection.SetPassword("Gozareshgir2049"); // Set your desired password here
|
|
|
|
worksheet.Protection.AllowSelectLockedCells = true; // Unlock all other cells
|
|
|
|
// Add headers
|
|
worksheet.Cells["A6"].Value = "ردیف";
|
|
worksheet.Cells["B6"].Value = "تاریخ";
|
|
worksheet.Cells["D6"].Value = "تاخیر در ورود";
|
|
worksheet.Cells["E6"].Value = "ورود";
|
|
worksheet.Cells["F6"].Value = "خروج";
|
|
worksheet.Cells["G6"].Value = "تعجیل در خروج";
|
|
worksheet.Cells["H6"].Value = "مجموع ساعات کاری";
|
|
|
|
// Style headers
|
|
using (var range = worksheet.Cells[row, 1, row, 8])
|
|
{
|
|
range.Style.Font.Bold = true;
|
|
range.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
range.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
|
|
range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
range.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
range.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
range.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
range.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
}
|
|
|
|
// Add data
|
|
for (int i = 0; i < rollCalls.Count; i++)
|
|
{
|
|
var rollCall = rollCalls[i];
|
|
worksheet.Cells[i + row + 1, 1].Value = i + 1;
|
|
worksheet.Cells[i + row + 1, 2].Value = rollCall.DayOfWeekFa;
|
|
worksheet.Cells[i + row + 1, 3].Value = rollCall.DateFa;
|
|
worksheet.Cells[i + row + 1, 4].Value = rollCall.EnterTimeDifferences;
|
|
worksheet.Cells[i + row + 1, 5].Value = rollCall.StartsItems;
|
|
worksheet.Cells[i + row + 1, 6].Value = rollCall.EndsItems;
|
|
worksheet.Cells[i + row + 1, 7].Value = rollCall.ExitTimeDifferences;
|
|
worksheet.Cells[i + row + 1, 8].Value = rollCall.TotalWorkingHours == string.Empty
|
|
? "ندارد" : rollCall.TotalWorkingHours;
|
|
|
|
// Style data cells
|
|
for (int j = 1; j <= 8; j++)
|
|
{
|
|
var cell = worksheet.Cells[i + row + 1, j];
|
|
cell.Style.Border.BorderAround(OfficeOpenXml.Style.ExcelBorderStyle.Thin);
|
|
cell.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
cell.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
|
|
|
|
if (j == 5 || j == 6)
|
|
{
|
|
cell.Style.WrapText = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Merge the last row
|
|
int lastRow = rollCalls.Count + row +1;
|
|
worksheet.Cells[$"A{lastRow}:G{lastRow}"].Merge = true;
|
|
worksheet.Cells[$"A{lastRow}"].Value = $"مجموع کل ساعات کاری : {data.TotalWorkingHoursFa}"; // Replace with your actual data
|
|
worksheet.Cells[$"A{lastRow}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Left; // Align left
|
|
worksheet.Cells[$"A{lastRow}"].Style.Font.Bold = true;
|
|
|
|
|
|
|
|
// Add border to the merged last row
|
|
worksheet.Cells[$"A{lastRow}:G{lastRow}"].Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"A{lastRow}:G{lastRow}"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"A{lastRow}:G{lastRow}"].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"A{lastRow}:G{lastRow}"].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
|
|
|
|
worksheet.Cells[$"H{lastRow}"].Value = data.TotalWorkingTimeSpan;
|
|
worksheet.Cells[$"H{lastRow}"].Style.Font.Bold = true;
|
|
|
|
worksheet.Cells[$"H{lastRow}"].Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"H{lastRow}"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"H{lastRow}"].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"H{lastRow}"].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells[$"H{lastRow}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
|
|
|
|
|
|
// Adjust column widths
|
|
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
|
|
|
|
// Set the sheet to A4 size
|
|
worksheet.PrinterSettings.PaperSize = ePaperSize.A4;
|
|
worksheet.PrinterSettings.Orientation = eOrientation.Portrait; // or Landscape
|
|
worksheet.PrinterSettings.FitToWidth = 1;
|
|
worksheet.PrinterSettings.FitToHeight = 0;
|
|
worksheet.View.RightToLeft = true;
|
|
|
|
// Repeat headers on every page
|
|
worksheet.PrinterSettings.RepeatRows = new OfficeOpenXml.ExcelAddress("1:6"); // Repeat rows 1 to 6 on every page
|
|
|
|
return package.GetAsByteArray();
|
|
}
|
|
|
|
|
|
public static byte[] CaseHistoryExcelForOneDay(CaseHistoryRollCallForOneDayViewModel data)
|
|
{
|
|
OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
|
|
using var package = new OfficeOpenXml.ExcelPackage();
|
|
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
|
|
var rollCalls = data.RollCalls;
|
|
var row = 6;
|
|
|
|
worksheet.Cells.Style.Locked = false;
|
|
|
|
|
|
// Merge cells from row 1 to 4, covering columns A to H
|
|
worksheet.Cells["A1:H4"].Merge = true;
|
|
|
|
|
|
// Add the image to the merged cell
|
|
var headerImagePath = Path.Combine("wwwroot", "Excel", "header", "21.OneDay.png");
|
|
using (var stream = new FileStream(headerImagePath, FileMode.Open, FileAccess.Read))
|
|
{
|
|
var picture = worksheet.Drawings.AddPicture("HeaderImage", stream);
|
|
picture.SetPosition(0, 0, 0, 0); // Set position to the merged cell
|
|
//picture.SetSize(600, 75); // Adjust the size as needed
|
|
}
|
|
|
|
// Add border to the merged cell
|
|
var mergedCell = worksheet.Cells["A1:H4"];
|
|
mergedCell.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
mergedCell.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
mergedCell.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
mergedCell.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
|
|
// Add merged cells below the image
|
|
worksheet.Cells["A5:H5"].Merge = true;
|
|
|
|
// Add data from ViewModel
|
|
worksheet.Cells["A5"].Value = $"پرینت حضور و غیاب کل پرسنل به تاریخ {data.DateFa}"; // تاریخ
|
|
|
|
// Style merged cells
|
|
var mergedHeaderCell = worksheet.Cells["A5:H5"];
|
|
mergedHeaderCell.Style.Font.Bold = true;
|
|
mergedHeaderCell.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
mergedHeaderCell.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
|
|
mergedHeaderCell.Style.Font.Size = 14; // Larger font size
|
|
|
|
// Add border to header cell
|
|
worksheet.Cells["A5"].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
worksheet.Cells["H5"].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
|
|
// Add headers
|
|
worksheet.Cells[row, 1].Value = "ردیف";
|
|
worksheet.Cells[row, 2].Value = "نام و نام خانوادگی";
|
|
worksheet.Cells[row, 3].Value = "شماره پرسنلی";
|
|
worksheet.Cells[row, 4].Value = "تاخیر در ورود";
|
|
worksheet.Cells[row, 5].Value = "ورود";
|
|
worksheet.Cells[row, 6].Value = "خروج";
|
|
worksheet.Cells[row, 7].Value = "تعجیل در خروج";
|
|
worksheet.Cells[row, 8].Value = "مجموع ساعات کاری";
|
|
|
|
// Style headers with left and right borders
|
|
worksheet.Cells[row, 1].Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; // Right border for first column
|
|
worksheet.Cells[row, 8].Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin; // Left border for last column
|
|
|
|
// Style headers
|
|
using (var range = worksheet.Cells[row, 1, row, 8])
|
|
{
|
|
range.Style.Font.Bold = true;
|
|
range.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
range.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
|
|
range.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
range.Style.Border.Right.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
range.Style.Border.Left.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
range.Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
range.Style.Border.Top.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thin;
|
|
}
|
|
|
|
// Lock cells A1 to H6
|
|
worksheet.Cells["A1:H6"].Style.Locked = true;
|
|
// Set worksheet protection with password
|
|
|
|
worksheet.Protection.IsProtected = true;
|
|
worksheet.Protection.SetPassword("Gozareshgir2049");
|
|
|
|
// Add data
|
|
for (int i = 0; i < rollCalls.Count; i++)
|
|
{
|
|
var rollCall = rollCalls[i];
|
|
worksheet.Cells[i + row + 1, 1].Value = i + 1;
|
|
worksheet.Cells[i + row + 1, 2].Value = rollCall.EmployeeFullName;
|
|
worksheet.Cells[i + row + 1, 3].Value = rollCall.PersonnelCode;
|
|
worksheet.Cells[i + row + 1, 4].Value = "-";
|
|
worksheet.Cells[i + row + 1, 5].Value = rollCall.StartsItems;
|
|
worksheet.Cells[i + row + 1, 6].Value = rollCall.EndsItems;
|
|
worksheet.Cells[i + row + 1, 7].Value = "-";
|
|
worksheet.Cells[i + row + 1, 8].Value = rollCall.TotalWorkingHours;
|
|
|
|
// Style data cells
|
|
for (int j = 1; j <= 8; j++)
|
|
{
|
|
var cell = worksheet.Cells[i + row + 1, j];
|
|
cell.Style.Border.BorderAround(OfficeOpenXml.Style.ExcelBorderStyle.Thin);
|
|
cell.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
|
|
cell.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
|
|
|
|
if (j == 5 || j == 6)
|
|
{
|
|
cell.Style.WrapText = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Adjust column widths
|
|
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
|
|
|
|
// Set the sheet to A4 size
|
|
worksheet.PrinterSettings.PaperSize = ePaperSize.A4;
|
|
worksheet.PrinterSettings.Orientation = eOrientation.Portrait;
|
|
worksheet.PrinterSettings.FitToPage = true;
|
|
worksheet.PrinterSettings.FitToWidth = 1;
|
|
worksheet.PrinterSettings.FitToHeight = 0;
|
|
worksheet.PrinterSettings.Scale = 85; // Scale to fit content within A4 width
|
|
worksheet.View.RightToLeft = true;
|
|
|
|
// Repeat headers on every page
|
|
worksheet.PrinterSettings.RepeatRows = new OfficeOpenXml.ExcelAddress("1:6"); // Repeat rows 1 to 6 on every page
|
|
|
|
return package.GetAsByteArray();
|
|
}
|
|
|
|
public static byte[] CaseHistoryExcelForEmployee(List<RollCallCaseHistoryDetail> data, string titleId)
|
|
{
|
|
if (!Regex.IsMatch(titleId, @"^\d{4}_\d{2}$"))
|
|
throw new ArgumentException("Invalid titleId format.", nameof(titleId));
|
|
|
|
var splitDate = titleId.Split("_");
|
|
var year = Convert.ToInt32(splitDate.First());
|
|
var month = Convert.ToInt32(splitDate.Last());
|
|
|
|
var startDateFa = $"{year:D4}/{month:D2}/01";
|
|
var startDate = startDateFa.ToGeorgianDateTime();
|
|
var endDateFa = startDateFa.FindeEndOfMonth();
|
|
var endDate = endDateFa.ToGeorgianDateTime();
|
|
|
|
var dateRange = (int)(endDate.Date - startDate.Date).TotalDays + 1;
|
|
var dates = Enumerable.Range(0, dateRange).Select(x => startDate.AddDays(x)).ToList();
|
|
|
|
var safeData = data ?? new List<RollCallCaseHistoryDetail>();
|
|
var first = safeData.FirstOrDefault();
|
|
var totalWorkingTime = new TimeSpan(safeData.Sum(x => x.TotalWorkingTime.Ticks));
|
|
|
|
var viewModel = new CaseHistoryRollCallExcelForEmployeeViewModel
|
|
{
|
|
EmployeeId = first?.EmployeeId ?? 0,
|
|
DateGr = startDate,
|
|
PersonnelCode = first?.PersonnelCode,
|
|
EmployeeFullName = first?.EmployeeFullName,
|
|
PersianMonthName = month.ToFarsiMonthByIntNumber(),
|
|
PersianYear = year.ToString(),
|
|
TotalWorkingHoursFa = totalWorkingTime.ToFarsiHoursAndMinutes("-"),
|
|
TotalWorkingTimeSpan = $"{(int)totalWorkingTime.TotalHours}:{totalWorkingTime.Minutes:00}",
|
|
RollCalls = dates.Select((date, index) =>
|
|
{
|
|
var item = index < safeData.Count ? safeData[index] : null;
|
|
var records = item?.Records ?? new List<RollCallCaseHistoryDetailRecord>();
|
|
|
|
return new RollCallItemForEmployeeExcelViewModel
|
|
{
|
|
DateGr = date,
|
|
DateFa = date.ToFarsi(),
|
|
DayOfWeekFa = date.DayOfWeek.DayOfWeeKToPersian(),
|
|
PersonnelCode = item?.PersonnelCode,
|
|
EmployeeFullName = item?.EmployeeFullName,
|
|
IsAbsent = item?.Status == RollCallRecordStatus.Absent,
|
|
HasLeave = item?.Status == RollCallRecordStatus.Leaved,
|
|
IsHoliday = false,
|
|
TotalWorkingHours = (item?.TotalWorkingTime ?? TimeSpan.Zero).ToFarsiHoursAndMinutes("-"),
|
|
StartsItems = JoinRecords(records, r => r.StartTime),
|
|
EndsItems = JoinRecords(records, r => r.EndTime),
|
|
EnterTimeDifferences = JoinRecords(records, r => FormatSignedTimeSpan(r.EntryTimeDifference)),
|
|
ExitTimeDifferences = JoinRecords(records, r => FormatSignedTimeSpan(r.ExitTimeDifference))
|
|
};
|
|
}).ToList()
|
|
};
|
|
|
|
return CaseHistoryExcelForEmployee(viewModel);
|
|
}
|
|
|
|
public static byte[] CaseHistoryExcelForOneDay(List<RollCallCaseHistoryDetail> data, string titleId)
|
|
{
|
|
if (!Regex.IsMatch(titleId, @"^\d{4}/\d{2}/\d{2}$"))
|
|
throw new ArgumentException("Invalid titleId format.", nameof(titleId));
|
|
|
|
var dateGr = titleId.ToGeorgianDateTime();
|
|
var safeData = data ?? new List<RollCallCaseHistoryDetail>();
|
|
|
|
var viewModel = new CaseHistoryRollCallForOneDayViewModel
|
|
{
|
|
DateFa = titleId,
|
|
DateGr = dateGr,
|
|
DayOfWeekFa = dateGr.DayOfWeek.DayOfWeeKToPersian(),
|
|
RollCalls = safeData.Select(item =>
|
|
{
|
|
var records = item.Records ?? new List<RollCallCaseHistoryDetailRecord>();
|
|
return new RollCallItemForOneDayExcelViewModel
|
|
{
|
|
EmployeeFullName = item.EmployeeFullName,
|
|
PersonnelCode = item.PersonnelCode,
|
|
StartsItems = JoinRecords(records, r => r.StartTime),
|
|
EndsItems = JoinRecords(records, r => r.EndTime),
|
|
TotalWorkingHours = item.TotalWorkingTime.ToFarsiHoursAndMinutes("-")
|
|
};
|
|
}).ToList()
|
|
};
|
|
|
|
return CaseHistoryExcelForOneDay(viewModel);
|
|
}
|
|
|
|
private static string JoinRecords(IEnumerable<RollCallCaseHistoryDetailRecord> records, Func<RollCallCaseHistoryDetailRecord, string> selector)
|
|
{
|
|
var safeRecords = records ?? Enumerable.Empty<RollCallCaseHistoryDetailRecord>();
|
|
var values = safeRecords.Select(selector).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
|
|
return values.Count == 0 ? string.Empty : string.Join(Environment.NewLine, values);
|
|
}
|
|
|
|
private static string FormatSignedTimeSpan(TimeSpan value)
|
|
{
|
|
if (value == TimeSpan.Zero)
|
|
return "-";
|
|
|
|
var abs = value.Duration();
|
|
var sign = value.Ticks < 0 ? "-" : "+";
|
|
return $"{(int)abs.TotalHours}:{abs.Minutes:00}{sign}";
|
|
}
|
|
|
|
private string CalculateExitMinuteDifference(TimeSpan early, TimeSpan late)
|
|
{
|
|
if (early == TimeSpan.Zero && late == TimeSpan.Zero)
|
|
{
|
|
return "-";
|
|
}
|
|
else if (late != TimeSpan.Zero)
|
|
{
|
|
var minutes = late.TotalMinutes > 999 ? "999" : late.TotalMinutes.ToString();
|
|
return $"{minutes}+";
|
|
}
|
|
else if (early != TimeSpan.Zero)
|
|
{
|
|
var minutes = early.TotalMinutes > 999 ? "999" : early.TotalMinutes.ToString();
|
|
return $"{minutes}-";
|
|
}
|
|
else
|
|
{
|
|
return $"";
|
|
}
|
|
}
|
|
|
|
private string CalculateEntryMinuteDifference(TimeSpan early, TimeSpan late)
|
|
{
|
|
if (early == TimeSpan.Zero && late == TimeSpan.Zero)
|
|
{
|
|
return "-";
|
|
}
|
|
else if (late != TimeSpan.Zero)
|
|
{
|
|
var minutes = late.TotalMinutes > 999 ? "999" : late.TotalMinutes.ToString();
|
|
return $"{minutes}-";
|
|
}
|
|
else if (early != TimeSpan.Zero)
|
|
{
|
|
var minutes = early.TotalMinutes > 999 ? "999" : early.TotalMinutes.ToString();
|
|
return $"{minutes}+";
|
|
}
|
|
else
|
|
{
|
|
return $"";
|
|
}
|
|
}
|
|
|
|
|
|
}
|