From cf241d3e9a7fb52c2b8756de023f07f0d58b6792 Mon Sep 17 00:00:00 2001 From: mahan Date: Sat, 27 Dec 2025 15:41:19 +0330 Subject: [PATCH] add: implement AsghaeeAzarWorkshopsExcelGenerator and view model for generating Excel reports --- .../AsghaeeAzarWorkshopsExcelGenerator.cs | 154 ++++++++++++++++++ .../AsghaeeAzarWorkshopsExcelViewModel.cs | 8 + .../Pages/Company/AndroidApk/Index.cshtml.cs | 28 +++- 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelGenerator.cs create mode 100644 CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelViewModel.cs diff --git a/CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelGenerator.cs b/CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelGenerator.cs new file mode 100644 index 00000000..8014ebe1 --- /dev/null +++ b/CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelGenerator.cs @@ -0,0 +1,154 @@ +using System.Drawing; +using _0_Framework.Application; +using OfficeOpenXml; +using OfficeOpenXml.Style; + +namespace CompanyManagement.Infrastructure.Excel.Checkout.AsghaeeAzarWorkshops; + +public class AsghaeeAzarWorkshopsExcelGenerator +{ + public static Dictionary Header { get; set; } = new() + { + { "FullName", "نام و نام خانوادگی" }, + { "NationalCode", "کد ملی" }, + { "FinalAmount", "مبلغ نهایی" } + }; + + public static byte[] Generate(List data) + { + ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization"); + using var package = new ExcelPackage(); + var worksheet = package.Workbook.Worksheets.Add("Sheet1"); + + // Add index column header + var indexCell = worksheet.Cells[1, 1]; + indexCell.Value = "ردیف"; + ApplyHeaderStyle(indexCell); + + // Add headers to worksheet + for (int i = 0; i < Header.Count; i++) + { + worksheet.Cells[1, i + 2].Value = Header.ElementAt(i).Value; + ApplyHeaderStyle(worksheet.Cells[1, i + 2]); + } + + var dataRow = 2; + int finalAmountColumnIndex = -1; + + foreach (var item in data) + { + var column = 2; + foreach (var header in Header) + { + var property = item.GetType().GetProperty(header.Key); + var value = property?.GetValue(item, null)?.ToString(); + + // Check if the property requires MoneyToDouble() + if (header.Key == "FinalAmount") + { + worksheet.Cells[dataRow, column].Value = MoneyToDouble(value ?? "0"); + finalAmountColumnIndex = column; + } + else + { + worksheet.Cells[dataRow, column].Value = value; + } + + ApplyGeneralDataStyle(worksheet.Cells[dataRow, column]); + ApplySpecificStyle(worksheet.Cells[dataRow, column], header.Key); + + column++; + } + + // Add row number + var rowCounter = worksheet.Cells[dataRow, 1]; + rowCounter.Value = dataRow - 1; + ApplyGeneralDataStyle(rowCounter); + ApplySpecificStyle(rowCounter, "RowNumber"); + + dataRow++; + } + + worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns(); + 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; + worksheet.View.RightToLeft = true; + + if (finalAmountColumnIndex != -1) + { + ApplyConditionalFormatting(worksheet, dataRow, finalAmountColumnIndex); + } + + return package.GetAsByteArray(); + } + + private static double MoneyToDouble(string value) + { + if (string.IsNullOrEmpty(value)) + return 0; + + var min = value.Length > 1 ? value.Substring(0, 2) : ""; + var result = min == "\u200e\u2212" ? value.MoneyToDouble() * -1 : value.MoneyToDouble(); + return result; + } + + private static void ApplyHeaderStyle(ExcelRange cell) + { + cell.Style.Font.Bold = true; + cell.Style.Fill.PatternType = ExcelFillStyle.Solid; + cell.Style.Fill.BackgroundColor.SetColor(Color.LightGray); + cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; + cell.Style.VerticalAlignment = ExcelVerticalAlignment.Center; + cell.Style.Border.BorderAround(ExcelBorderStyle.Thin); + } + + private static void ApplyGeneralDataStyle(ExcelRange cell) + { + cell.Style.Border.BorderAround(ExcelBorderStyle.Thin); + cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; + cell.Style.VerticalAlignment = ExcelVerticalAlignment.Center; + cell.Style.Fill.PatternType = ExcelFillStyle.Solid; + } + + private static void ApplySpecificStyle(ExcelRange cell, string columnKey) + { + switch (columnKey) + { + case "RowNumber": + case "FullName": + case "NationalCode": + cell.Style.Fill.BackgroundColor.SetColor(Color.LightYellow); + break; + case "FinalAmount": + cell.Style.Fill.BackgroundColor.SetColor(ColorTranslator.FromHtml("#A8BAFE")); // Light blue + cell.Style.Numberformat.Format = "#,##0"; + break; + } + } + + private static void ApplyConditionalFormatting(ExcelWorksheet worksheet, int dataRow, int finalAmountColumnIndex) + { + for (int rowIndex = 2; rowIndex < dataRow; rowIndex++) + { + var finalAmountValue = worksheet.Cells[rowIndex, finalAmountColumnIndex].Value; + if (finalAmountValue != null && double.TryParse(finalAmountValue.ToString(), out double amount)) + { + if (amount < 0) + { + var rowRange = worksheet.Cells[rowIndex, 1, rowIndex, worksheet.Dimension.End.Column]; + rowRange.Style.Fill.PatternType = ExcelFillStyle.Solid; + rowRange.Style.Fill.BackgroundColor.SetColor(Color.Red); + foreach (var cell in rowRange) + { + cell.Style.Font.Color.SetColor(Color.White); + } + } + } + } + } +} + diff --git a/CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelViewModel.cs b/CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelViewModel.cs new file mode 100644 index 00000000..3e7ad20d --- /dev/null +++ b/CompanyManagement.Infrastructure.Excel/Checkout/AsghaeeAzarWorkshops/AsghaeeAzarWorkshopsExcelViewModel.cs @@ -0,0 +1,8 @@ +namespace CompanyManagement.Infrastructure.Excel.Checkout.AsghaeeAzarWorkshops; + +public class AsghaeeAzarWorkshopsExcelViewModel +{ + public string FullName { get; set; } + public string NationalCode { get; set; } + public string FinalAmount { get; set; } +} diff --git a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs index 042099da..6436331e 100644 --- a/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs +++ b/ServiceHost/Areas/AdminNew/Pages/Company/AndroidApk/Index.cshtml.cs @@ -14,6 +14,7 @@ using Company.Domain.PaymentTransactionAgg; using Company.Domain.RewardAgg; using Company.Domain.RollCallAgg.DomainService; using CompanyManagement.Infrastructure.Excel.WorkshopsRollCall; +using CompanyManagement.Infrastructure.Excel.Checkout.AsghaeeAzarWorkshops; using CompanyManagment.App.Contracts.AndroidApkVersion; using CompanyManagment.App.Contracts.InstitutionContract; using CompanyManagment.App.Contracts.PaymentTransaction; @@ -152,7 +153,10 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk { //await UpdateInstitutionContract(); //await UpdateFaceEmbeddingNames(); - await SetInstitutionContractSigningType(); + //await SetInstitutionContractSigningType(); + var data = OnGetExportAsghaeeAzarWorkshops(); + return File(data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "AsghaeeAzarWorkshops.xlsx"); ViewData["message"] = "تومام یک"; return Page(); } @@ -1111,6 +1115,28 @@ namespace ServiceHost.Areas.AdminNew.Pages.Company.AndroidApk } #endregion + + #region Excel + + /// + /// خروجی اکسل آقایی آذر ورکشاپ + /// + /// + private byte[] OnGetExportAsghaeeAzarWorkshops() + { + var data = _context.CheckoutSet + .Where(x => x.WorkshopId == 768 && x.Month =="آذر" && x.Year =="1404") + .Select(x => new AsghaeeAzarWorkshopsExcelViewModel() + { + FinalAmount = x.TotalPayment.ToMoney(), + FullName = x.EmployeeFullName, + NationalCode = x.NationalCode + }).ToList(); + + return AsghaeeAzarWorkshopsExcelGenerator.Generate(data); + } + + #endregion } public class IndexModel2 : PageModel