feat: add versioning to Law entity and implement version management in LawApplication

This commit is contained in:
2025-10-13 09:02:17 +03:30
parent 5cde26e7f3
commit fdf7fa0d3c
4 changed files with 107 additions and 28 deletions

View File

@@ -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<string> Notifications
@@ -26,14 +27,15 @@ namespace Company.Domain.LawAgg
set => NotificationsJson = JsonSerializer.Serialize(value);
}
public Law(string title, LawType lawType, List<string> notifications, string headTitle )
public Law(string title, LawType lawType, List<string> notifications, string headTitle, int version = 1)
{
Title = title;
IsActive = true;
IsActive = true; // آخرین نسخه فعال است
Items = new List<LawItem>();
Type = lawType;
Notifications = notifications ?? new List<string>();
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<LawItem> items)
{
Items = items ?? new List<LawItem>();
@@ -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<string> notifications, string headTitle, List<LawItem> items)
{
var newVersion = new Law(
title,
this.Type,
notifications,
headTitle,
this.Version + 1
);
newVersion.SetItem(items);
newVersion.SetAsLatestVersion();
return newVersion;
}
}
public class LawItem

View File

@@ -14,6 +14,7 @@ namespace CompanyManagment.App.Contracts.Law
public LawType Type { get; set; }
public string HeadTitle { get; set; }
public List<string> Notifications { get; set; }
public int Version { get; set; }
}
public class LawItemViewModel

View File

@@ -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 =>
{
@@ -64,11 +73,16 @@ public class LawApplication : ILawApplication
return res;
}).ToList();
law.Edit(command.Title);
// Mark the current version as old version
law.SetAsOldVersion();
law.SetItem(lawItems);
// 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,8 +96,8 @@ 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)
{
@@ -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<string>(), "");
@@ -161,20 +191,35 @@ public class LawApplication : ILawApplication
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("قانون مورد نظر یافت نشد");
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<List<LawViewModel>> 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<LawViewModel> 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<LawItemViewModel>()
};
}

View File

@@ -49,7 +49,8 @@ public class LawRepository:RepositoryBase<long,Law>,ILawRepository
public async Task<List<LawViewModel>> 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));