From fdf7fa0d3c1237798374f171835a5764f0f33131 Mon Sep 17 00:00:00 2001 From: mahan Date: Mon, 13 Oct 2025 09:02:17 +0330 Subject: [PATCH] feat: add versioning to Law entity and implement version management in LawApplication --- Company.Domain/LawAgg/Law.cs | 33 ++++++- .../Law/LawViewModel.cs | 1 + .../LawApplication.cs | 98 ++++++++++++++----- .../Repository/LawRepository.cs | 3 +- 4 files changed, 107 insertions(+), 28 deletions(-) diff --git a/Company.Domain/LawAgg/Law.cs b/Company.Domain/LawAgg/Law.cs index d181e8b9..284f251f 100644 --- a/Company.Domain/LawAgg/Law.cs +++ b/Company.Domain/LawAgg/Law.cs @@ -16,6 +16,7 @@ namespace Company.Domain.LawAgg public LawType Type { get; private set; } public string HeadTitle { get; private set; } public string NotificationsJson { get; private set; } + public int Version { get; private set; } [NotMapped] public List Notifications @@ -26,14 +27,15 @@ namespace Company.Domain.LawAgg set => NotificationsJson = JsonSerializer.Serialize(value); } - public Law(string title, LawType lawType, List notifications, string headTitle ) + public Law(string title, LawType lawType, List notifications, string headTitle, int version = 1) { Title = title; - IsActive = true; + IsActive = true; // آخرین نسخه فعال است Items = new List(); Type = lawType; Notifications = notifications ?? new List(); HeadTitle = headTitle; + Version = version; } public void Edit(string title) @@ -46,7 +48,6 @@ namespace Company.Domain.LawAgg Items.Add(new LawItem(header, details, orderNumber)); } - public void SetItem(List items) { Items = items ?? new List(); @@ -67,6 +68,32 @@ namespace Company.Domain.LawAgg { IsActive = false; } + + public void SetAsLatestVersion() + { + IsActive = true; + } + + public void SetAsOldVersion() + { + IsActive = false; + } + + public Law CreateNewVersion(string title, List notifications, string headTitle, List items) + { + var newVersion = new Law( + title, + this.Type, + notifications, + headTitle, + this.Version + 1 + ); + + newVersion.SetItem(items); + newVersion.SetAsLatestVersion(); + + return newVersion; + } } public class LawItem diff --git a/CompanyManagment.App.Contracts/Law/LawViewModel.cs b/CompanyManagment.App.Contracts/Law/LawViewModel.cs index 13c0bf57..ae481625 100644 --- a/CompanyManagment.App.Contracts/Law/LawViewModel.cs +++ b/CompanyManagment.App.Contracts/Law/LawViewModel.cs @@ -14,6 +14,7 @@ namespace CompanyManagment.App.Contracts.Law public LawType Type { get; set; } public string HeadTitle { get; set; } public List Notifications { get; set; } + public int Version { get; set; } } public class LawItemViewModel diff --git a/CompanyManagment.Application/LawApplication.cs b/CompanyManagment.Application/LawApplication.cs index 94267f82..4b15b225 100644 --- a/CompanyManagment.Application/LawApplication.cs +++ b/CompanyManagment.Application/LawApplication.cs @@ -20,9 +20,16 @@ public class LawApplication : ILawApplication public OperationResult Create(CreateLaw command) { var operation = new OperationResult(); - if (_lawRepository.Exists(x => x.Type == command.Type)) + + // قبل از ایجاد قانون جدید، همه قوانین قدیمی از این نوع را غیرفعال می‌کنیم + var existingLaws = _lawRepository.Get().Where(x => x.Type == command.Type).ToList(); + if (existingLaws.Any()) { - return operation.Failed("این قانون قبلا ثبت شده است"); + foreach (var existingLaw in existingLaws) + { + existingLaw.Deactivate(); + } + _lawRepository.SaveChanges(); } var law = new Law(command.Title, command.Type, command.Notifications, command.HeadTitle); @@ -56,6 +63,8 @@ public class LawApplication : ILawApplication { return operation.Failed("باید حداقل یک بند برای قانون باید ثبت شود"); } + + // Create new items list for the new version var orderNumber = 1; var lawItems = command.Items.Select(x => { @@ -63,12 +72,17 @@ public class LawApplication : ILawApplication orderNumber++; return res; }).ToList(); - - law.Edit(command.Title); - - law.SetItem(lawItems); - + + // Mark the current version as old version + law.SetAsOldVersion(); + + // Create a new version based on the old one + var newVersion = law.CreateNewVersion(command.Title, command.Notifications, command.HeadTitle, lawItems); + + // Save the new version + _lawRepository.Create(newVersion); _lawRepository.SaveChanges(); + return operation.Succcedded(); } @@ -82,13 +96,13 @@ public class LawApplication : ILawApplication return operation.Failed("باید حداقل یک بند برای قانون باید ثبت شود"); } - // Check if law exists by type - var existingLaw = _lawRepository.Get().FirstOrDefault(x => x.Type == command.Type); + // Check if active law exists by type + var existingLaw = _lawRepository.Get().FirstOrDefault(x => x.Type == command.Type && x.IsActive); if (existingLaw == null) { // If law doesn't exist, create a new one - var law = new Law(command.Title, command.Type,command.Notifications, command.HeadTitle); + var law = new Law(command.Title, command.Type, command.Notifications, command.HeadTitle); var orderNumber = 1; foreach (var item in command.Items) @@ -102,7 +116,10 @@ public class LawApplication : ILawApplication } else { - // If law exists, update it + // Mark the current version as old version + existingLaw.SetAsOldVersion(); + + // Create new items list for the new version var orderNumber = 1; var lawItems = command.Items.Select(x => { @@ -111,9 +128,11 @@ public class LawApplication : ILawApplication return res; }).ToList(); - existingLaw.Edit(command.Title); - existingLaw.SetItem(lawItems); + // Create a new version based on the old one + var newVersion = existingLaw.CreateNewVersion(command.Title, command.Notifications, command.HeadTitle, lawItems); + // Save the new version + _lawRepository.Create(newVersion); _lawRepository.SaveChanges(); } @@ -128,8 +147,17 @@ public class LawApplication : ILawApplication if (law == null) return operation.Failed(ApplicationMessages.RecordNotFound); + // غیرفعال کردن همه نسخه‌های قبلی از این نوع قانون + var otherLaws = _lawRepository.Get().Where(x => x.Type == law.Type && x.id != law.id).ToList(); + foreach (var otherLaw in otherLaws) + { + otherLaw.Deactivate(); + } + + // فعال کردن این نسخه به عنوان آخرین نسخه law.Activate(); _lawRepository.SaveChanges(); + return operation.Succcedded(); } @@ -149,9 +177,11 @@ public class LawApplication : ILawApplication public OperationResult ActivateByType(LawType type) { var operation = new OperationResult(); - var law = _lawRepository.Get().FirstOrDefault(x => x.Type == type); - - if (law == null) + + // غیرفعال کردن همه نسخه‌های قبلی از این نوع قانون + var existingLaws = _lawRepository.Get().Where(x => x.Type == type).ToList(); + + if (!existingLaws.Any()) { // If law doesn't exist, create a new active one with default values var newLaw = new Law(GetDefaultTitleForLawType(type), type, new List(), ""); @@ -160,21 +190,36 @@ public class LawApplication : ILawApplication _lawRepository.SaveChanges(); return operation.Succcedded(); } - - law.Activate(); + + // فعال کردن آخرین نسخه (با بالاترین شماره نسخه) + var latestVersion = existingLaws.OrderByDescending(x => x.Version).First(); + + // غیرفعال کردن سایر نسخه‌ها + foreach (var law in existingLaws.Where(x => x.id != latestVersion.id)) + { + law.Deactivate(); + } + + // فعال کردن آخرین نسخه + latestVersion.Activate(); _lawRepository.SaveChanges(); + return operation.Succcedded(); } public OperationResult DeactivateByType(LawType type) { var operation = new OperationResult(); - var law = _lawRepository.Get().FirstOrDefault(x => x.Type == type); + var laws = _lawRepository.Get().Where(x => x.Type == type).ToList(); - if (law == null) + if (!laws.Any()) return operation.Failed("قانون مورد نظر یافت نشد"); - law.Deactivate(); + foreach (var law in laws) + { + law.Deactivate(); + } + _lawRepository.SaveChanges(); return operation.Succcedded(); } @@ -187,6 +232,8 @@ public class LawApplication : ILawApplication Id = law.id, Title = law.Title, Type = law.Type, + HeadTitle = law.HeadTitle, + Notifications = law.Notifications, Items = law.Items.OrderBy(x => x.OrderNumber).Select(x => new LawItemViewModel { Header = x.Header, @@ -197,10 +244,8 @@ public class LawApplication : ILawApplication public async Task> GetList(LawSearchModel searchModel) { - // Get filtered laws from database + // Get all laws from database, including version information return await _lawRepository.GetList(searchModel); - - } private string GetDefaultTitleForLawType(LawType lawType) @@ -225,6 +270,9 @@ public class LawApplication : ILawApplication IsActive = law.IsActive, CreatedAt = law.CreationDate, Type = law.Type, + HeadTitle = law.HeadTitle, + Notifications = law.Notifications, + Version = law.Version, Items = law.Items.OrderBy(x=>x.OrderNumber).Select(x => new LawItemViewModel { Header = x.Header, @@ -235,6 +283,7 @@ public class LawApplication : ILawApplication public async Task GetLawByType(LawType type) { + // Only get the active (latest) version of the law var lawViewModel = await _lawRepository.GetByType(type); // If no law exists for this type, return a default empty law @@ -247,6 +296,7 @@ public class LawApplication : ILawApplication IsActive = false, CreatedAt = DateTime.Now, Type = type, + Version = 1, Items = new List() }; } diff --git a/CompanyManagment.EFCore/Repository/LawRepository.cs b/CompanyManagment.EFCore/Repository/LawRepository.cs index 47b581b5..2fe17b35 100644 --- a/CompanyManagment.EFCore/Repository/LawRepository.cs +++ b/CompanyManagment.EFCore/Repository/LawRepository.cs @@ -49,7 +49,8 @@ public class LawRepository:RepositoryBase,ILawRepository public async Task> GetList(LawSearchModel searchModel) { - var query = _context.Laws.Include(x => x.Items).AsQueryable(); + var query = _context.Laws.Include(x => x.Items) + .Where(x=>x.IsActive).AsQueryable(); if (!string.IsNullOrWhiteSpace(searchModel.Title)) query = query.Where(x => x.Title.Contains(searchModel.Title));