From 730e5a252b024eec5426ba55124e5f6922d1f599 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 14 Dec 2025 03:35:40 +0330 Subject: [PATCH] feat: add target week activation flag to network membership --- .../GetNetworkTreeQueryHandler.cs | 149 +++++++----------- .../Queries/GetNetworkTree/NetworkTreeDto.cs | 5 + .../CMSMicroservice.Protobuf.csproj | 2 +- .../Protos/networkmembership.proto | 3 +- .../Mappings/NetworkMembershipProfile.cs | 3 +- 5 files changed, 68 insertions(+), 94 deletions(-) diff --git a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/GetNetworkTreeQueryHandler.cs b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/GetNetworkTreeQueryHandler.cs index bdd08e0..dff15d2 100644 --- a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/GetNetworkTreeQueryHandler.cs +++ b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/GetNetworkTreeQueryHandler.cs @@ -26,7 +26,9 @@ public class GetNetworkTreeQueryHandler : IRequestHandler BuildTree(long userId, int maxDepth, int currentDepth, CancellationToken cancellationToken, GetNetworkTreeQuery request) { + // دریافت کاربر با اطلاعات باشگاه مشتریان var user = await _context.Users + .Include(u => u.ClubMembership) .AsNoTracking() .FirstOrDefaultAsync(x => x.Id == userId, cancellationToken); @@ -35,23 +37,19 @@ public class GetNetworkTreeQueryHandler : IRequestHandler x.UserId == userId && x.IsDeleted == false, cancellationToken); - // محاسبه شماره هفته فعال‌سازی string? activationWeekNumber = null; - if (clubMembership?.ActivatedAt != null) + bool isActivatedInTargetWeek = false; + + if (user.ClubMembership?.ActivatedAt != null) { - var activatedAt = clubMembership.ActivatedAt.Value; - var year = activatedAt.Year; - var jan1 = new DateTime(year, 1, 1); - var daysToFirstSaturday = (7 - (int)jan1.DayOfWeek + 7) % 7; - if (jan1.DayOfWeek == DayOfWeek.Saturday) daysToFirstSaturday = 0; - var firstSaturday = jan1.AddDays(daysToFirstSaturday); - var weekNum = activatedAt < firstSaturday ? 1 : ((activatedAt - firstSaturday).Days / 7) + 1; - activationWeekNumber = $"{year}-W{weekNum:D2}"; + activationWeekNumber = CalculateWeekNumber(user.ClubMembership.ActivatedAt.Value); + + // بررسی آیا در هفته هدف فعال شده است + if (!string.IsNullOrEmpty(request.ActivationWeekNumber)) + { + isActivatedInTargetWeek = activationWeekNumber == request.ActivationWeekNumber; + } } var node = new NetworkTreeDto @@ -62,9 +60,10 @@ public class GetNetworkTreeQueryHandler : IRequestHandler x.NetworkParentId == userId && x.LegPosition == NetworkLeg.Left); - - // اعمال فیلتر IsClubActive - if (request.IsClubActive.HasValue) - { - var activeUserIds = await _context.ClubMemberships - .AsNoTracking() - .Where(cm => cm.IsActive == request.IsClubActive.Value && cm.IsDeleted == false) - .Select(cm => cm.UserId) - .ToListAsync(cancellationToken); - - leftChildQuery = leftChildQuery.Where(u => activeUserIds.Contains(u.Id)); - } - - // اعمال فیلتر ActivationWeekNumber - if (!string.IsNullOrEmpty(request.ActivationWeekNumber)) - { - var (startDate, endDate) = ParseWeekNumber(request.ActivationWeekNumber); - if (startDate.HasValue && endDate.HasValue) - { - var weekUserIds = await _context.ClubMemberships - .AsNoTracking() - .Where(cm => cm.IsDeleted == false - && cm.ActivatedAt != null - && cm.ActivatedAt >= startDate.Value - && cm.ActivatedAt < endDate.Value) - .Select(cm => cm.UserId) - .ToListAsync(cancellationToken); - - leftChildQuery = leftChildQuery.Where(u => weekUserIds.Contains(u.Id)); - } - } - - var leftChild = await leftChildQuery.FirstOrDefaultAsync(cancellationToken); + // پیدا کردن فرزندان (چپ و راست) + var children = await GetFilteredChildren(userId, request, cancellationToken); + var leftChild = children.FirstOrDefault(c => c.LegPosition == NetworkLeg.Left); if (leftChild != null) { node.LeftChild = await BuildTree(leftChild.Id, maxDepth, currentDepth + 1, cancellationToken, request); } - // پیدا کردن فرزند راست - var rightChildQuery = _context.Users - .AsNoTracking() - .Where(x => x.NetworkParentId == userId && x.LegPosition == NetworkLeg.Right); - - // اعمال فیلتر IsClubActive - if (request.IsClubActive.HasValue) - { - var activeUserIds = await _context.ClubMemberships - .AsNoTracking() - .Where(cm => cm.IsActive == request.IsClubActive.Value && cm.IsDeleted == false) - .Select(cm => cm.UserId) - .ToListAsync(cancellationToken); - - rightChildQuery = rightChildQuery.Where(u => activeUserIds.Contains(u.Id)); - } - - // اعمال فیلتر ActivationWeekNumber - if (!string.IsNullOrEmpty(request.ActivationWeekNumber)) - { - var (startDate, endDate) = ParseWeekNumber(request.ActivationWeekNumber); - if (startDate.HasValue && endDate.HasValue) - { - var weekUserIds = await _context.ClubMemberships - .AsNoTracking() - .Where(cm => cm.IsDeleted == false - && cm.ActivatedAt != null - && cm.ActivatedAt >= startDate.Value - && cm.ActivatedAt < endDate.Value) - .Select(cm => cm.UserId) - .ToListAsync(cancellationToken); - - rightChildQuery = rightChildQuery.Where(u => weekUserIds.Contains(u.Id)); - } - } - - var rightChild = await rightChildQuery.FirstOrDefaultAsync(cancellationToken); - + var rightChild = children.FirstOrDefault(c => c.LegPosition == NetworkLeg.Right); if (rightChild != null) { node.RightChild = await BuildTree(rightChild.Id, maxDepth, currentDepth + 1, cancellationToken, request); @@ -163,6 +91,45 @@ public class GetNetworkTreeQueryHandler : IRequestHandler + /// دریافت فرزندان با اعمال فیلترها + /// + private async Task> GetFilteredChildren(long parentId, GetNetworkTreeQuery request, CancellationToken cancellationToken) + { + var query = _context.Users + .Include(u => u.ClubMembership) + .AsNoTracking() + .Where(x => x.NetworkParentId == parentId); + + // اعمال فیلتر IsClubActive + if (request.IsClubActive.HasValue) + { + query = query.Where(u => + u.ClubMembership != null && + u.ClubMembership.IsDeleted == false && + u.ClubMembership.IsActive == request.IsClubActive.Value); + } + + return await query.ToListAsync(cancellationToken); + } + + /// + /// محاسبه شماره هفته از تاریخ + /// + private static string CalculateWeekNumber(DateTime date) + { + var year = date.Year; + var jan1 = new DateTime(year, 1, 1); + var daysToFirstSaturday = (7 - (int)jan1.DayOfWeek + 7) % 7; + if (jan1.DayOfWeek == DayOfWeek.Saturday) + daysToFirstSaturday = 0; + + var firstSaturday = jan1.AddDays(daysToFirstSaturday); + var weekNum = date < firstSaturday ? 1 : ((date - firstSaturday).Days / 7) + 1; + + return $"{year}-W{weekNum:D2}"; + } + /// /// تبدیل شماره هفته (مثلاً 2025-W05) به تاریخ شروع و پایان هفته /// diff --git a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs index b43e599..ee60a6e 100644 --- a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs +++ b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs @@ -27,6 +27,11 @@ public class NetworkTreeDto /// public string? ActivationWeekNumber { get; set; } + /// + /// آیا کاربر در هفته هدف فعال شده است؟ + /// + public bool IsActivatedInTargetWeek { get; set; } + /// /// تاریخ ایجاد کاربر /// diff --git a/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj b/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj index 985486e..177884e 100644 --- a/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj +++ b/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj @@ -3,7 +3,7 @@ net9.0 enable enable - 0.0.154 + 0.0.155 None False False diff --git a/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto b/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto index ddbc842..2386b31 100644 --- a/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto +++ b/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto @@ -176,7 +176,8 @@ message NetworkTreeNodeModel google.protobuf.Timestamp club_activated_at = 8; // تاریخ فعال‌سازی در باشگاه bool is_club_active = 9; // فعال بودن در باشگاه string activation_week_number = 10; // شماره هفته فعال‌سازی - google.protobuf.Timestamp user_created = 11; // تاریخ ایجاد کاربر + bool is_activated_in_target_week = 11; // آیا در هفته هدف فعال شده + google.protobuf.Timestamp user_created = 12; // تاریخ ایجاد کاربر } // GetHistory Query diff --git a/src/CMSMicroservice.WebApi/Common/Mappings/NetworkMembershipProfile.cs b/src/CMSMicroservice.WebApi/Common/Mappings/NetworkMembershipProfile.cs index e109233..6badf7a 100644 --- a/src/CMSMicroservice.WebApi/Common/Mappings/NetworkMembershipProfile.cs +++ b/src/CMSMicroservice.WebApi/Common/Mappings/NetworkMembershipProfile.cs @@ -85,7 +85,8 @@ public class NetworkMembershipProfile : IRegister NetworkLevel = node.CurrentDepth, IsActive = true, IsClubActive = node.IsClubActive, - ActivationWeekNumber = node.ActivationWeekNumber ?? string.Empty + ActivationWeekNumber = node.ActivationWeekNumber ?? string.Empty, + IsActivatedInTargetWeek = node.IsActivatedInTargetWeek }; if (parentId.HasValue)