diff --git a/CompanyManagement.Infrastructure.Excel/InstitutionContract/InstitutionContractExcelGenerator.cs b/CompanyManagement.Infrastructure.Excel/InstitutionContract/InstitutionContractExcelGenerator.cs index e17f21df..24f5ce8a 100644 --- a/CompanyManagement.Infrastructure.Excel/InstitutionContract/InstitutionContractExcelGenerator.cs +++ b/CompanyManagement.Infrastructure.Excel/InstitutionContract/InstitutionContractExcelGenerator.cs @@ -8,86 +8,130 @@ using System.Text.RegularExpressions; namespace CompanyManagement.Infrastructure.Excel.InstitutionContract; +// Enum برای تعریف ستون‌های موجود +public enum ExcelColumnType +{ + RowNumber, // ردیف + PhysicalContract, // قرارداد فیزیکی + ContractNo, // شماره قرارداد + Representative, // معرف + ContractingPartyName, // طرف حساب + ArchiveCode, // شماره کارفرما + EmployerName, // کارفرما + WorkshopName, // کارگاه‌ها (چندخطی) + WorkshopCount, // تعداد کارگاه + EmployeeCount, // مجموع پرسنل + ContractStartDate, // شروع قرارداد + ContractEndDate, // پایان قرارداد + InstallmentAmount, // مبلغ قسط + ContractAmount, // مبلغ قرارداد + FinancialStatus // وضعیت مالی +} + +// کلاس کانفیگ برای تنظیم ستون‌های نمایشی +public class ExcelColumnConfig +{ + public List VisibleColumns { get; set; } + + public ExcelColumnConfig() + { + // فعلاً تمام ستون‌ها فعال هستند + VisibleColumns = new List + { + ExcelColumnType.RowNumber, + ExcelColumnType.PhysicalContract, + ExcelColumnType.ContractNo, + ExcelColumnType.Representative, + ExcelColumnType.ContractingPartyName, + ExcelColumnType.ArchiveCode, + ExcelColumnType.EmployerName, + ExcelColumnType.WorkshopName, + ExcelColumnType.WorkshopCount, + ExcelColumnType.EmployeeCount, + ExcelColumnType.ContractStartDate, + ExcelColumnType.ContractEndDate, + ExcelColumnType.InstallmentAmount, + ExcelColumnType.ContractAmount, + ExcelColumnType.FinancialStatus + }; + } +} + public class InstitutionContractExcelGenerator { + private static ExcelColumnConfig _columnConfig = new ExcelColumnConfig(); - public static byte[] GenerateExcel(List institutionContractViewModels) + public static byte[] GenerateExcel(List contractViewModels) { ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization"); using var package = new ExcelPackage(); - var allWorksheet = package.Workbook.Worksheets.Add("همه"); - - var blueWorksheet = package.Workbook.Worksheets.Add("آبی"); - blueWorksheet.TabColor = Color.LightBlue; - - var grayWorksheet = package.Workbook.Worksheets.Add("خاکستری"); - grayWorksheet.TabColor = Color.LightGray; - - var redWorksheet = package.Workbook.Worksheets.Add("قرمز"); - redWorksheet.TabColor = Color.LightCoral; - - var purpleWorksheet = package.Workbook.Worksheets.Add("بنفش"); - purpleWorksheet.TabColor = Color.MediumPurple; - - var blackWorksheet = package.Workbook.Worksheets.Add("مشکی"); - blackWorksheet.TabColor = Color.DimGray; - - var yellowWorksheet = package.Workbook.Worksheets.Add("زرد"); - yellowWorksheet.TabColor = Color.Yellow; - - var whiteWorksheet = package.Workbook.Worksheets.Add("سفید"); - whiteWorksheet.TabColor = Color.White; - - - CreateExcelSheet(institutionContractViewModels, allWorksheet); - - var blueContracts = institutionContractViewModels.Where(x=>x.ExpireColor == "blue").ToList(); - CreateExcelSheet(blueContracts, blueWorksheet); - institutionContractViewModels = institutionContractViewModels.Except(blueContracts).ToList(); - - var grayContracts = institutionContractViewModels.Where(x => x.IsContractingPartyBlock == "true").ToList(); - CreateExcelSheet(grayContracts, grayWorksheet); - institutionContractViewModels = institutionContractViewModels.Except(grayContracts).ToList(); - - var redContracts = institutionContractViewModels.Where(x=>x.ExpireColor == "red").ToList(); - CreateExcelSheet(redContracts, redWorksheet); - institutionContractViewModels = institutionContractViewModels.Except(redContracts).ToList(); - - var purpleContracts = institutionContractViewModels.Where(x=>x.ExpireColor == "purple").ToList(); - CreateExcelSheet(purpleContracts, purpleWorksheet); - institutionContractViewModels = institutionContractViewModels.Except(purpleContracts).ToList(); - var blackContracts = institutionContractViewModels.Where(x=>x.ExpireColor == "black").ToList(); - CreateExcelSheet(blackContracts, blackWorksheet); - institutionContractViewModels = institutionContractViewModels.Except(blackContracts).ToList(); - - var yellowContracts = institutionContractViewModels - .Where(x => string.IsNullOrWhiteSpace(x.ExpireColor) && x.WorkshopCount == "0").ToList(); - CreateExcelSheet(yellowContracts, yellowWorksheet); - institutionContractViewModels = institutionContractViewModels.Except(yellowContracts).ToList(); - - var otherContracts = institutionContractViewModels; - CreateExcelSheet(otherContracts, whiteWorksheet); + // ایجاد شیت برای هر تب با داده‌های مربوطه + foreach (var viewModel in contractViewModels) + { + var worksheet = CreateWorksheet(package, viewModel.Tab); + CreateExcelSheet(viewModel.GetInstitutionContractListItemsViewModels ?? new List(), worksheet); + } return package.GetAsByteArray(); } - private static void CreateExcelSheet(List institutionContractViewModels, ExcelWorksheet worksheet) + /// + /// ایجاد شیت بر اساس نوع تب + /// + private static ExcelWorksheet CreateWorksheet(ExcelPackage package, InstitutionContractListStatus? status) { - // Headers - worksheet.Cells[1, 1].Value = "شماره قرارداد"; - worksheet.Cells[1, 2].Value = "طرف حساب"; - worksheet.Cells[1, 3].Value = "شماره کارفرما"; - worksheet.Cells[1, 4].Value = "کارفرما ها"; - worksheet.Cells[1, 5].Value = "کارگاه ها"; - worksheet.Cells[1, 6].Value = "مجبوع پرسنل"; - worksheet.Cells[1, 7].Value = "شروع قرارداد"; - worksheet.Cells[1, 8].Value = "پایان قرارداد"; - worksheet.Cells[1, 9].Value = "مبلغ قرارداد (بدون کارگاه)"; - worksheet.Cells[1, 10].Value = "مبلغ قرارداد"; - worksheet.Cells[1, 11].Value = "وضعیت مالی"; + return status switch + { + InstitutionContractListStatus.DeactiveWithDebt => + CreateColoredWorksheet(package, "غیرفعال دارای بدهی", Color.LightBlue), + + InstitutionContractListStatus.Deactive => + CreateColoredWorksheet(package, "غیرفعال", Color.LightGray), + + InstitutionContractListStatus.PendingForRenewal => + CreateColoredWorksheet(package, "در انتظار تمدید", Color.LightCoral), + + InstitutionContractListStatus.Free => + CreateColoredWorksheet(package, "بنفش", Color.MediumPurple), + + InstitutionContractListStatus.Block => + CreateColoredWorksheet(package, "بلاک", Color.DimGray), + + InstitutionContractListStatus.WithoutWorkshop => + CreateColoredWorksheet(package, "بدون کارگاه", Color.Yellow), + + InstitutionContractListStatus.Active => + CreateColoredWorksheet(package, "فعال", Color.White), + + InstitutionContractListStatus.PendingForVerify => + CreateColoredWorksheet(package, "در انتظار تایید", Color.OrangeRed), + + null => CreateColoredWorksheet(package, "کل قرارداد ها", Color.White), + _ => throw new ArgumentOutOfRangeException(nameof(status), status, null) + }; + } - using (var range = worksheet.Cells[1, 1, 1, 11]) + /// + /// ایجاد شیت با رنگ تب + /// + private static ExcelWorksheet CreateColoredWorksheet(ExcelPackage package, string sheetName, Color tabColor) + { + var worksheet = package.Workbook.Worksheets.Add(sheetName); + worksheet.TabColor = tabColor; + return worksheet; + } + + private static void CreateExcelSheet(List contractItems, ExcelWorksheet worksheet) + { + // دریافت نقشه ستون‌های مرئی + var visibleColumnIndices = GetVisibleColumnIndices(); + int columnCount = visibleColumnIndices.Count; + + // تنظیم Headers + SetupHeaders(worksheet, visibleColumnIndices, columnCount); + + using (var range = worksheet.Cells[1, 1, 1, columnCount]) { range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; range.Style.VerticalAlignment = ExcelVerticalAlignment.Center; @@ -110,30 +154,35 @@ public class InstitutionContractExcelGenerator int row = 2; - for (int i = 0; i < institutionContractViewModels.Count; i++) + for (int i = 0; i < contractItems.Count; i++) { - var contract = institutionContractViewModels[i]; - var employers = contract.EmployerViewModels?.ToList() ?? new(); - var workshops = contract.WorkshopViewModels?.ToList() ?? new(); + var contract = contractItems[i]; + var employers = contract.EmployerNames?.ToList() ?? new(); + var workshops = contract.WorkshopNames?.ToList() ?? new(); - int maxRows = Math.Max(employers.Count, workshops.Count); - maxRows = Math.Max(1, maxRows); + int maxRows = 1; // هر قرارداد فقط یک ردیف؛ نیازی به مرج عمودی نیست int startRow = row; int endRow = row + maxRows - 1; - // 🎨 دریافت رنگ پس‌زمینه از مقدار رنگ موجود در داده - string colorName = contract.ExpireColor.ToLower(); - var fillColor = GetColorByName(colorName, contract.WorkshopCount, contract.IsContractingPartyBlock); + // 🎨 دریافت رنگ پس‌زمینه بر اساس وضعیت قرارداد + var fillColor = GetColorByStatus(contract.ListStatus, contract.WorkshopsCount); for (int j = 0; j < maxRows; j++) { int currentRow = row + j; - worksheet.Cells[currentRow, 4].Value = j < employers.Count ? employers[j].FullName : null; - worksheet.Cells[currentRow, 5].Value = j < workshops.Count ? workshops[j].WorkshopFullName : null; + // پر کردن ستون‌های employer و workshop + var employerColIndex = GetColumnIndexForType(ExcelColumnType.EmployerName, visibleColumnIndices); + var workshopColIndex = GetColumnIndexForType(ExcelColumnType.WorkshopName, visibleColumnIndices); - for (int col = 1; col <= 11; col++) + if (employerColIndex > 0) + worksheet.Cells[currentRow, employerColIndex].Value = j < employers.Count ? employers[j] : null; + + if (workshopColIndex > 0) + worksheet.Cells[currentRow, workshopColIndex].Value = j < workshops.Count ? workshops[j] : null; + + for (int col = 1; col <= columnCount; col++) { var cell = worksheet.Cells[currentRow, col]; @@ -154,109 +203,226 @@ public class InstitutionContractExcelGenerator } // 🧱 مرج و مقداردهی ستون‌های اصلی - worksheet.Cells[startRow, 1, endRow, 1].Merge = true; - worksheet.Cells[startRow, 1].Value = contract.ContractNo; - - worksheet.Cells[startRow, 2, endRow, 2].Merge = true; - worksheet.Cells[startRow, 2].Value = contract.ContractingPartyName; - - worksheet.Cells[startRow, 3, endRow, 3].Merge = true; - worksheet.Cells[startRow, 3].Value = contract.ArchiveCode; - - worksheet.Cells[startRow, 6, endRow, 6].Merge = true; - worksheet.Cells[startRow, 6].Value = contract.EmployeeCount; - - worksheet.Cells[startRow, 7, endRow, 7].Merge = true; - worksheet.Cells[startRow, 7].Value = contract.ContractStartFa; - - worksheet.Cells[startRow, 8, endRow, 8].Merge = true; - worksheet.Cells[startRow, 8].Value = contract.ContractEndFa; - - worksheet.Cells[startRow, 9, endRow, 9].Merge = true; - var contractWithoutWorkshopAmountCell = worksheet.Cells[startRow, 9]; - contractWithoutWorkshopAmountCell.Value = contract.WorkshopCount == "0" ? MoneyToDouble(contract.ContractAmount) : ""; - contractWithoutWorkshopAmountCell.Style.Numberformat.Format = "#,##0"; - - - worksheet.Cells[startRow, 10, endRow, 10].Merge = true; - var contractAmountCell = worksheet.Cells[startRow, 10]; - contractAmountCell.Value = contract.WorkshopCount != "0" ? MoneyToDouble(contract.ContractAmount) : ""; - contractAmountCell.Style.Numberformat.Format = "#,##0"; - - - worksheet.Cells[startRow, 11, endRow, 11].Merge = true; - var balance = MoneyToDouble(contract.BalanceStr); - var balanceCell = worksheet.Cells[startRow, 11]; - balanceCell.Value = balance; - balanceCell.Style.Numberformat.Format = "#,##0"; - - if (balance > 0) - balanceCell.Style.Font.Color.SetColor(Color.Red); - else if (balance < 0) - balanceCell.Style.Font.Color.SetColor(Color.Green); + FillColumnData(worksheet, contract, startRow, endRow, visibleColumnIndices); // 📦 بوردر ضخیم خارجی برای هر سطر - var boldRange = worksheet.Cells[startRow, 1, endRow, 11]; + var boldRange = worksheet.Cells[startRow, 1, endRow, columnCount]; boldRange.Style.Border.BorderAround(ExcelBorderStyle.Medium); row += maxRows; } + SetupPrintSettings(worksheet, visibleColumnIndices, columnCount); + } + /// + /// دریافت فهرست ستون‌های مرئی بر اساس کانفیگ + /// + private static List GetVisibleColumnIndices() + { + return _columnConfig.VisibleColumns; + } + /// + /// دریافت شماره ستون برای یک نوع ستون خاص + /// + private static int GetColumnIndexForType(ExcelColumnType columnType, List visibleColumns) + { + var index = visibleColumns.IndexOf(columnType); + return index >= 0 ? index + 1 : 0; // 1-based indexing + } + + /// + /// دریافت متن header برای یک نوع ستون + /// + private static string GetColumnHeader(ExcelColumnType columnType) + { + return columnType switch + { + ExcelColumnType.RowNumber => "ردیف", + ExcelColumnType.PhysicalContract => "قرارداد فیزیکی", + ExcelColumnType.ContractNo => "شماره قرارداد", + ExcelColumnType.Representative => "معرف", + ExcelColumnType.ContractingPartyName => "طرف حساب", + ExcelColumnType.ArchiveCode => "شماره کارفرما", + ExcelColumnType.EmployerName => "کارفرما", + ExcelColumnType.WorkshopName => "کارگاه‌ها", + ExcelColumnType.WorkshopCount => "تعداد کارگاه", + ExcelColumnType.EmployeeCount => "مجموع پرسنل", + ExcelColumnType.ContractStartDate => "شروع قرارداد", + ExcelColumnType.ContractEndDate => "پایان قرارداد", + ExcelColumnType.InstallmentAmount => "مبلغ قسط", + ExcelColumnType.ContractAmount => "مبلغ قرارداد", + ExcelColumnType.FinancialStatus => "وضعیت مالی", + _ => "" + }; + } + + /// + /// تنظیم Header‌های ستون‌ها + /// + private static void SetupHeaders(ExcelWorksheet worksheet, List visibleColumns, int columnCount) + { + for (int i = 0; i < visibleColumns.Count; i++) + { + worksheet.Cells[1, i + 1].Value = GetColumnHeader(visibleColumns[i]); + } + } + + /// + /// پر کردن داده‌های ستون‌ها برای یک قرارداد + /// + private static void FillColumnData(ExcelWorksheet worksheet, GetInstitutionContractListItemsViewModel contract, int startRow, int endRow, List visibleColumns) + { + for (int i = 0; i < visibleColumns.Count; i++) + { + int columnIndex = i + 1; // 1-based indexing + var columnType = visibleColumns[i]; + + // Merge cells for non-repeating columns + worksheet.Cells[startRow, columnIndex, endRow, columnIndex].Merge = true; + + var cell = worksheet.Cells[startRow, columnIndex]; + + switch (columnType) + { + case ExcelColumnType.RowNumber: + // TODO: مقدار ردیف رو از user input دریافت کن + break; + case ExcelColumnType.PhysicalContract: + // TODO: مقدار قرارداد فیزیکی رو دریافت کن + break; + case ExcelColumnType.ContractNo: + cell.Value = contract.ContractNo; + break; + case ExcelColumnType.Representative: + cell.Value = contract.RepresentativeName; + break; + case ExcelColumnType.ContractingPartyName: + cell.Value = contract.ContractingPartyName; + break; + case ExcelColumnType.ArchiveCode: + cell.Value = contract.ArchiveNo; + break; + case ExcelColumnType.EmployerName: + // این ستون چندخطی است و داخل loop پر می‌شود + break; + case ExcelColumnType.WorkshopName: + // این ستون چندخطی است و داخل loop پر می‌شود + break; + case ExcelColumnType.WorkshopCount: + cell.Value = contract.WorkshopsCount; + break; + case ExcelColumnType.EmployeeCount: + cell.Value = contract.EmployeesCount; + break; + case ExcelColumnType.ContractStartDate: + cell.Value = contract.ContractStartFa; + break; + case ExcelColumnType.ContractEndDate: + cell.Value = contract.ContractEndFa; + break; + case ExcelColumnType.InstallmentAmount: + cell.Value = contract.InstallmentAmount; + cell.Style.Numberformat.Format = "#,##0"; + break; + case ExcelColumnType.ContractAmount: + cell.Value = contract.ContractAmount; + cell.Style.Numberformat.Format = "#,##0"; + break; + case ExcelColumnType.FinancialStatus: + cell.Value = contract.Balance; + cell.Style.Numberformat.Format = "#,##0"; + + if (contract.Balance > 0) + cell.Style.Font.Color.SetColor(Color.Red); + else if (contract.Balance < 0) + cell.Style.Font.Color.SetColor(Color.Green); + break; + } + } + } + + /// + /// تنظیم تنظیمات چاپ و عرض ستون‌ها + /// + private static void SetupPrintSettings(ExcelWorksheet worksheet, List visibleColumns, int columnCount) + { worksheet.PrinterSettings.PaperSize = ePaperSize.A4; worksheet.PrinterSettings.Orientation = eOrientation.Landscape; worksheet.PrinterSettings.FitToPage = true; worksheet.PrinterSettings.FitToWidth = 1; worksheet.PrinterSettings.FitToHeight = 0; worksheet.PrinterSettings.Scale = 85; - int contractNoCol = 1; - int contractingPartyNameCol = 2; - int archiveNoCol = 3; - int employersCol = 4; - int workshopsCol = 5; - int employeeCountCol = 6; - int startContractCol = 7; - int endContractCol = 8; - int contractWithoutWorkshopAmountCol = 9; - int contractAmountCol = 10; - int balanceCol = 11; - worksheet.Columns[contractNoCol].Width = 17; - worksheet.Columns[contractingPartyNameCol].Width = 40; - worksheet.Columns[archiveNoCol].Width = 10; - worksheet.Columns[employersCol].Width = 40; - worksheet.Columns[workshopsCol].Width = 45; - worksheet.Columns[employeeCountCol].Width = 12; - worksheet.Columns[startContractCol].Width = 12; - worksheet.Columns[endContractCol].Width = 12; - worksheet.Columns[contractWithoutWorkshopAmountCol].Width = 18; - worksheet.Columns[contractAmountCol].Width = 12; - worksheet.Columns[balanceCol].Width = 12; + + // تنظیم عرض ستون‌ها بر اساس نوع ستون + for (int i = 0; i < visibleColumns.Count; i++) + { + int columnIndex = i + 1; + worksheet.Columns[columnIndex].Width = GetColumnWidth(visibleColumns[i]); + } + worksheet.View.RightToLeft = true; // فارسی - //worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns(); + } + + /// + /// دریافت عرض ستون پیش‌فرض برای هر نوع ستون + /// + private static double GetColumnWidth(ExcelColumnType columnType) + { + return columnType switch + { + ExcelColumnType.RowNumber => 8, + ExcelColumnType.PhysicalContract => 15, + ExcelColumnType.ContractNo => 17, + ExcelColumnType.Representative => 15, + ExcelColumnType.ContractingPartyName => 40, + ExcelColumnType.ArchiveCode => 10, + ExcelColumnType.EmployerName => 40, + ExcelColumnType.WorkshopName => 45, + ExcelColumnType.WorkshopCount => 12, + ExcelColumnType.EmployeeCount => 12, + ExcelColumnType.ContractStartDate => 12, + ExcelColumnType.ContractEndDate => 12, + ExcelColumnType.InstallmentAmount => 15, + ExcelColumnType.ContractAmount => 15, + ExcelColumnType.FinancialStatus => 12, + _ => 12 + }; } private static double MoneyToDouble(string value) { - Console.WriteLine(value); + if (string.IsNullOrEmpty(value)) + return 0; + var min = value.Length > 1 ? value.Substring(0, 2) : ""; var test = min == "\u200e\u2212" ? value.MoneyToDouble() * -1 : value.MoneyToDouble(); - - Console.WriteLine(test); return test; } - private static Color GetColorByName(string name, string workshopCount, string IsContractingPartyBlock) + + /// + /// دریافت رنگ بر اساس وضعیت قرارداد + /// + private static Color GetColorByStatus(InstitutionContractListStatus status, int workshopsCount) { - return name switch + return status switch { - "blue" => Color.LightBlue, - _ when IsContractingPartyBlock == "true" => Color.LightGray, - "red" => Color.LightCoral, - "purple" => Color.MediumPurple, - "black" => Color.DimGray, - var n when string.IsNullOrWhiteSpace(n) && workshopCount == "0" => Color.Yellow, + InstitutionContractListStatus.DeactiveWithDebt => Color.LightBlue, + InstitutionContractListStatus.Deactive => Color.LightGray, + InstitutionContractListStatus.PendingForRenewal => Color.LightCoral, + InstitutionContractListStatus.Free => Color.MediumPurple, + InstitutionContractListStatus.Block => Color.DimGray, + InstitutionContractListStatus.WithoutWorkshop => Color.Yellow, + InstitutionContractListStatus.Active => Color.White, _ => Color.White }; } -} \ No newline at end of file +} + +public class InstitutionContractExcelViewModel +{ + public InstitutionContractListStatus? Tab { get; set; } + public List GetInstitutionContractListItemsViewModels { get; set; } +} diff --git a/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs b/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs index 3e965996..3f2eb9ac 100644 --- a/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs +++ b/CompanyManagment.EFCore/Repository/InsuranceListRepository.cs @@ -1814,7 +1814,17 @@ public class InsuranceListRepository : RepositoryBase, IIns Count = g.Count(x=>x.LeftWorkDate != null) }).ToListAsync(); - + query = searchModel.Sorting switch + { + "CreationDate-Max" => query.OrderByDescending(x => x.id), + "CreationDate-Min" => query.OrderBy(x => x.id), + "Month-Max" => query.OrderByDescending(x => x.Month), + "Month-Min" => query.OrderBy(x => x.Month), + "Year-Max" => query.OrderByDescending(x => x.Year), + "Year-Min" => query.OrderBy(x => x.Year), + _ => query.OrderByDescending(x => x.id), + }; + var resList = list .Select(x => new InsuranceClientListViewModel { @@ -1835,17 +1845,7 @@ public class InsuranceListRepository : RepositoryBase, IIns LeftWorkCount =employeeData.FirstOrDefault(e=>e.Key == x.id)?.Count ?? 0, }).ToList(); - resList = searchModel.Sorting switch - { - "CreationDate-Max" => resList.OrderByDescending(x => x.Id).ToList(), - "CreationDate-Min" => resList.OrderBy(x => x.Id).ToList(), - "Month-Max" => resList.OrderByDescending(x => x.MonthInt).ToList(), - "Month-Min" => resList.OrderBy(x => x.MonthInt).ToList(), - "Year-Max" => resList.OrderByDescending(x => x.YearInt).ToList(), - "Year-Min" => resList.OrderBy(x => x.YearInt).ToList(), - _ => resList.OrderByDescending(x => x.Id).ToList(), - }; - + res.List = resList; return res; @@ -1961,37 +1961,37 @@ public class InsuranceListRepository : RepositoryBase, IIns var workshopList = await query.Skip(searchModel.PageIndex).Take(30).ToListAsync(); - var workshopIds = workshopList.Select(x => x.WorkShopId); - - var employers = await _context.WorkshopEmployers - .Where(x => workshopIds.Contains(x.WorkshopId)) - .GroupBy(x => x.WorkshopId) - .Select(x => x.First()).ToListAsync(); - - var res = workshopList.Select(x => - { - var employer = employers.FirstOrDefault(e => e.WorkshopId == x.WorkShopId)?.Employer; - - return new InsuranceListViewModel - { - WorkShopId = x.WorkShopId, - WorkShopCode = x.WorkShopCode, - WorkShopName = x.WorkShopName, - EmployerName = employer != null - ? employer.FullName - : (x.EmployerName), - Year = searchModel.Year, - Month = searchModel.Month, - TypeOfInsuranceSend = x.TypeOfInsuranceSend == "NormalList" ? "عادی" : - x.TypeOfInsuranceSend == "Govermentlist" ? "کمک دولت" : - x.TypeOfInsuranceSend == "Familylist" ? "خانوادگی" : "", - FixedSalary = (bool)x.FixedSalary, - StrFixedSalary = (bool)x.FixedSalary ? "دارد" : "ندارد", - EmployerId = employer?.id ?? 0, - ArchiveCode = x.ArchiveCode, - City = x.City, - }; - }).ToList(); + var workshopIds = workshopList.Select(x=>x.WorkShopId); + + var employers =await _context.WorkshopEmployers + .Where(x=>workshopIds.Contains(x.WorkshopId)) + .GroupBy(x=>x.WorkshopId) + .Select(x=>x.First()).ToListAsync(); + + var res = workshopList.Select(x => + { + var employer = employers.FirstOrDefault(e => e.WorkshopId ==x.WorkShopId)?.Employer; + + return new InsuranceListViewModel + { + WorkShopId = x.WorkShopId, + WorkShopCode = x.WorkShopCode, + WorkShopName = x.WorkShopName, + EmployerName = employer != null + ? employer.FullName + : (x.EmployerName), + Year = searchModel.Year, + Month = searchModel.Month, + TypeOfInsuranceSend = x.TypeOfInsuranceSend == "NormalList" ? "عادی" : + x.TypeOfInsuranceSend == "Govermentlist" ? "کمک دولت" : + x.TypeOfInsuranceSend == "Familylist" ? "خانوادگی" : "", + FixedSalary = (bool)x.FixedSalary, + StrFixedSalary = (bool)x.FixedSalary ? "دارد" : "ندارد", + EmployerId = employer?.id ?? 0, + ArchiveCode = x.ArchiveCode, + City = x.City, + }; + }).ToList(); return res; } diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs index 5a085060..69e82940 100644 --- a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectBoardList/ProjectBoardListQueryHandler.cs @@ -22,8 +22,9 @@ public class ProjectBoardListQueryHandler : IBaseQueryHandler x.InitialEstimatedHours > TimeSpan.Zero) + .Where(x => x.InitialEstimatedHours > TimeSpan.Zero && x.Status != TaskSectionStatus.Completed) .Include(x => x.Task) .ThenInclude(x => x.Phase) .ThenInclude(x => x.Project) diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardDetail/ProjectDeployBoardDetailsQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardDetail/ProjectDeployBoardDetailsQueryHandler.cs new file mode 100644 index 00000000..3e3657d9 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardDetail/ProjectDeployBoardDetailsQueryHandler.cs @@ -0,0 +1,101 @@ +using System.Security.AccessControl; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail; + +public record ProjectDeployBoardDetailsResponse( + ProjectDeployBoardDetailPhaseItem Phase, + List Tasks); + +public record ProjectDeployBoardDetailPhaseItem( + string Name, + TimeSpan TotalTimeSpan, + TimeSpan DoneTimeSpan); + +public record ProjectDeployBoardDetailTaskItem( + string Name, + TimeSpan TotalTimeSpan, + TimeSpan DoneTimeSpan, + List Skills) + : ProjectDeployBoardDetailPhaseItem(Name, TotalTimeSpan, DoneTimeSpan); + +public record ProjectDeployBoardDetailItemSkill(string OriginalUserFullName, string SkillName, int TimePercentage); + +public record ProjectDeployBoardDetailsQuery(Guid PhaseId) : IBaseQuery; + +public class + ProjectDeployBoardDetailsQueryHandler : IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _dbContext; + + public ProjectDeployBoardDetailsQueryHandler(IProgramManagerDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> Handle(ProjectDeployBoardDetailsQuery request, + CancellationToken cancellationToken) + { + var phase = await _dbContext.ProjectPhases + .Include(x => x.Tasks) + .ThenInclude(x => x.Sections) + .ThenInclude(x => x.Activities) + .Include(x => x.Tasks) + .ThenInclude(x => x.Sections) + .ThenInclude(x => x.AdditionalTimes) + .Include(x => x.Tasks) + .ThenInclude(x => x.Sections) + .ThenInclude(x => x.Skill) + .FirstOrDefaultAsync(x => x.Id == request.PhaseId, cancellationToken); + + if (phase == null) + return OperationResult.NotFound("بخش اصلی مورد نظر یافت نشد"); + + var userIds = phase.Tasks + .SelectMany(t => t.Sections) + .Select(s => s.OriginalAssignedUserId) + .Distinct() + .ToList(); + + var usersDict = await _dbContext.Users + .Where(x => userIds.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id, x => x.FullName, cancellationToken); + + var tasksRes = phase.Tasks.Select(t => + { + var totalTime = t.Sections.Select(s => s.FinalEstimatedHours) + .Aggregate(TimeSpan.Zero, (sum, next) => sum.Add(next)); + + var doneTime = t.Sections.Aggregate(TimeSpan.Zero, + (sum, next) => sum.Add(next.GetTotalTimeSpent())); + var skills = t.Sections + .Select(s => new ProjectDeployBoardDetailItemSkill( + usersDict.GetValueOrDefault(s.OriginalAssignedUserId, "کاربر ناشناس"), + s.Skill?.Name ?? "بدون مهارت", + totalTime.TotalSeconds > 0 + ? (int)((doneTime.TotalSeconds / totalTime.TotalSeconds) * 100) + : 0)).ToList(); + + return new ProjectDeployBoardDetailTaskItem( + t.Name, + totalTime, + doneTime, + skills); + }).ToList(); + + var totalTimeSpan = tasksRes.Aggregate(TimeSpan.Zero, + (sum, next) => sum.Add(next.TotalTimeSpan)); + + var doneTimeSpan = tasksRes.Aggregate(TimeSpan.Zero, + (sum, next) => sum.Add(next.DoneTimeSpan)); + + var phaseRes = new ProjectDeployBoardDetailPhaseItem(phase.Name, totalTimeSpan, doneTimeSpan); + + var res = new ProjectDeployBoardDetailsResponse(phaseRes, tasksRes); + + return OperationResult.Success(res); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardDetail/ProjectDeployBoardDetailsQueryValidator.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardDetail/ProjectDeployBoardDetailsQueryValidator.cs new file mode 100644 index 00000000..0cbf5cd9 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardDetail/ProjectDeployBoardDetailsQueryValidator.cs @@ -0,0 +1,11 @@ +using FluentValidation; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardDetail; + +public class ProjectDeployBoardDetailsQueryValidator:AbstractValidator +{ + public ProjectDeployBoardDetailsQueryValidator() + { + RuleFor(x=>x.PhaseId).NotNull().WithMessage("شناسه بخش اصلی نمی‌تواند خالی باشد"); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs new file mode 100644 index 00000000..3cbac6e0 --- /dev/null +++ b/ProgramManager/src/Application/GozareshgirProgramManager.Application/Modules/Projects/Queries/ProjectDeployBoardList/ProjectDeployBoardListQueryHandler.cs @@ -0,0 +1,70 @@ +using System.Xml.Schema; +using GozareshgirProgramManager.Application._Common.Interfaces; +using GozareshgirProgramManager.Application._Common.Models; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; +using GozareshgirProgramManager.Domain.ProjectAgg.Entities; +using GozareshgirProgramManager.Domain.ProjectAgg.Enums; +using Microsoft.EntityFrameworkCore; + +namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardList; + +public record ProjectDeployBoardListItem() +{ + public string ProjectName { get; set; } + public string PhaseName { get; set; } + public int TotalTasks { get; set; } + public int DoneTasks { get; set; } + public TimeSpan TotalTimeSpan { get; set; } + public TimeSpan DoneTimeSpan { get; set; } + public ProjectDeployStatus DeployStatus { get; set; } +} +public record GetProjectsDeployBoardListResponse(List Items); + + +public record GetProjectDeployBoardListQuery():IBaseQuery; + +public class ProjectDeployBoardListQueryHandler:IBaseQueryHandler +{ + private readonly IProgramManagerDbContext _dbContext; + private readonly IAuthHelper _authHelper; + + + public ProjectDeployBoardListQueryHandler(IProgramManagerDbContext dbContext, IAuthHelper authHelper) + { + _dbContext = dbContext; + _authHelper = authHelper; + } + + public async Task> Handle(GetProjectDeployBoardListQuery request, CancellationToken cancellationToken) + { + var userId = _authHelper.GetCurrentUserId(); + if (userId == null) + { + return OperationResult.NotFound("کاربر یافت نشد"); + } + + var query =await _dbContext.TaskSections + .Include(x=>x.Task) + .ThenInclude(x => x.Phase) + .ThenInclude(x => x.Project) + .AsNoTracking() + .Where(x => x.Status == TaskSectionStatus.Completed + || x.Status == TaskSectionStatus.PendingForCompletion + || x.Task.Phase.DeployStatus != ProjectDeployStatus.NoTCompleted) + .GroupBy(x=>x.Task.PhaseId).ToListAsync(cancellationToken: cancellationToken); + + var list = query.Select(g => new ProjectDeployBoardListItem + { + ProjectName = g.First().Task.Phase.Project.Name, + PhaseName = g.First().Task.Phase.Name, + TotalTasks = g.Select(x => x.TaskId).Distinct().Count(), + DoneTasks = g.Where(x => x.Status == TaskSectionStatus.Completed).Select(x => x.TaskId).Distinct().Count(), + TotalTimeSpan = TimeSpan.FromHours(g.Sum(x => x.InitialEstimatedHours.TotalHours)), + DoneTimeSpan = TimeSpan.FromHours(g.Where(x => x.Status == TaskSectionStatus.Completed) + .Sum(x => x.InitialEstimatedHours.TotalHours)), + DeployStatus = g.First().Task.Phase.DeployStatus + }).ToList(); + var response = new GetProjectsDeployBoardListResponse(list); + return OperationResult.Success(response); + } +} \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs index 539ac278..8d7583bc 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Entities/ProjectPhase.cs @@ -23,6 +23,7 @@ public class ProjectPhase : ProjectHierarchyNode ProjectId = projectId; _tasks = new List(); _phaseSections = new List(); + DeployStatus = ProjectDeployStatus.NoTCompleted; AddDomainEvent(new PhaseCreatedEvent(Id, projectId, name)); } @@ -36,6 +37,8 @@ public class ProjectPhase : ProjectHierarchyNode public DateTime? StartDate { get; private set; } public DateTime? EndDate { get; private set; } public int OrderIndex { get; private set; } + public bool IsArchived { get; set; } + public ProjectDeployStatus DeployStatus { get; set; } #region Task Management @@ -196,4 +199,26 @@ public class ProjectPhase : ProjectHierarchyNode } #endregion + + public void SetArchived() + { + IsArchived = true; + } + public void SetUnarchived() + { + IsArchived = false; + } + public void UpdateDeployStatus(ProjectDeployStatus status) + { + DeployStatus = status; + } +} + +public enum ProjectDeployStatus +{ + NoTCompleted, + PendingDevDeploy, + DevDeployed, + PendingDeploy, + Deployed } diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs index d5208bfb..5c5a019e 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Enums/TaskSectionStatus.cs @@ -6,5 +6,6 @@ public enum TaskSectionStatus ReadyToStart = 1, // آماده شروع InProgress = 2, // درحال انجام Incomplete = 3, // ناتمام شده - Completed = 4 // تکمیل شده + PendingForCompletion = 4, // در انتظار تکمیل + Completed = 5 // تکمیل شده } \ No newline at end of file diff --git a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs index fb6ca424..155fec66 100644 --- a/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs +++ b/ProgramManager/src/Domain/GozareshgirProgramManager.Domain/ProjectAgg/Events/ProjectEvents.cs @@ -8,171 +8,171 @@ namespace GozareshgirProgramManager.Domain.ProjectAgg.Events; // Project Events public record ProjectCreatedEvent(Guid ProjectId, string Name) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectStatusUpdatedEvent(Guid ProjectId, ProjectStatus Status) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectAssignedEvent(Guid ProjectId, long UserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectUnassignedEvent(Guid ProjectId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } // Phase Events public record PhaseCreatedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record PhaseAddedEvent(Guid PhaseId, Guid ProjectId, string Name) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record PhaseRemovedEvent(Guid PhaseId, Guid ProjectId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record PhaseStatusUpdatedEvent(Guid PhaseId, PhaseStatus Status) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record PhaseAssignedEvent(Guid PhaseId, long UserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record PhaseUnassignedEvent(Guid PhaseId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } // Task Events public record TaskCreatedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskAddedEvent(Guid TaskId, Guid PhaseId, string Name) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskRemovedEvent(Guid TaskId, Guid PhaseId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskStatusUpdatedEvent(Guid TaskId, TaskStatus Status) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskPriorityUpdatedEvent(Guid TaskId, TaskPriority Priority) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskAssignedEvent(Guid TaskId, long UserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskUnassignedEvent(Guid TaskId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskSectionAddedEvent(Guid TaskId, Guid SectionId, Guid SkillId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskSectionRemovedEvent(Guid TaskId, Guid SectionId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } // TaskSection Events public record TaskSectionStatusChangedEvent(Guid SectionId, TaskSectionStatus OldStatus, TaskSectionStatus NewStatus,long UserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record TaskSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } // Section Events (Legacy - keeping for backward compatibility) public record ProjectPhaseAddedEvent(Guid ProjectId, Guid PhaseId, string PhaseName) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectTaskStatusChangedEvent(Guid SectionId, TaskStatus OldStatus, TaskStatus NewStatus) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectSectionAddedEvent(Guid SectionId, Guid TaskId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectSectionAssignedEvent(Guid SectionId, long UserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectSectionTransferredEvent(Guid SectionId, long FromUserId, long ToUserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record WorkStartedEvent(Guid SectionId, long UserId, DateTime StartTime, string? Notes) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record WorkStoppedEvent(Guid SectionId, long UserId, DateTime StartTime, DateTime EndTime, TimeSpan Duration, string? Notes) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record ProjectSectionCompletedEvent(Guid ProjectId, long UserId, TimeSpan TotalTimeSpent, string? Notes) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record AdditionalTimeAddedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan Hours, string? Reason, long? AddedByUserId) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record AdditionalTimeRemovedEvent(Guid ProjectId, Guid AdditionalTimeId, TimeSpan RemovedHours) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } public record InitialEstimatedTimeUpdatedEvent(Guid ProjectId, TimeSpan OldEstimate, TimeSpan NewEstimate) : IDomainEvent { - public DateTime OccurredOn { get; init; } = DateTime.UtcNow; + public DateTime OccurredOn { get; init; } = DateTime.Now; } diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251227094008_add phase deploy status and is archived.Designer.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251227094008_add phase deploy status and is archived.Designer.cs new file mode 100644 index 00000000..74452d75 --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251227094008_add phase deploy status and is archived.Designer.cs @@ -0,0 +1,865 @@ +// +using System; +using GozareshgirProgramManager.Infrastructure.Persistence.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + [DbContext(typeof(ProgramManagerDbContext))] + [Migration("20251227094008_add phase deploy status and is archived")] + partial class addphasedeploystatusandisarchived + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CheckoutAgg.Entities.Checkout", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CheckoutEndDate") + .HasColumnType("datetime2"); + + b.Property("CheckoutStartDate") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeductionFromSalary") + .HasColumnType("float"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MandatoryHours") + .HasColumnType("int"); + + b.Property("Month") + .HasColumnType("int"); + + b.Property("MonthlySalaryDefined") + .HasColumnType("float"); + + b.Property("MonthlySalaryPay") + .HasColumnType("float"); + + b.Property("RemainingHours") + .HasColumnType("int"); + + b.Property("TotalDaysWorked") + .HasColumnType("int"); + + b.Property("TotalHoursWorked") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Checkouts", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.CustomerAgg.Customer", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Customers", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.HasIndex("SkillId"); + + b.ToTable("PhaseSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime2"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime2"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("DeployStatus") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("IsArchived") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectPhases", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ProjectId") + .HasColumnType("uniqueidentifier"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("SkillId"); + + b.ToTable("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AllocatedTime") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DueDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("HasAssignmentOverride") + .HasColumnType("bit"); + + b.Property("HasTimeOverride") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.Property("PhaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("PhaseId"); + + b.ToTable("ProjectTasks", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("CurrentAssignedUserId") + .HasColumnType("bigint"); + + b.Property("InitialDescription") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("InitialEstimatedHours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("OriginalAssignedUserId") + .HasColumnType("bigint"); + + b.Property("SkillId") + .HasColumnType("uniqueidentifier"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaskId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SkillId"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskSections", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("EndNotes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("SectionId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("SectionId"); + + b.ToTable("TaskSectionActivities", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AddedAt") + .HasColumnType("datetime2"); + + b.Property("AddedByUserId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Hours") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Reason") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("TaskSectionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TaskSectionId"); + + b.ToTable("TaskSectionAdditionalTimes", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("GozareshgirRoleId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("PmRoles", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("EndSettingDate") + .HasColumnType("datetime2"); + + b.Property("HolidayWorking") + .HasColumnType("bit"); + + b.Property("MonthlySalary") + .HasColumnType("float"); + + b.Property("StartSettingDate") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("SalaryPaymentSetting", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.ToTable("Skills", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ProfilePhotoPath") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("VerifyCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RevokedAt") + .HasColumnType("datetime2"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserAgent") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ExpiresAt"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserRefreshTokens", (string)null); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.PhaseSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("PhaseSections") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany() + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Phase"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project") + .WithMany("Phases") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", "Project") + .WithMany("ProjectSections") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany() + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Project"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", "Phase") + .WithMany("Tasks") + .HasForeignKey("PhaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Phase"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.HasOne("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", "Skill") + .WithMany("Sections") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", "Task") + .WithMany("Sections") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Skill"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionActivity", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", "Section") + .WithMany("Activities") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSectionAdditionalTime", b => + { + b.HasOne("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", null) + .WithMany("AdditionalTimes") + .HasForeignKey("TaskSectionId"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.RoleAgg.Entities.Role", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.PermissionAgg.Entities.Permission", "Permissions", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("Code") + .HasColumnType("int"); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("RoleId"); + + b1.ToTable("PmRolePermissions", (string)null); + + b1.WithOwner("Role") + .HasForeignKey("RoleId"); + + b1.Navigation("Role"); + }); + + b.Navigation("Permissions"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.SalaryPaymentSetting", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.SalaryPaymentSettingAgg.Entities.WorkingHours", "WorkingHoursList", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("EndShiftOne") + .HasColumnType("time(0)"); + + b1.Property("EndShiftTwo") + .HasColumnType("time(0)"); + + b1.Property("HasRestTime") + .HasColumnType("bit"); + + b1.Property("HasShiftOne") + .HasColumnType("bit"); + + b1.Property("HasShiftTow") + .HasColumnType("bit"); + + b1.Property("IsActiveDay") + .HasColumnType("bit"); + + b1.Property("PersianDayOfWeek") + .HasColumnType("int"); + + b1.Property("RestTime") + .HasColumnType("time(0)"); + + b1.Property("SalaryPaymentSettingId") + .HasColumnType("bigint"); + + b1.Property("ShiftDurationInMinutes") + .HasColumnType("int"); + + b1.Property("StartShiftOne") + .HasColumnType("time(0)"); + + b1.Property("StartShiftTwo") + .HasColumnType("time(0)"); + + b1.HasKey("Id"); + + b1.HasIndex("SalaryPaymentSettingId"); + + b1.ToTable("WorkingHours", (string)null); + + b1.WithOwner("SalaryPaymentSetting") + .HasForeignKey("SalaryPaymentSettingId"); + + b1.Navigation("SalaryPaymentSetting"); + }); + + b.Navigation("WorkingHoursList"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.OwnsMany("GozareshgirProgramManager.Domain.RoleUserAgg.RoleUser", "RoleUser", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b1.Property("Id")); + + b1.Property("RoleId") + .HasColumnType("bigint"); + + b1.Property("UserId") + .HasColumnType("bigint"); + + b1.HasKey("Id"); + + b1.HasIndex("UserId"); + + b1.ToTable("RoleUsers", (string)null); + + b1.WithOwner("User") + .HasForeignKey("UserId"); + + b1.Navigation("User"); + }); + + b.Navigation("RoleUser"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.UserRefreshToken", b => + { + b.HasOne("GozareshgirProgramManager.Domain.UserAgg.Entities.User", "User") + .WithMany("RefreshTokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => + { + b.Navigation("Phases"); + + b.Navigation("ProjectSections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectPhase", b => + { + b.Navigation("PhaseSections"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.TaskSection", b => + { + b.Navigation("Activities"); + + b.Navigation("AdditionalTimes"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.SkillAgg.Entities.Skill", b => + { + b.Navigation("Sections"); + }); + + modelBuilder.Entity("GozareshgirProgramManager.Domain.UserAgg.Entities.User", b => + { + b.Navigation("RefreshTokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251227094008_add phase deploy status and is archived.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251227094008_add phase deploy status and is archived.cs new file mode 100644 index 00000000..7dce42cd --- /dev/null +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/20251227094008_add phase deploy status and is archived.cs @@ -0,0 +1,41 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace GozareshgirProgramManager.Infrastructure.Migrations +{ + /// + public partial class addphasedeploystatusandisarchived : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "DeployStatus", + table: "ProjectPhases", + type: "nvarchar(30)", + maxLength: 30, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "IsArchived", + table: "ProjectPhases", + type: "bit", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DeployStatus", + table: "ProjectPhases"); + + migrationBuilder.DropColumn( + name: "IsArchived", + table: "ProjectPhases"); + } + } +} diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs index 25e60639..4382f61b 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Migrations/AppDbContextModelSnapshot.cs @@ -126,7 +126,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.HasIndex("SkillId"); - b.ToTable("PhaseSections", (string)null); + b.ToTable("PhaseSections"); }); modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.Project", b => @@ -179,6 +179,11 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Property("CreationDate") .HasColumnType("datetime2"); + b.Property("DeployStatus") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + b.Property("Description") .HasMaxLength(1000) .HasColumnType("nvarchar(1000)"); @@ -189,6 +194,9 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.Property("HasAssignmentOverride") .HasColumnType("bit"); + b.Property("IsArchived") + .HasColumnType("bit"); + b.Property("Name") .IsRequired() .HasMaxLength(200) @@ -238,7 +246,7 @@ namespace GozareshgirProgramManager.Infrastructure.Migrations b.HasIndex("SkillId"); - b.ToTable("ProjectSections", (string)null); + b.ToTable("ProjectSections"); }); modelBuilder.Entity("GozareshgirProgramManager.Domain.ProjectAgg.Entities.ProjectTask", b => diff --git a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs index 838b7f0e..01a43077 100644 --- a/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs +++ b/ProgramManager/src/Infrastructure/GozareshgirProgramManager.Infrastructure/Persistence/Mappings/ProjectPhaseMapping.cs @@ -48,6 +48,9 @@ public class ProjectPhaseMapping : IEntityTypeConfiguration builder.Property(ph => ph.HasAssignmentOverride) .IsRequired(); + builder.Property(x => x.DeployStatus) + .HasConversion().HasMaxLength(30); + // Relationship with Project builder.HasOne(ph => ph.Project) .WithMany(p => p.Phases) diff --git a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs index 548018f6..3381ce20 100644 --- a/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs +++ b/ServiceHost/Areas/Admin/Controllers/ProgramManager/ProjectController.cs @@ -12,6 +12,7 @@ using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectA using GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectsList; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardDetail; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectBoardList; +using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectDeployBoardList; using GozareshgirProgramManager.Application.Modules.Projects.Queries.ProjectSetTimeDetails; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -112,4 +113,18 @@ public class ProjectController : ProgramManagerBaseController var res = await _mediator.Send(query); return res; } + + [HttpGet("deploy-board")] + public async Task>> GetProjectDeployBoard() + { + var request = new GetProjectDeployBoardListQuery(); + return await _mediator.Send(request); + } + [HttpGet("deploy-board/details")] + public async Task>> GetProjectDeployBoardDetails(Guid id) + { + var query = new ProjectBoardDetailQuery(id); + var res = await _mediator.Send(query); + return res; + } } \ No newline at end of file diff --git a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs index 64586ae5..e24372f3 100644 --- a/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs +++ b/ServiceHost/Areas/Admin/Controllers/institutionContractController.cs @@ -348,7 +348,7 @@ public class institutionContractController : AdminBaseController { var institutionContractViewModels = _institutionContractApplication.NewSearch(new() { IsActiveString = "both", TypeOfContract = "both" }); - var bytes = InstitutionContractExcelGenerator.GenerateExcel(institutionContractViewModels); + var bytes = InstitutionContractExcelGenerator.GenerateExcel(new List()); return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"قرارداد های مالی.xlsx"); @@ -855,6 +855,34 @@ public class institutionContractController : AdminBaseController var res= await _institutionContractApplication.VerifyInstitutionContractManually(id); return res; } + + [HttpGet("excel-download")] + public async Task ExcelDownload() + { + + var searchModel = new InstitutionContractListSearchModel(); + + var dataVm=new List(); + + foreach (var name in typeof(InstitutionContractListStatus).GetEnumNames()) + { + var @enum = Enum.Parse(name); + searchModel.Status = @enum; + searchModel.PageSize = 99999; + var data =( await(_institutionContractApplication.GetList(searchModel))).List; + dataVm.Add(new InstitutionContractExcelViewModel(){Tab = @enum, GetInstitutionContractListItemsViewModels = data}); + } + + searchModel.Status = null; + + var nullData = ( await(_institutionContractApplication.GetList(searchModel))).List; + dataVm.Add(new InstitutionContractExcelViewModel(){Tab = null, GetInstitutionContractListItemsViewModels = nullData}); + + var bytes = InstitutionContractExcelGenerator.GenerateExcel(dataVm); + return File(bytes, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + $"قرارداد های مالی.xlsx"); + } } diff --git a/ServiceHost/Areas/Admin/Pages/Company/InstitutionContracts/Index.cshtml.cs b/ServiceHost/Areas/Admin/Pages/Company/InstitutionContracts/Index.cshtml.cs index 24586065..bda169a5 100644 --- a/ServiceHost/Areas/Admin/Pages/Company/InstitutionContracts/Index.cshtml.cs +++ b/ServiceHost/Areas/Admin/Pages/Company/InstitutionContracts/Index.cshtml.cs @@ -2,6 +2,7 @@ using System.Drawing; using _0_Framework.Application; using AccountManagement.Application.Contracts.Account; +using Company.Domain.InstitutionContractAgg; using CompanyManagement.Infrastructure.Excel.InstitutionContract; using CompanyManagment.App.Contracts.Employer; using CompanyManagment.App.Contracts.InstitutionContract; @@ -38,6 +39,7 @@ public class IndexModel : PageModel private readonly IInstitutionContractApplication _institutionContract; private readonly ILeftWorkApplication _leftWorkApplication; private readonly IRepresentativeApplication _representativeApplication; + private readonly IInstitutionContractRepository _institutionContractRepository; private readonly string _viewName; @@ -60,7 +62,7 @@ public class IndexModel : PageModel IPersonalContractingPartyApp contractingPartyApplication, IRepresentativeApplication representativeApplication, IInstitutionContractApplication institutionContract, ILeftWorkApplication leftWorkApplication - , IContactInfoApplication contactInfoApplication, IAccountApplication accountApplication) + , IContactInfoApplication contactInfoApplication, IAccountApplication accountApplication, IInstitutionContractRepository institutionContractRepository) { _workshopApplication = workshopApplication; @@ -71,6 +73,7 @@ public class IndexModel : PageModel _leftWorkApplication = leftWorkApplication; _contactInfoApplication = contactInfoApplication; _accountApplication = accountApplication; + _institutionContractRepository = institutionContractRepository; } public string Message { get; set; } @@ -920,12 +923,27 @@ public class IndexModel : PageModel }); } - public IActionResult OnGetDownloadExcel() + public async Task OnGetDownloadExcel() { - var institutionContractViewModels = _institutionContract.NewSearch(new() {IsActiveString = "both", TypeOfContract = "both" }); - - institutionContractViewModels= institutionContractViewModels.GroupBy(x=>x.ContractingPartyId).Select(g=>g.MaxBy(x=>x.ContractStartGr)).ToList(); - var bytes = InstitutionContractExcelGenerator.GenerateExcel(institutionContractViewModels); + var searchModel = new InstitutionContractListSearchModel(); + + var dataVm=new List(); + + foreach (var name in typeof(InstitutionContractListStatus).GetEnumNames()) + { + var @enum = Enum.Parse(name); + searchModel.Status = @enum; + searchModel.PageSize = 99999; + var data =( await(_institutionContractRepository.GetList(searchModel))).List; + dataVm.Add(new InstitutionContractExcelViewModel(){Tab = @enum, GetInstitutionContractListItemsViewModels = data}); + } + + searchModel.Status = null; + + var nullData = ( await(_institutionContractRepository.GetList(searchModel))).List; + dataVm.Add(new InstitutionContractExcelViewModel(){Tab = null, GetInstitutionContractListItemsViewModels = nullData}); + + var bytes = InstitutionContractExcelGenerator.GenerateExcel(dataVm); return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"قرارداد های مالی.xlsx"); diff --git a/ServiceHost/Areas/Client/Pages/Shared/_Menu.cshtml b/ServiceHost/Areas/Client/Pages/Shared/_Menu.cshtml index 3887dd82..b1e830a2 100644 --- a/ServiceHost/Areas/Client/Pages/Shared/_Menu.cshtml +++ b/ServiceHost/Areas/Client/Pages/Shared/_Menu.cshtml @@ -91,9 +91,9 @@ diff --git a/ServiceHost/Program.cs b/ServiceHost/Program.cs index d5fdc458..cc950cf4 100644 --- a/ServiceHost/Program.cs +++ b/ServiceHost/Program.cs @@ -289,6 +289,7 @@ builder.Services.AddCors(options => "http://localhost:3000", "http://localhost:4000", "http://localhost:4001", + "http://localhost:4002", "http://localhost:3001", "https://gozareshgir.ir", "https://dad-mehr.ir", diff --git a/ServiceHost/Properties/launchSettings.json b/ServiceHost/Properties/launchSettings.json index d7381591..1e604c6c 100644 --- a/ServiceHost/Properties/launchSettings.json +++ b/ServiceHost/Properties/launchSettings.json @@ -11,7 +11,7 @@ }, "ServiceHost": { "commandName": "Project", - "launchBrowser": true, + "launchBrowser": false, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"